diff --git a/Package.swift b/Package.swift index 80a3b1f139..d278bd7867 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,12 @@ // swift-tools-version:5.0 // The swift-tools-version declares the minimum version of Swift required to build this package. +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + import PackageDescription @@ -31,9 +38,9 @@ let package = Package( name: "YogaKitSwift", dependencies: ["YogaKit", "Yoga"], path: ".", - exclude: ["yoga/include/Yoga.modulemap"], sources: ["YogaKit/YogaKit.Swift"], cSettings: [ + .headerSearchPath("."), .headerSearchPath("yoga") ]), .target( @@ -49,13 +56,12 @@ let package = Package( .target( name: "Yoga", path: ".", + exclude: ["yoga/Yoga.h"], sources: ["yoga"], publicHeadersPath: "yoga/include", cSettings: [ .headerSearchPath(".") ]) ], - swiftLanguageVersions: [.v5], - cLanguageStandard: .gnu11, - cxxLanguageStandard: .gnucxx14 + cxxLanguageStandard: CXXLanguageStandard(rawValue: "c++20") ) diff --git a/README.md b/README.md index 527879ff51..83fa6459bd 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,35 @@ -# Yoga [![CocoaPods](https://img.shields.io/cocoapods/v/YogaKit.svg)](http://cocoapods.org/pods/YogaKit) [![npm](https://img.shields.io/npm/v/yoga-layout.svg)](https://www.npmjs.com/package/yoga-layout) [![bintray](https://img.shields.io/bintray/v/facebook/maven/com.facebook.yoga:yoga.svg)](https://bintray.com/facebook/maven/com.facebook.yoga%3Ayoga/_latestVersion) [![NuGet](https://img.shields.io/nuget/v/Facebook.Yoga.svg)](https://www.nuget.org/packages/Facebook.Yoga) +# Yoga [![CocoaPods](https://img.shields.io/cocoapods/v/Yoga.svg)](http://cocoapods.org/pods/Yoga) [![npm](https://img.shields.io/npm/v/yoga-layout.svg)](https://www.npmjs.com/package/yoga-layout) [![Maven Central](https://img.shields.io/maven-central/v/com.facebook.yoga/yoga)](https://search.maven.org/artifact/com.facebook.yoga/yoga) ![SPM](https://img.shields.io/badge/SPM-Supported-blue.svg) -## Building -Yoga builds with [buck](https://buckbuild.com). Make sure you install buck before contributing to Yoga. Yoga's main implementation is in C++, with bindings to supported languages and frameworks. When making changes to Yoga please ensure the changes are also propagated to these bindings when applicable. - -## Testing -For testing we rely on [gtest](https://github.com/google/googletest) as a submodule. After cloning Yoga run `git submodule init` followed by `git submodule update`. +Yoga is an embeddable and performant flexbox layout engine with bindings for multiple languages. -For any changes you make you should ensure that all the tests are passing. In case you make any fixes or additions to the library please also add tests for that change to ensure we don't break anything in the future. Tests are located in the `tests` directory. Run the tests by executing `buck test //:yoga`. +## Building -Instead of manually writing a test which ensures parity with web implementations of Flexbox you can run `gentest/gentest.rb` to generate a test for you. You can write html which you want to verify in Yoga, in `gentest/fixtures` folder, such as the following. +Yoga's main implementation targets C++ 20 with accompanying build logic in CMake. A wrapper is provided to build the main library and run unit tests. -```html -
-
-
+```sh +./unit_tests ``` -Run `gentest/gentest.rb` to generate test code and re-run `buck test //:yoga` to validate the behavior. One test case will be generated for every root `div` in the input html. +While not required, this script will use [ninja](https://ninja-build.org/) if it is installed for faster builds. -You may need to install the latest watir-webdriver gem (`gem install watir-webdriver`) and [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) to run `gentest/gentest.rb` Ruby script. +Yoga is additionally part of the [vcpkg](https://github.com/Microsoft/vcpkg/) collection of ports maintained by Microsoft and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. -### .NET -.NET testing is not integrated in buck yet, you might need to set up .NET testing environment. We have a script which to launch C# test on macOS, `csharp/tests/Facebook.Yoga/test_macos.sh`. +## Adding Tests -## Benchmarks -Benchmarks are located in `benchmark/YGBenchmark.c` and can be run with `buck run //benchmark:benchmark`. If you think your change has affected performance please run this before and after your change to validate that nothing has regressed. Benchmarks are run on every commit in CI. +Many of Yoga's tests are automatically generated, using HTML fixtures describing node structure. These are rendered in Chrome to generate an expected layout result for the tree. New fixtures can be added to `gentest/fixtures`. -### JavaScript -Installing through NPM -```sh -npm install yoga-layout -``` -By default this will install the library and try to build for all platforms (node, browser asm, and standalone webpack). You may receive errors if you do not have the required platform development tools already installed. To preset the platform you'd like to build for you can set a .npmrc property first. -```sh -npm config set yoga-layout:platform standalone +```html +
+
+
``` -This will now only run the standalone webpack build upon install. - -## Build Platforms -| name | description | -|----------------|-------------------------------------------------| -| all (default) | Builds all of these platforms. | -| browser | Builds asm js browser version. | -| node | Builds node js version. | -| standalone | Runs webpack. | -| none | Does nothing. You can use the prepackaged libs. | +To generate new tests from added fixtures: -## Maintainer Release Guide +1. Ensure you have [yarn classic](https://classic.yarnpkg.com) installed. +2. Run `yarn install` to install dependencies for the test generator. +3. Run `yarn gentest` in the `yoga` directory. -To publish a new release, follow these steps: - -1. Ensure you have your GPG key set up and your [OSS Sonatype](https://oss.sonatype.org/) credentials handy. -2. Add the follow entries to either your local `gradle.properties` (don't forget to revert) or your global `~/.gradle/gradle.properties`: - -``` -# You get these from https://oss.sonatype.org/#profile;User%20Token -mavenCentralRepositoryUsername= -mavenCentralRepositoryPassword= - -# You can get the keyId (in GPG 1.4 format) by running `gpg1 --list-keys`. -signing.secretKeyRingFile= -signing.keyId= -signing.password= -``` +## Debugging -3. Change the `VERSION_NAME` in `gradle.properties` to a non-SNAPSHOT release. -4. Commit and land the version change. -5. Run `./gradlew publishToMaven`. -6. Run `./gradlew closeAndReleaseRepository`. -7. Change the `VERSION_NAME` in `gradle.properties` back to a new SNAPSHOT release. -8. Commit and land the version change. -9. Celebrate! You've made a release! +Yoga provides a VSCode "launch.json" configuration which allows debugging unit tests. Simply add your breakpoints, and run "Debug C++ Unit tests (lldb)" (or "Debug C++ Unit tests (vsdbg)" on Windows). diff --git a/YogaKit/Source/YGLayout.m b/YogaKit/Source/YGLayout.m index d1d15dcfe7..494d1ddf96 100644 --- a/YogaKit/Source/YGLayout.m +++ b/YogaKit/Source/YGLayout.m @@ -387,7 +387,7 @@ - (void)configureLayoutWithBlock:(NS_NOESCAPE YGLayoutConfigurationBlock)block { #pragma mark - Private -static YGSize YGMeasureView(YGNodeRef node, double width, YGMeasureMode widthMode, double height, YGMeasureMode heightMode) { +static YGSize YGMeasureView(YGNodeConstRef node, double width, YGMeasureMode widthMode, double height, YGMeasureMode heightMode) { const CGFloat constrainedWidth = (widthMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : width; const CGFloat constrainedHeight = (heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : height; diff --git a/YogaKit/Tests/YogaKitTests.m b/YogaKit/Tests/YogaKitTests.m index c78e509699..19fb35008e 100644 --- a/YogaKit/Tests/YogaKitTests.m +++ b/YogaKit/Tests/YogaKitTests.m @@ -279,11 +279,9 @@ - (void)testMarkingDirtyOnlyWorksOnLeafNodes { subview.yoga.isIncludedInLayout = YES; [container addSubview:subview]; - XCTAssertFalse(container.yoga.isDirty); [container.yoga markDirty]; - XCTAssertFalse(container.yoga.isDirty); + XCTAssertTrue(container.yoga.isDirty); - XCTAssertFalse(subview.yoga.isDirty); [subview.yoga markDirty]; XCTAssertTrue(subview.yoga.isDirty); } diff --git a/YogaKit/YogaKit.xcodeproj/project.pbxproj b/YogaKit/YogaKit.xcodeproj/project.pbxproj index dccc6d1e95..3e3e74238c 100644 --- a/YogaKit/YogaKit.xcodeproj/project.pbxproj +++ b/YogaKit/YogaKit.xcodeproj/project.pbxproj @@ -10,13 +10,87 @@ 1511C08C251ED11900A2C621 /* Yoga.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15865FFE24E58BD800345BD7 /* Yoga.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 1511C0BB251F1BB600A2C621 /* YGLayoutProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1511C0BA251F1BB600A2C621 /* YGLayoutProperties.swift */; }; 153098C22692ED29009B4135 /* YGValueExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153098C12692ED29009B4135 /* YGValueExtensions.swift */; }; - 153098CA26930BAF009B4135 /* Yoga-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 153098C826930BAE009B4135 /* Yoga-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 153B526524E6AD8D008156D3 /* YogaKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 153B526324E6AD8D008156D3 /* YogaKitTests.m */; }; 153B526B24E6ADFA008156D3 /* Yoga.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15865FFE24E58BD800345BD7 /* Yoga.framework */; }; 153B526C24E6ADFA008156D3 /* YogaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15865F5424E5834E00345BD7 /* YogaKit.framework */; }; 153B526E24E6AECF008156D3 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 153B526D24E6AECF008156D3 /* libc++.tbd */; }; 154A6EF524E6B1260091264C /* dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 154A6EF424E6B1260091264C /* dummy.swift */; }; 154D2C9A269362600027364F /* YogaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15865F5424E5834E00345BD7 /* YogaKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + 157283692D4397EB00F20253 /* Node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572834C2D4397EB00F20253 /* Node.cpp */; }; + 1572836A2D4397EB00F20253 /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572831A2D4397EB00F20253 /* Cache.cpp */; }; + 1572836B2D4397EB00F20253 /* YGEnums.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572835B2D4397EB00F20253 /* YGEnums.cpp */; }; + 1572836C2D4397EB00F20253 /* Baseline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283172D4397EB00F20253 /* Baseline.cpp */; }; + 1572836D2D4397EB00F20253 /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283442D4397EB00F20253 /* event.cpp */; }; + 1572836E2D4397EB00F20253 /* PixelGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283212D4397EB00F20253 /* PixelGrid.cpp */; }; + 1572836F2D4397EB00F20253 /* Config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283272D4397EB00F20253 /* Config.cpp */; }; + 157283702D4397EB00F20253 /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572832C2D4397EB00F20253 /* Log.cpp */; }; + 157283712D4397EB00F20253 /* YGConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283592D4397EB00F20253 /* YGConfig.cpp */; }; + 157283722D4397EB00F20253 /* YGPixelGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283642D4397EB00F20253 /* YGPixelGrid.cpp */; }; + 157283732D4397EB00F20253 /* AbsoluteLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283142D4397EB00F20253 /* AbsoluteLayout.cpp */; }; + 157283742D4397EB00F20253 /* AssertFatal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572832A2D4397EB00F20253 /* AssertFatal.cpp */; }; + 157283752D4397EB00F20253 /* YGNodeLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283602D4397EB00F20253 /* YGNodeLayout.cpp */; }; + 157283762D4397EB00F20253 /* YGValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283662D4397EB00F20253 /* YGValue.cpp */; }; + 157283772D4397EB00F20253 /* LayoutResults.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572834A2D4397EB00F20253 /* LayoutResults.cpp */; }; + 157283782D4397EB00F20253 /* YGNodeStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 157283622D4397EB00F20253 /* YGNodeStyle.cpp */; }; + 157283792D4397EB00F20253 /* YGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572835E2D4397EB00F20253 /* YGNode.cpp */; }; + 1572837A2D4397EB00F20253 /* FlexLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572831F2D4397EB00F20253 /* FlexLine.cpp */; }; + 1572837B2D4397EB00F20253 /* CalculateLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1572831C2D4397EB00F20253 /* CalculateLayout.cpp */; }; + 1572837C2D4397EB00F20253 /* YGEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572835A2D4397EB00F20253 /* YGEnums.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1572837D2D4397EB00F20253 /* Dimension.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283302D4397EB00F20253 /* Dimension.h */; }; + 1572837E2D4397EB00F20253 /* FlexDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572831D2D4397EB00F20253 /* FlexDirection.h */; }; + 1572837F2D4397EB00F20253 /* Gutter.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283372D4397EB00F20253 /* Gutter.h */; }; + 157283802D4397EB00F20253 /* LayoutableChildren.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283482D4397EB00F20253 /* LayoutableChildren.h */; }; + 157283812D4397EB00F20253 /* NodeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572833B2D4397EB00F20253 /* NodeType.h */; }; + 157283822D4397EB00F20253 /* Wrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283402D4397EB00F20253 /* Wrap.h */; }; + 157283832D4397EB00F20253 /* PixelGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283202D4397EB00F20253 /* PixelGrid.h */; }; + 157283842D4397EB00F20253 /* Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283672D4397EB00F20253 /* Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283852D4397EB00F20253 /* YGMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572835C2D4397EB00F20253 /* YGMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283862D4397EB00F20253 /* Align.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283152D4397EB00F20253 /* Align.h */; }; + 157283872D4397EB00F20253 /* Overflow.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572833C2D4397EB00F20253 /* Overflow.h */; }; + 157283882D4397EB00F20253 /* StyleValuePool.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283562D4397EB00F20253 /* StyleValuePool.h */; }; + 157283892D4397EB00F20253 /* Justify.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283382D4397EB00F20253 /* Justify.h */; }; + 1572838A2D4397EB00F20253 /* Log.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572832B2D4397EB00F20253 /* Log.h */; }; + 1572838B2D4397EB00F20253 /* LayoutResults.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283492D4397EB00F20253 /* LayoutResults.h */; }; + 1572838C2D4397EB00F20253 /* StyleSizeLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283542D4397EB00F20253 /* StyleSizeLength.h */; }; + 1572838D2D4397EB00F20253 /* Config.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283262D4397EB00F20253 /* Config.h */; }; + 1572838E2D4397EB00F20253 /* Direction.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283312D4397EB00F20253 /* Direction.h */; }; + 1572838F2D4397EB00F20253 /* ExperimentalFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283352D4397EB00F20253 /* ExperimentalFeature.h */; }; + 157283902D4397EB00F20253 /* Display.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283322D4397EB00F20253 /* Display.h */; }; + 157283912D4397EB00F20253 /* SizingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283222D4397EB00F20253 /* SizingMode.h */; }; + 157283922D4397EB00F20253 /* YGPixelGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283632D4397EB00F20253 /* YGPixelGrid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283932D4397EB00F20253 /* MeasureMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572833A2D4397EB00F20253 /* MeasureMode.h */; }; + 157283942D4397EB00F20253 /* TrailingPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283232D4397EB00F20253 /* TrailingPosition.h */; }; + 157283952D4397EB00F20253 /* Align.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572832E2D4397EB00F20253 /* Align.h */; }; + 157283962D4397EB00F20253 /* SmallValueBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283512D4397EB00F20253 /* SmallValueBuffer.h */; }; + 157283972D4397EB00F20253 /* YGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572835D2D4397EB00F20253 /* YGNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283982D4397EB00F20253 /* StyleLength.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283532D4397EB00F20253 /* StyleLength.h */; }; + 157283992D4397EB00F20253 /* CalculateLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572831B2D4397EB00F20253 /* CalculateLayout.h */; }; + 1572839A2D4397EB00F20253 /* FlexLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572831E2D4397EB00F20253 /* FlexLine.h */; }; + 1572839B2D4397EB00F20253 /* BoundAxis.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283182D4397EB00F20253 /* BoundAxis.h */; }; + 1572839C2D4397EB00F20253 /* AbsoluteLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283132D4397EB00F20253 /* AbsoluteLayout.h */; }; + 1572839D2D4397EB00F20253 /* Edge.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283332D4397EB00F20253 /* Edge.h */; }; + 1572839E2D4397EB00F20253 /* AssertFatal.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283292D4397EB00F20253 /* AssertFatal.h */; }; + 1572839F2D4397EB00F20253 /* YGNodeStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283612D4397EB00F20253 /* YGNodeStyle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283A02D4397EB00F20253 /* FlexDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283362D4397EB00F20253 /* FlexDirection.h */; }; + 157283A12D4397EB00F20253 /* Comparison.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572834E2D4397EB00F20253 /* Comparison.h */; }; + 157283A22D4397EB00F20253 /* Cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283192D4397EB00F20253 /* Cache.h */; }; + 157283A32D4397EB00F20253 /* Baseline.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283162D4397EB00F20253 /* Baseline.h */; }; + 157283A42D4397EB00F20253 /* Errata.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283342D4397EB00F20253 /* Errata.h */; }; + 157283A52D4397EB00F20253 /* BoxSizing.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572832F2D4397EB00F20253 /* BoxSizing.h */; }; + 157283A62D4397EB00F20253 /* PositionType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572833E2D4397EB00F20253 /* PositionType.h */; }; + 157283A72D4397EB00F20253 /* Unit.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572833F2D4397EB00F20253 /* Unit.h */; }; + 157283A82D4397EB00F20253 /* YGNodeLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572835F2D4397EB00F20253 /* YGNodeLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283A92D4397EB00F20253 /* StyleValueHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283552D4397EB00F20253 /* StyleValueHandle.h */; }; + 157283AA2D4397EB00F20253 /* YGValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283652D4397EB00F20253 /* YGValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283AB2D4397EB00F20253 /* LogLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283392D4397EB00F20253 /* LogLevel.h */; }; + 157283AC2D4397EB00F20253 /* YogaEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283412D4397EB00F20253 /* YogaEnums.h */; }; + 157283AD2D4397EB00F20253 /* Style.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283522D4397EB00F20253 /* Style.h */; }; + 157283AE2D4397EB00F20253 /* FloatOptional.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572834F2D4397EB00F20253 /* FloatOptional.h */; }; + 157283AF2D4397EB00F20253 /* CachedMeasurement.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283472D4397EB00F20253 /* CachedMeasurement.h */; }; + 157283B02D4397EB00F20253 /* PhysicalEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572833D2D4397EB00F20253 /* PhysicalEdge.h */; }; + 157283B12D4397EB00F20253 /* Node.h in Headers */ = {isa = PBXBuildFile; fileRef = 1572834B2D4397EB00F20253 /* Node.h */; }; + 157283B22D4397EB00F20253 /* YGConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283582D4397EB00F20253 /* YGConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 157283B32D4397EB00F20253 /* event.h in Headers */ = {isa = PBXBuildFile; fileRef = 157283432D4397EB00F20253 /* event.h */; }; 15865F6624E583F000345BD7 /* YGLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 15865F5F24E583F000345BD7 /* YGLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15865F6724E583F000345BD7 /* UIView+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 15865F6024E583F000345BD7 /* UIView+Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15865F6824E583F000345BD7 /* YGLayout+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 15865F6124E583F000345BD7 /* YGLayout+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -24,36 +98,6 @@ 15865F6A24E583F000345BD7 /* UIView+Yoga.m in Sources */ = {isa = PBXBuildFile; fileRef = 15865F6324E583F000345BD7 /* UIView+Yoga.m */; }; 15865F6C24E583F000345BD7 /* YogaKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 15865F6524E583F000345BD7 /* YogaKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1586600824E58C0F00345BD7 /* Yoga.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15865FFE24E58BD800345BD7 /* Yoga.framework */; settings = {ATTRIBUTES = (Required, ); }; }; - 1586602924E58C3700345BD7 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586600924E58C3600345BD7 /* Utils.cpp */; }; - 1586602A24E58C3700345BD7 /* experiments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586600B24E58C3600345BD7 /* experiments.cpp */; }; - 1586602B24E58C3700345BD7 /* experiments-inl.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586600C24E58C3600345BD7 /* experiments-inl.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586602C24E58C3700345BD7 /* experiments.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586600D24E58C3600345BD7 /* experiments.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586602D24E58C3700345BD7 /* YGStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586600E24E58C3600345BD7 /* YGStyle.cpp */; }; - 1586602E24E58C3700345BD7 /* YGNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586600F24E58C3600345BD7 /* YGNode.cpp */; }; - 1586602F24E58C3700345BD7 /* YGConfig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586601024E58C3600345BD7 /* YGConfig.cpp */; }; - 1586603024E58C3700345BD7 /* Utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601124E58C3600345BD7 /* Utils.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603124E58C3700345BD7 /* BitUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601224E58C3600345BD7 /* BitUtils.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603224E58C3700345BD7 /* CompactValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601324E58C3600345BD7 /* CompactValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603324E58C3700345BD7 /* YGValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586601424E58C3700345BD7 /* YGValue.cpp */; }; - 1586603424E58C3700345BD7 /* YGLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586601524E58C3700345BD7 /* YGLayout.cpp */; }; - 1586603524E58C3700345BD7 /* log.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601624E58C3700345BD7 /* log.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603624E58C3700345BD7 /* YGNodePrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586601724E58C3700345BD7 /* YGNodePrint.cpp */; }; - 1586603724E58C3700345BD7 /* event.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601924E58C3700345BD7 /* event.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603824E58C3700345BD7 /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586601A24E58C3700345BD7 /* event.cpp */; }; - 1586603924E58C3700345BD7 /* YGNodePrint.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601B24E58C3700345BD7 /* YGNodePrint.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603A24E58C3700345BD7 /* Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601C24E58C3700345BD7 /* Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1586603B24E58C3700345BD7 /* YGFloatOptional.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601D24E58C3700345BD7 /* YGFloatOptional.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603C24E58C3700345BD7 /* YGConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601E24E58C3700345BD7 /* YGConfig.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586603D24E58C3700345BD7 /* YGMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586601F24E58C3700345BD7 /* YGMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1586603E24E58C3700345BD7 /* YGEnums.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586602024E58C3700345BD7 /* YGEnums.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1586603F24E58C3700345BD7 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586602124E58C3700345BD7 /* log.cpp */; }; - 1586604024E58C3700345BD7 /* YGStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586602224E58C3700345BD7 /* YGStyle.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586604124E58C3700345BD7 /* Yoga.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586602324E58C3700345BD7 /* Yoga.cpp */; }; - 1586604224E58C3700345BD7 /* Yoga-internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586602424E58C3700345BD7 /* Yoga-internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586604324E58C3700345BD7 /* YGValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586602524E58C3700345BD7 /* YGValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1586604424E58C3700345BD7 /* YGLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586602624E58C3700345BD7 /* YGLayout.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586604524E58C3700345BD7 /* YGNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 1586602724E58C3700345BD7 /* YGNode.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1586604624E58C3700345BD7 /* YGEnums.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1586602824E58C3700345BD7 /* YGEnums.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -98,7 +142,6 @@ 1511C053251EBED100A2C621 /* YogaKitSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = YogaKitSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1511C0BA251F1BB600A2C621 /* YGLayoutProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YGLayoutProperties.swift; sourceTree = ""; }; 153098C12692ED29009B4135 /* YGValueExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YGValueExtensions.swift; sourceTree = ""; }; - 153098C826930BAE009B4135 /* Yoga-umbrella.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Yoga-umbrella.h"; sourceTree = ""; }; 153B525B24E6AD6B008156D3 /* YogaKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = YogaKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 153B526324E6AD8D008156D3 /* YogaKitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YogaKitTests.m; path = Tests/YogaKitTests.m; sourceTree = SOURCE_ROOT; }; 153B526424E6AD8D008156D3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = Info.plist; path = Tests/Info.plist; sourceTree = SOURCE_ROOT; }; @@ -106,6 +149,81 @@ 153D326D24E6549A00EDDBEA /* Yoga.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = Yoga.modulemap; sourceTree = ""; }; 153D326E24E6549A00EDDBEA /* Yoga-umbrella.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Yoga-umbrella.h"; sourceTree = ""; }; 154A6EF424E6B1260091264C /* dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = dummy.swift; path = Tests/dummy.swift; sourceTree = SOURCE_ROOT; }; + 157283132D4397EB00F20253 /* AbsoluteLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AbsoluteLayout.h; sourceTree = ""; }; + 157283142D4397EB00F20253 /* AbsoluteLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AbsoluteLayout.cpp; sourceTree = ""; }; + 157283152D4397EB00F20253 /* Align.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Align.h; sourceTree = ""; }; + 157283162D4397EB00F20253 /* Baseline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Baseline.h; sourceTree = ""; }; + 157283172D4397EB00F20253 /* Baseline.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Baseline.cpp; sourceTree = ""; }; + 157283182D4397EB00F20253 /* BoundAxis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BoundAxis.h; sourceTree = ""; }; + 157283192D4397EB00F20253 /* Cache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Cache.h; sourceTree = ""; }; + 1572831A2D4397EB00F20253 /* Cache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Cache.cpp; sourceTree = ""; }; + 1572831B2D4397EB00F20253 /* CalculateLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CalculateLayout.h; sourceTree = ""; }; + 1572831C2D4397EB00F20253 /* CalculateLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CalculateLayout.cpp; sourceTree = ""; }; + 1572831D2D4397EB00F20253 /* FlexDirection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FlexDirection.h; sourceTree = ""; }; + 1572831E2D4397EB00F20253 /* FlexLine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FlexLine.h; sourceTree = ""; }; + 1572831F2D4397EB00F20253 /* FlexLine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FlexLine.cpp; sourceTree = ""; }; + 157283202D4397EB00F20253 /* PixelGrid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PixelGrid.h; sourceTree = ""; }; + 157283212D4397EB00F20253 /* PixelGrid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PixelGrid.cpp; sourceTree = ""; }; + 157283222D4397EB00F20253 /* SizingMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SizingMode.h; sourceTree = ""; }; + 157283232D4397EB00F20253 /* TrailingPosition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TrailingPosition.h; sourceTree = ""; }; + 157283262D4397EB00F20253 /* Config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = ""; }; + 157283272D4397EB00F20253 /* Config.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Config.cpp; sourceTree = ""; }; + 157283292D4397EB00F20253 /* AssertFatal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AssertFatal.h; sourceTree = ""; }; + 1572832A2D4397EB00F20253 /* AssertFatal.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AssertFatal.cpp; sourceTree = ""; }; + 1572832B2D4397EB00F20253 /* Log.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = ""; }; + 1572832C2D4397EB00F20253 /* Log.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Log.cpp; sourceTree = ""; }; + 1572832E2D4397EB00F20253 /* Align.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Align.h; sourceTree = ""; }; + 1572832F2D4397EB00F20253 /* BoxSizing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BoxSizing.h; sourceTree = ""; }; + 157283302D4397EB00F20253 /* Dimension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Dimension.h; sourceTree = ""; }; + 157283312D4397EB00F20253 /* Direction.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Direction.h; sourceTree = ""; }; + 157283322D4397EB00F20253 /* Display.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Display.h; sourceTree = ""; }; + 157283332D4397EB00F20253 /* Edge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Edge.h; sourceTree = ""; }; + 157283342D4397EB00F20253 /* Errata.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Errata.h; sourceTree = ""; }; + 157283352D4397EB00F20253 /* ExperimentalFeature.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExperimentalFeature.h; sourceTree = ""; }; + 157283362D4397EB00F20253 /* FlexDirection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FlexDirection.h; sourceTree = ""; }; + 157283372D4397EB00F20253 /* Gutter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Gutter.h; sourceTree = ""; }; + 157283382D4397EB00F20253 /* Justify.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Justify.h; sourceTree = ""; }; + 157283392D4397EB00F20253 /* LogLevel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogLevel.h; sourceTree = ""; }; + 1572833A2D4397EB00F20253 /* MeasureMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MeasureMode.h; sourceTree = ""; }; + 1572833B2D4397EB00F20253 /* NodeType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NodeType.h; sourceTree = ""; }; + 1572833C2D4397EB00F20253 /* Overflow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Overflow.h; sourceTree = ""; }; + 1572833D2D4397EB00F20253 /* PhysicalEdge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PhysicalEdge.h; sourceTree = ""; }; + 1572833E2D4397EB00F20253 /* PositionType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PositionType.h; sourceTree = ""; }; + 1572833F2D4397EB00F20253 /* Unit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Unit.h; sourceTree = ""; }; + 157283402D4397EB00F20253 /* Wrap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Wrap.h; sourceTree = ""; }; + 157283412D4397EB00F20253 /* YogaEnums.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YogaEnums.h; sourceTree = ""; }; + 157283432D4397EB00F20253 /* event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = ""; }; + 157283442D4397EB00F20253 /* event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = ""; }; + 157283472D4397EB00F20253 /* CachedMeasurement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CachedMeasurement.h; sourceTree = ""; }; + 157283482D4397EB00F20253 /* LayoutableChildren.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutableChildren.h; sourceTree = ""; }; + 157283492D4397EB00F20253 /* LayoutResults.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutResults.h; sourceTree = ""; }; + 1572834A2D4397EB00F20253 /* LayoutResults.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutResults.cpp; sourceTree = ""; }; + 1572834B2D4397EB00F20253 /* Node.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Node.h; sourceTree = ""; }; + 1572834C2D4397EB00F20253 /* Node.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Node.cpp; sourceTree = ""; }; + 1572834E2D4397EB00F20253 /* Comparison.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Comparison.h; sourceTree = ""; }; + 1572834F2D4397EB00F20253 /* FloatOptional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FloatOptional.h; sourceTree = ""; }; + 157283512D4397EB00F20253 /* SmallValueBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SmallValueBuffer.h; sourceTree = ""; }; + 157283522D4397EB00F20253 /* Style.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Style.h; sourceTree = ""; }; + 157283532D4397EB00F20253 /* StyleLength.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleLength.h; sourceTree = ""; }; + 157283542D4397EB00F20253 /* StyleSizeLength.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleSizeLength.h; sourceTree = ""; }; + 157283552D4397EB00F20253 /* StyleValueHandle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleValueHandle.h; sourceTree = ""; }; + 157283562D4397EB00F20253 /* StyleValuePool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StyleValuePool.h; sourceTree = ""; }; + 157283582D4397EB00F20253 /* YGConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGConfig.h; sourceTree = ""; }; + 157283592D4397EB00F20253 /* YGConfig.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGConfig.cpp; sourceTree = ""; }; + 1572835A2D4397EB00F20253 /* YGEnums.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGEnums.h; sourceTree = ""; }; + 1572835B2D4397EB00F20253 /* YGEnums.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGEnums.cpp; sourceTree = ""; }; + 1572835C2D4397EB00F20253 /* YGMacros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGMacros.h; sourceTree = ""; }; + 1572835D2D4397EB00F20253 /* YGNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGNode.h; sourceTree = ""; }; + 1572835E2D4397EB00F20253 /* YGNode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGNode.cpp; sourceTree = ""; }; + 1572835F2D4397EB00F20253 /* YGNodeLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGNodeLayout.h; sourceTree = ""; }; + 157283602D4397EB00F20253 /* YGNodeLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGNodeLayout.cpp; sourceTree = ""; }; + 157283612D4397EB00F20253 /* YGNodeStyle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGNodeStyle.h; sourceTree = ""; }; + 157283622D4397EB00F20253 /* YGNodeStyle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGNodeStyle.cpp; sourceTree = ""; }; + 157283632D4397EB00F20253 /* YGPixelGrid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGPixelGrid.h; sourceTree = ""; }; + 157283642D4397EB00F20253 /* YGPixelGrid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGPixelGrid.cpp; sourceTree = ""; }; + 157283652D4397EB00F20253 /* YGValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = YGValue.h; sourceTree = ""; }; + 157283662D4397EB00F20253 /* YGValue.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = YGValue.cpp; sourceTree = ""; }; + 157283672D4397EB00F20253 /* Yoga.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Yoga.h; sourceTree = ""; }; 15865F5424E5834E00345BD7 /* YogaKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = YogaKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 15865F5F24E583F000345BD7 /* YGLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGLayout.h; sourceTree = ""; }; 15865F6024E583F000345BD7 /* UIView+Yoga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Yoga.h"; sourceTree = ""; }; @@ -114,36 +232,6 @@ 15865F6324E583F000345BD7 /* UIView+Yoga.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Yoga.m"; sourceTree = ""; }; 15865F6524E583F000345BD7 /* YogaKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YogaKit.h; sourceTree = ""; }; 15865FFE24E58BD800345BD7 /* Yoga.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Yoga.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 1586600924E58C3600345BD7 /* Utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Utils.cpp; sourceTree = ""; }; - 1586600B24E58C3600345BD7 /* experiments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = experiments.cpp; sourceTree = ""; }; - 1586600C24E58C3600345BD7 /* experiments-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "experiments-inl.h"; sourceTree = ""; }; - 1586600D24E58C3600345BD7 /* experiments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = experiments.h; sourceTree = ""; }; - 1586600E24E58C3600345BD7 /* YGStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGStyle.cpp; sourceTree = ""; }; - 1586600F24E58C3600345BD7 /* YGNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGNode.cpp; sourceTree = ""; }; - 1586601024E58C3600345BD7 /* YGConfig.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGConfig.cpp; sourceTree = ""; }; - 1586601124E58C3600345BD7 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; - 1586601224E58C3600345BD7 /* BitUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitUtils.h; sourceTree = ""; }; - 1586601324E58C3600345BD7 /* CompactValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompactValue.h; sourceTree = ""; }; - 1586601424E58C3700345BD7 /* YGValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGValue.cpp; sourceTree = ""; }; - 1586601524E58C3700345BD7 /* YGLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGLayout.cpp; sourceTree = ""; }; - 1586601624E58C3700345BD7 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = ""; }; - 1586601724E58C3700345BD7 /* YGNodePrint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGNodePrint.cpp; sourceTree = ""; }; - 1586601924E58C3700345BD7 /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = ""; }; - 1586601A24E58C3700345BD7 /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = ""; }; - 1586601B24E58C3700345BD7 /* YGNodePrint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGNodePrint.h; sourceTree = ""; }; - 1586601C24E58C3700345BD7 /* Yoga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Yoga.h; sourceTree = ""; }; - 1586601D24E58C3700345BD7 /* YGFloatOptional.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGFloatOptional.h; sourceTree = ""; }; - 1586601E24E58C3700345BD7 /* YGConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGConfig.h; sourceTree = ""; }; - 1586601F24E58C3700345BD7 /* YGMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGMacros.h; sourceTree = ""; }; - 1586602024E58C3700345BD7 /* YGEnums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGEnums.h; sourceTree = ""; }; - 1586602124E58C3700345BD7 /* log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = log.cpp; sourceTree = ""; }; - 1586602224E58C3700345BD7 /* YGStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGStyle.h; sourceTree = ""; }; - 1586602324E58C3700345BD7 /* Yoga.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Yoga.cpp; sourceTree = ""; }; - 1586602424E58C3700345BD7 /* Yoga-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Yoga-internal.h"; sourceTree = ""; }; - 1586602524E58C3700345BD7 /* YGValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGValue.h; sourceTree = ""; }; - 1586602624E58C3700345BD7 /* YGLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGLayout.h; sourceTree = ""; }; - 1586602724E58C3700345BD7 /* YGNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YGNode.h; sourceTree = ""; }; - 1586602824E58C3700345BD7 /* YGEnums.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YGEnums.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -193,14 +281,6 @@ path = YogaKit.Swift; sourceTree = ""; }; - 153098C726930BAE009B4135 /* include */ = { - isa = PBXGroup; - children = ( - 153098C826930BAE009B4135 /* Yoga-umbrella.h */, - ); - path = include; - sourceTree = ""; - }; 153B525C24E6AD6B008156D3 /* YogaKitTests */ = { isa = PBXGroup; children = ( @@ -221,6 +301,121 @@ name = "Supporting Files"; sourceTree = ""; }; + 157283242D4397EB00F20253 /* algorithm */ = { + isa = PBXGroup; + children = ( + 157283132D4397EB00F20253 /* AbsoluteLayout.h */, + 157283142D4397EB00F20253 /* AbsoluteLayout.cpp */, + 157283152D4397EB00F20253 /* Align.h */, + 157283162D4397EB00F20253 /* Baseline.h */, + 157283172D4397EB00F20253 /* Baseline.cpp */, + 157283182D4397EB00F20253 /* BoundAxis.h */, + 157283192D4397EB00F20253 /* Cache.h */, + 1572831A2D4397EB00F20253 /* Cache.cpp */, + 1572831B2D4397EB00F20253 /* CalculateLayout.h */, + 1572831C2D4397EB00F20253 /* CalculateLayout.cpp */, + 1572831D2D4397EB00F20253 /* FlexDirection.h */, + 1572831E2D4397EB00F20253 /* FlexLine.h */, + 1572831F2D4397EB00F20253 /* FlexLine.cpp */, + 157283202D4397EB00F20253 /* PixelGrid.h */, + 157283212D4397EB00F20253 /* PixelGrid.cpp */, + 157283222D4397EB00F20253 /* SizingMode.h */, + 157283232D4397EB00F20253 /* TrailingPosition.h */, + ); + path = algorithm; + sourceTree = ""; + }; + 157283282D4397EB00F20253 /* config */ = { + isa = PBXGroup; + children = ( + 157283262D4397EB00F20253 /* Config.h */, + 157283272D4397EB00F20253 /* Config.cpp */, + ); + path = config; + sourceTree = ""; + }; + 1572832D2D4397EB00F20253 /* debug */ = { + isa = PBXGroup; + children = ( + 157283292D4397EB00F20253 /* AssertFatal.h */, + 1572832A2D4397EB00F20253 /* AssertFatal.cpp */, + 1572832B2D4397EB00F20253 /* Log.h */, + 1572832C2D4397EB00F20253 /* Log.cpp */, + ); + path = debug; + sourceTree = ""; + }; + 157283422D4397EB00F20253 /* enums */ = { + isa = PBXGroup; + children = ( + 1572832E2D4397EB00F20253 /* Align.h */, + 1572832F2D4397EB00F20253 /* BoxSizing.h */, + 157283302D4397EB00F20253 /* Dimension.h */, + 157283312D4397EB00F20253 /* Direction.h */, + 157283322D4397EB00F20253 /* Display.h */, + 157283332D4397EB00F20253 /* Edge.h */, + 157283342D4397EB00F20253 /* Errata.h */, + 157283352D4397EB00F20253 /* ExperimentalFeature.h */, + 157283362D4397EB00F20253 /* FlexDirection.h */, + 157283372D4397EB00F20253 /* Gutter.h */, + 157283382D4397EB00F20253 /* Justify.h */, + 157283392D4397EB00F20253 /* LogLevel.h */, + 1572833A2D4397EB00F20253 /* MeasureMode.h */, + 1572833B2D4397EB00F20253 /* NodeType.h */, + 1572833C2D4397EB00F20253 /* Overflow.h */, + 1572833D2D4397EB00F20253 /* PhysicalEdge.h */, + 1572833E2D4397EB00F20253 /* PositionType.h */, + 1572833F2D4397EB00F20253 /* Unit.h */, + 157283402D4397EB00F20253 /* Wrap.h */, + 157283412D4397EB00F20253 /* YogaEnums.h */, + ); + path = enums; + sourceTree = ""; + }; + 157283452D4397EB00F20253 /* event */ = { + isa = PBXGroup; + children = ( + 157283432D4397EB00F20253 /* event.h */, + 157283442D4397EB00F20253 /* event.cpp */, + ); + path = event; + sourceTree = ""; + }; + 1572834D2D4397EB00F20253 /* node */ = { + isa = PBXGroup; + children = ( + 157283472D4397EB00F20253 /* CachedMeasurement.h */, + 157283482D4397EB00F20253 /* LayoutableChildren.h */, + 157283492D4397EB00F20253 /* LayoutResults.h */, + 1572834A2D4397EB00F20253 /* LayoutResults.cpp */, + 1572834B2D4397EB00F20253 /* Node.h */, + 1572834C2D4397EB00F20253 /* Node.cpp */, + ); + path = node; + sourceTree = ""; + }; + 157283502D4397EB00F20253 /* numeric */ = { + isa = PBXGroup; + children = ( + 1572834E2D4397EB00F20253 /* Comparison.h */, + 1572834F2D4397EB00F20253 /* FloatOptional.h */, + ); + path = numeric; + sourceTree = ""; + }; + 157283572D4397EB00F20253 /* style */ = { + isa = PBXGroup; + children = ( + 157283512D4397EB00F20253 /* SmallValueBuffer.h */, + 157283522D4397EB00F20253 /* Style.h */, + 157283532D4397EB00F20253 /* StyleLength.h */, + 157283542D4397EB00F20253 /* StyleSizeLength.h */, + 157283552D4397EB00F20253 /* StyleValueHandle.h */, + 157283562D4397EB00F20253 /* StyleValuePool.h */, + ); + path = style; + sourceTree = ""; + }; 15865F4A24E5834E00345BD7 = { isa = PBXGroup; children = ( @@ -270,58 +465,35 @@ 15865FFF24E58BD800345BD7 /* Yoga */ = { isa = PBXGroup; children = ( - 153098C726930BAE009B4135 /* include */, - 1586601824E58C3700345BD7 /* event */, - 1586600A24E58C3600345BD7 /* internal */, - 1586601224E58C3600345BD7 /* BitUtils.h */, - 1586601324E58C3600345BD7 /* CompactValue.h */, - 1586602124E58C3700345BD7 /* log.cpp */, - 1586601624E58C3700345BD7 /* log.h */, - 1586600924E58C3600345BD7 /* Utils.cpp */, - 1586601124E58C3600345BD7 /* Utils.h */, - 1586601024E58C3600345BD7 /* YGConfig.cpp */, - 1586601E24E58C3700345BD7 /* YGConfig.h */, - 1586602824E58C3700345BD7 /* YGEnums.cpp */, - 1586602024E58C3700345BD7 /* YGEnums.h */, - 1586601D24E58C3700345BD7 /* YGFloatOptional.h */, - 1586601524E58C3700345BD7 /* YGLayout.cpp */, - 1586602624E58C3700345BD7 /* YGLayout.h */, - 1586601F24E58C3700345BD7 /* YGMacros.h */, - 1586600F24E58C3600345BD7 /* YGNode.cpp */, - 1586602724E58C3700345BD7 /* YGNode.h */, - 1586601724E58C3700345BD7 /* YGNodePrint.cpp */, - 1586601B24E58C3700345BD7 /* YGNodePrint.h */, - 1586600E24E58C3600345BD7 /* YGStyle.cpp */, - 1586602224E58C3700345BD7 /* YGStyle.h */, - 1586601424E58C3700345BD7 /* YGValue.cpp */, - 1586602524E58C3700345BD7 /* YGValue.h */, - 1586602424E58C3700345BD7 /* Yoga-internal.h */, - 1586602324E58C3700345BD7 /* Yoga.cpp */, - 1586601C24E58C3700345BD7 /* Yoga.h */, + 157283242D4397EB00F20253 /* algorithm */, + 157283282D4397EB00F20253 /* config */, + 1572832D2D4397EB00F20253 /* debug */, + 157283422D4397EB00F20253 /* enums */, + 157283452D4397EB00F20253 /* event */, + 1572834D2D4397EB00F20253 /* node */, + 157283502D4397EB00F20253 /* numeric */, + 157283572D4397EB00F20253 /* style */, + 157283582D4397EB00F20253 /* YGConfig.h */, + 157283592D4397EB00F20253 /* YGConfig.cpp */, + 1572835A2D4397EB00F20253 /* YGEnums.h */, + 1572835B2D4397EB00F20253 /* YGEnums.cpp */, + 1572835C2D4397EB00F20253 /* YGMacros.h */, + 1572835D2D4397EB00F20253 /* YGNode.h */, + 1572835E2D4397EB00F20253 /* YGNode.cpp */, + 1572835F2D4397EB00F20253 /* YGNodeLayout.h */, + 157283602D4397EB00F20253 /* YGNodeLayout.cpp */, + 157283612D4397EB00F20253 /* YGNodeStyle.h */, + 157283622D4397EB00F20253 /* YGNodeStyle.cpp */, + 157283632D4397EB00F20253 /* YGPixelGrid.h */, + 157283642D4397EB00F20253 /* YGPixelGrid.cpp */, + 157283652D4397EB00F20253 /* YGValue.h */, + 157283662D4397EB00F20253 /* YGValue.cpp */, + 157283672D4397EB00F20253 /* Yoga.h */, ); name = Yoga; path = ../yoga; sourceTree = ""; }; - 1586600A24E58C3600345BD7 /* internal */ = { - isa = PBXGroup; - children = ( - 1586600B24E58C3600345BD7 /* experiments.cpp */, - 1586600C24E58C3600345BD7 /* experiments-inl.h */, - 1586600D24E58C3600345BD7 /* experiments.h */, - ); - path = internal; - sourceTree = ""; - }; - 1586601824E58C3700345BD7 /* event */ = { - isa = PBXGroup; - children = ( - 1586601924E58C3700345BD7 /* event.h */, - 1586601A24E58C3700345BD7 /* event.cpp */, - ); - path = event; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -347,25 +519,62 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 1586603E24E58C3700345BD7 /* YGEnums.h in Headers */, - 1586603A24E58C3700345BD7 /* Yoga.h in Headers */, - 1586603D24E58C3700345BD7 /* YGMacros.h in Headers */, - 1586604324E58C3700345BD7 /* YGValue.h in Headers */, - 153098CA26930BAF009B4135 /* Yoga-umbrella.h in Headers */, - 1586604524E58C3700345BD7 /* YGNode.h in Headers */, - 1586604024E58C3700345BD7 /* YGStyle.h in Headers */, - 1586603124E58C3700345BD7 /* BitUtils.h in Headers */, - 1586603024E58C3700345BD7 /* Utils.h in Headers */, - 1586602B24E58C3700345BD7 /* experiments-inl.h in Headers */, - 1586603724E58C3700345BD7 /* event.h in Headers */, - 1586603524E58C3700345BD7 /* log.h in Headers */, - 1586603224E58C3700345BD7 /* CompactValue.h in Headers */, - 1586603924E58C3700345BD7 /* YGNodePrint.h in Headers */, - 1586604224E58C3700345BD7 /* Yoga-internal.h in Headers */, - 1586603C24E58C3700345BD7 /* YGConfig.h in Headers */, - 1586604424E58C3700345BD7 /* YGLayout.h in Headers */, - 1586602C24E58C3700345BD7 /* experiments.h in Headers */, - 1586603B24E58C3700345BD7 /* YGFloatOptional.h in Headers */, + 157283AA2D4397EB00F20253 /* YGValue.h in Headers */, + 157283922D4397EB00F20253 /* YGPixelGrid.h in Headers */, + 1572839F2D4397EB00F20253 /* YGNodeStyle.h in Headers */, + 157283A82D4397EB00F20253 /* YGNodeLayout.h in Headers */, + 157283972D4397EB00F20253 /* YGNode.h in Headers */, + 157283852D4397EB00F20253 /* YGMacros.h in Headers */, + 1572837C2D4397EB00F20253 /* YGEnums.h in Headers */, + 157283B22D4397EB00F20253 /* YGConfig.h in Headers */, + 157283842D4397EB00F20253 /* Yoga.h in Headers */, + 1572837D2D4397EB00F20253 /* Dimension.h in Headers */, + 1572837E2D4397EB00F20253 /* FlexDirection.h in Headers */, + 1572837F2D4397EB00F20253 /* Gutter.h in Headers */, + 157283802D4397EB00F20253 /* LayoutableChildren.h in Headers */, + 157283812D4397EB00F20253 /* NodeType.h in Headers */, + 157283822D4397EB00F20253 /* Wrap.h in Headers */, + 157283832D4397EB00F20253 /* PixelGrid.h in Headers */, + 157283862D4397EB00F20253 /* Align.h in Headers */, + 157283872D4397EB00F20253 /* Overflow.h in Headers */, + 157283882D4397EB00F20253 /* StyleValuePool.h in Headers */, + 157283892D4397EB00F20253 /* Justify.h in Headers */, + 1572838A2D4397EB00F20253 /* Log.h in Headers */, + 1572838B2D4397EB00F20253 /* LayoutResults.h in Headers */, + 1572838C2D4397EB00F20253 /* StyleSizeLength.h in Headers */, + 1572838D2D4397EB00F20253 /* Config.h in Headers */, + 1572838E2D4397EB00F20253 /* Direction.h in Headers */, + 1572838F2D4397EB00F20253 /* ExperimentalFeature.h in Headers */, + 157283902D4397EB00F20253 /* Display.h in Headers */, + 157283912D4397EB00F20253 /* SizingMode.h in Headers */, + 157283932D4397EB00F20253 /* MeasureMode.h in Headers */, + 157283942D4397EB00F20253 /* TrailingPosition.h in Headers */, + 157283952D4397EB00F20253 /* Align.h in Headers */, + 157283962D4397EB00F20253 /* SmallValueBuffer.h in Headers */, + 157283982D4397EB00F20253 /* StyleLength.h in Headers */, + 157283992D4397EB00F20253 /* CalculateLayout.h in Headers */, + 1572839A2D4397EB00F20253 /* FlexLine.h in Headers */, + 1572839B2D4397EB00F20253 /* BoundAxis.h in Headers */, + 1572839C2D4397EB00F20253 /* AbsoluteLayout.h in Headers */, + 1572839D2D4397EB00F20253 /* Edge.h in Headers */, + 1572839E2D4397EB00F20253 /* AssertFatal.h in Headers */, + 157283A02D4397EB00F20253 /* FlexDirection.h in Headers */, + 157283A12D4397EB00F20253 /* Comparison.h in Headers */, + 157283A22D4397EB00F20253 /* Cache.h in Headers */, + 157283A32D4397EB00F20253 /* Baseline.h in Headers */, + 157283A42D4397EB00F20253 /* Errata.h in Headers */, + 157283A52D4397EB00F20253 /* BoxSizing.h in Headers */, + 157283A62D4397EB00F20253 /* PositionType.h in Headers */, + 157283A72D4397EB00F20253 /* Unit.h in Headers */, + 157283A92D4397EB00F20253 /* StyleValueHandle.h in Headers */, + 157283AB2D4397EB00F20253 /* LogLevel.h in Headers */, + 157283AC2D4397EB00F20253 /* YogaEnums.h in Headers */, + 157283AD2D4397EB00F20253 /* Style.h in Headers */, + 157283AE2D4397EB00F20253 /* FloatOptional.h in Headers */, + 157283AF2D4397EB00F20253 /* CachedMeasurement.h in Headers */, + 157283B02D4397EB00F20253 /* PhysicalEdge.h in Headers */, + 157283B12D4397EB00F20253 /* Node.h in Headers */, + 157283B32D4397EB00F20253 /* event.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -558,18 +767,25 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1586602A24E58C3700345BD7 /* experiments.cpp in Sources */, - 1586602F24E58C3700345BD7 /* YGConfig.cpp in Sources */, - 1586602E24E58C3700345BD7 /* YGNode.cpp in Sources */, - 1586603624E58C3700345BD7 /* YGNodePrint.cpp in Sources */, - 1586604624E58C3700345BD7 /* YGEnums.cpp in Sources */, - 1586602D24E58C3700345BD7 /* YGStyle.cpp in Sources */, - 1586604124E58C3700345BD7 /* Yoga.cpp in Sources */, - 1586602924E58C3700345BD7 /* Utils.cpp in Sources */, - 1586603424E58C3700345BD7 /* YGLayout.cpp in Sources */, - 1586603824E58C3700345BD7 /* event.cpp in Sources */, - 1586603F24E58C3700345BD7 /* log.cpp in Sources */, - 1586603324E58C3700345BD7 /* YGValue.cpp in Sources */, + 157283692D4397EB00F20253 /* Node.cpp in Sources */, + 1572836A2D4397EB00F20253 /* Cache.cpp in Sources */, + 1572836B2D4397EB00F20253 /* YGEnums.cpp in Sources */, + 1572836C2D4397EB00F20253 /* Baseline.cpp in Sources */, + 1572836D2D4397EB00F20253 /* event.cpp in Sources */, + 1572836E2D4397EB00F20253 /* PixelGrid.cpp in Sources */, + 1572836F2D4397EB00F20253 /* Config.cpp in Sources */, + 157283702D4397EB00F20253 /* Log.cpp in Sources */, + 157283712D4397EB00F20253 /* YGConfig.cpp in Sources */, + 157283722D4397EB00F20253 /* YGPixelGrid.cpp in Sources */, + 157283732D4397EB00F20253 /* AbsoluteLayout.cpp in Sources */, + 157283742D4397EB00F20253 /* AssertFatal.cpp in Sources */, + 157283752D4397EB00F20253 /* YGNodeLayout.cpp in Sources */, + 157283762D4397EB00F20253 /* YGValue.cpp in Sources */, + 157283772D4397EB00F20253 /* LayoutResults.cpp in Sources */, + 157283782D4397EB00F20253 /* YGNodeStyle.cpp in Sources */, + 157283792D4397EB00F20253 /* YGNode.cpp in Sources */, + 1572837A2D4397EB00F20253 /* FlexLine.cpp in Sources */, + 1572837B2D4397EB00F20253 /* CalculateLayout.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -695,7 +911,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -765,7 +981,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -879,6 +1095,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_INPUT_FILETYPE = sourcecode.cpp.cpp; + HEADER_SEARCH_PATHS = "${SRCROOT}/.."; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -886,7 +1103,6 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "${SRCROOT}/../yoga/include/Yoga.modulemap"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Yoga; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; @@ -906,6 +1122,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_INPUT_FILETYPE = sourcecode.cpp.cpp; + HEADER_SEARCH_PATHS = "${SRCROOT}/.."; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -913,7 +1130,6 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "${SRCROOT}/../yoga/include/Yoga.modulemap"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Yoga; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; diff --git a/tests/BitUtilsTest.cpp b/tests/BitUtilsTest.cpp deleted file mode 100644 index d20ee3071b..0000000000 --- a/tests/BitUtilsTest.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 facebook { -namespace yoga { - -TEST(BitUtils, one_boolean_defaults_to_false) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - static_assert( - detail::getBooleanData(flags, 0) == false, - "first boolean member must default to false"); -} - -TEST(BitUtils, one_boolean_can_be_initialized_to_true) { - constexpr uint8_t flags = 1; - - ASSERT_EQ(detail::getBooleanData(flags, 0), true); - static_assert( - detail::getBooleanData(flags, 0) == true, - "first boolean member must be initialized to true"); -} - -TEST(BitUtils, one_boolean_can_be_set_to_true) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 0, true); - ASSERT_EQ(detail::getBooleanData(flags, 0), true); -} - -TEST(BitUtils, second_boolean_defaults_to_false) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getBooleanData(flags, 1), false); - static_assert( - detail::getBooleanData(flags, 1) == false, - "second boolean member must default to false"); -} - -TEST(BitUtils, second_boolean_can_be_initialized_to_true) { - constexpr uint8_t flags = 2; - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), true); - static_assert( - detail::getBooleanData(flags, 0) == false, - "first boolean member must default to false"); - static_assert( - detail::getBooleanData(flags, 1) == true, - "second boolean member must be initialized to true"); -} - -TEST(BitUtils, second_boolean_can_be_set_to_true) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 1, true); - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), true); -} - -TEST(BitUtils, third_boolean_defaults_to_false) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getBooleanData(flags, 2), false); - static_assert( - detail::getBooleanData(flags, 2) == false, - "second boolean member must default to false"); -} - -TEST(BitUtils, third_boolean_can_be_initialized_to_true) { - constexpr uint8_t flags = 4; - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), false); - ASSERT_EQ(detail::getBooleanData(flags, 2), true); - static_assert( - detail::getBooleanData(flags, 0) == false, - "first boolean member must default to false"); - static_assert( - detail::getBooleanData(flags, 1) == false, - "second boolean member must default to false"); - static_assert( - detail::getBooleanData(flags, 2) == true, - "second boolean member must be initialized to true"); -} - -TEST(BitUtils, third_boolean_can_be_set_to_true) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 2, true); - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), false); - ASSERT_EQ(detail::getBooleanData(flags, 2), true); -} - -TEST(BitUtils, setting_boolean_values_does_not_spill_over) { - uint8_t flags = 0; - - detail::setBooleanData(flags, 1, (bool) 7); - - ASSERT_EQ(detail::getBooleanData(flags, 0), false); - ASSERT_EQ(detail::getBooleanData(flags, 1), true); - ASSERT_EQ(detail::getBooleanData(flags, 2), false); -} - -TEST(BitUtils, first_enum_defaults_to_0) { - constexpr uint8_t flags = 0; - - ASSERT_EQ(detail::getEnumData(flags, 0), YGAlignAuto); - static_assert( - detail::getEnumData(flags, 0) == YGAlignAuto, - "first enum member must default to 0"); -} - -TEST(BitUtils, first_enum_can_be_set) { - uint8_t flags = 0; - - detail::setEnumData(flags, 0, YGAlignSpaceBetween); - - ASSERT_EQ(detail::getEnumData(flags, 0), YGAlignSpaceBetween); -} - -TEST(BitUtils, second_enum_defaults_to_0) { - constexpr uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgeOffset = 3; - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getEnumData(flags, edgeOffset), YGEdgeLeft); - static_assert( - detail::getEnumData(flags, alignOffset) == YGAlignAuto, - "first enum member must default to 0"); - static_assert( - detail::getEnumData(flags, edgeOffset) == YGEdgeLeft, - "second enum member must default to 0"); -} - -TEST(BitUtils, second_enum_can_be_set) { - uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgeOffset = 3; - - detail::setEnumData(flags, edgeOffset, YGEdgeAll); - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getEnumData(flags, edgeOffset), YGEdgeAll); -} - -TEST(BitUtils, third_enum_defaults_to_0) { - constexpr uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t boolOffset = 3; - static constexpr size_t edgesOffset = 4; - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); - ASSERT_EQ(detail::getEnumData(flags, edgesOffset), YGEdgeLeft); - static_assert( - detail::getEnumData(flags, alignOffset) == YGAlignAuto, - "first enum member must default to 0"); - static_assert( - detail::getBooleanData(flags, boolOffset) == false, - "middle boolean member must default to false"); - static_assert( - detail::getEnumData(flags, edgesOffset) == YGEdgeLeft, - "last enum member must default to 0"); -} - -TEST(BitUtils, third_enum_can_be_set) { - uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t boolOffset = 3; - static constexpr size_t edgesOffset = 4; - - detail::setEnumData(flags, edgesOffset, YGEdgeVertical); - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), YGAlignAuto); - ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); - ASSERT_EQ(detail::getEnumData(flags, edgesOffset), YGEdgeVertical); -} - -TEST(BitUtils, setting_values_does_not_spill_over) { - uint8_t flags = 0; - static constexpr size_t alignOffset = 0; - static constexpr size_t edgesOffset = 3; - static constexpr size_t boolOffset = 7; - - detail::setEnumData(flags, edgesOffset, (YGEdge) 0xffffff); - - ASSERT_EQ(detail::getEnumData(flags, alignOffset), 0); - ASSERT_EQ(detail::getBooleanData(flags, boolOffset), false); - ASSERT_EQ(detail::getEnumData(flags, edgesOffset), 0xf); -} - -} // namespace yoga -} // namespace facebook diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000000..c48bfb9fb0 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + + +cmake_minimum_required(VERSION 3.13...3.26) +project(tests) +set(CMAKE_VERBOSE_MAKEFILE on) + +include(FetchContent) +include(GoogleTest) + +set(YOGA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..) +include(${YOGA_ROOT}/cmake/project-defaults.cmake) + +# Fetch GTest +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip +) +FetchContent_MakeAvailable(googletest) + +add_subdirectory(${YOGA_ROOT}/yoga ${CMAKE_CURRENT_BINARY_DIR}/yoga) + +file(GLOB SOURCES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/**/*.cpp) + +enable_testing() + +add_executable(yogatests ${SOURCES}) +target_link_libraries(yogatests yogacore GTest::gtest_main) + +gtest_discover_tests(yogatests) diff --git a/tests/CompactValueTest.cpp b/tests/CompactValueTest.cpp deleted file mode 100644 index a77d0e9261..0000000000 --- a/tests/CompactValueTest.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#define YOGA_COMPACT_VALUE_TEST - -#include -#include -#include - -using facebook::yoga::detail::CompactValue; - -const auto tooSmall = nextafter(CompactValue::LOWER_BOUND, -INFINITY); -const auto tooLargePoints = - nextafter(CompactValue::UPPER_BOUND_POINT, INFINITY); -const auto tooLargePercent = - nextafter(CompactValue::UPPER_BOUND_PERCENT, INFINITY); - -TEST(YogaTest, compact_value_can_represent_undefined) { - auto c = CompactValue{YGValue{12.5, YGUnitUndefined}}; - YGValue v = c; - ASSERT_EQ(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-1.25, YGUnitPoint})); - ASSERT_NE(v, (YGValue{25, YGUnitPercent})); - ASSERT_TRUE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_manages_infinity_as_undefined) { - auto c = CompactValue{ - YGValue{std::numeric_limits::infinity(), YGUnitUndefined}}; - YGValue v = c; - ASSERT_EQ(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-1.25, YGUnitPoint})); - ASSERT_NE(v, (YGValue{25, YGUnitPercent})); - ASSERT_TRUE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_auto) { - auto c = CompactValue{YGValue{0, YGUnitAuto}}; - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_EQ(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-1.25, YGUnitPoint})); - ASSERT_NE(v, (YGValue{25, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_TRUE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_zero_points) { - auto c = CompactValue{YGValue{0, YGUnitPoint}}; - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{0, YGUnitPoint})); - ASSERT_NE(v, (YGValue{0, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_lower_bound_points) { - auto c = CompactValue({YGValue{CompactValue::LOWER_BOUND, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPoint})); - ASSERT_NE(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_negative_lower_bound_points) { - auto c = CompactValue({YGValue{-CompactValue::LOWER_BOUND, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPoint})); - ASSERT_NE(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_clamps_smaller_than_lower_bound_points_to_zero) { - auto c = CompactValue({YGValue{tooSmall, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{0, YGUnitPoint})); - ASSERT_NE(v, (YGValue{0, YGUnitPercent})); -} - -TEST( - YogaTest, - compact_value_clamps_greater_than_negative_lower_bound_points_to_zero) { - auto c = CompactValue({YGValue{-tooSmall, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{0, YGUnitPoint})); - ASSERT_NE(v, (YGValue{0, YGUnitPercent})); -} - -TEST(YogaTest, compact_value_can_represent_upper_bound_points) { - auto c = - CompactValue({YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); - ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_negative_upper_bound_points) { - auto c = - CompactValue({YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); - ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST( - YogaTest, - compact_value_clamps_greater_than__upper_bound_points_to_upper_bound) { - auto c = CompactValue({YGValue{tooLargePoints, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); - ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); -} - -TEST( - YogaTest, - compact_value_clamps_smaller_than_negative_upper_bound_points_to_upper_bound) { - auto c = CompactValue({YGValue{-tooLargePoints, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPoint})); - ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_POINT, YGUnitPercent})); -} - -TEST(YogaTest, compact_value_can_represent_one_point) { - auto c = CompactValue({YGValue{1, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{1, YGUnitPoint})); - ASSERT_NE(v, (YGValue{1, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_negative_one_point) { - auto c = CompactValue({YGValue{-1, YGUnitPoint}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_EQ(v, (YGValue{-1, YGUnitPoint})); - ASSERT_NE(v, (YGValue{-1, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_zero_percent) { - auto c = CompactValue{YGValue{0, YGUnitPercent}}; - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{0, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{0, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_lower_bound_percent) { - auto c = CompactValue({YGValue{CompactValue::LOWER_BOUND, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{CompactValue::LOWER_BOUND, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_negative_lower_bound_percent) { - auto c = CompactValue({YGValue{-CompactValue::LOWER_BOUND, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{-CompactValue::LOWER_BOUND, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_clamps_smaller_than_lower_bound_percent_to_zero) { - auto c = CompactValue({YGValue{tooSmall, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{0, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{0, YGUnitPercent})); -} - -TEST( - YogaTest, - compact_value_clamps_greater_than_negative_lower_bound_percent_to_zero) { - auto c = CompactValue({YGValue{-tooSmall, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{0, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{0, YGUnitPercent})); -} - -TEST(YogaTest, compact_value_can_represent_upper_bound_percent) { - auto c = - CompactValue({YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_negative_upper_bound_percent) { - auto c = CompactValue( - {YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST( - YogaTest, - compact_value_clamps_greater_than_upper_bound_percent_to_upper_bound) { - auto c = CompactValue({YGValue{tooLargePercent, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); -} - -TEST( - YogaTest, - compact_value_clamps_smaller_than_negative_upper_bound_percent_to_upper_bound) { - auto c = CompactValue({YGValue{-tooLargePercent, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{-CompactValue::UPPER_BOUND_PERCENT, YGUnitPercent})); -} - -TEST(YogaTest, compact_value_can_represent_one_percent) { - auto c = CompactValue({YGValue{1, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{1, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{1, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, compact_value_can_represent_negative_one_percent) { - auto c = CompactValue({YGValue{-1, YGUnitPercent}}); - YGValue v = c; - ASSERT_NE(v, YGValueUndefined); - ASSERT_NE(v, YGValueAuto); - ASSERT_NE(v, (YGValue{-1, YGUnitPoint})); - ASSERT_EQ(v, (YGValue{-1, YGUnitPercent})); - ASSERT_FALSE(c.isUndefined()); - ASSERT_FALSE(c.isAuto()); -} - -TEST(YogaTest, dedicated_unit_factories) { - ASSERT_EQ(CompactValue::ofUndefined(), CompactValue(YGValueUndefined)); - ASSERT_EQ(CompactValue::ofAuto(), CompactValue(YGValueAuto)); - ASSERT_EQ( - CompactValue::of(-9876.5), - CompactValue(YGValue{-9876.5, YGUnitPoint})); - ASSERT_EQ( - CompactValue::of(123.456), - CompactValue(YGValue{123.456, YGUnitPercent})); -} - -TEST(YogaTest, dedicated_unit_maybe_factories) { - ASSERT_EQ( - CompactValue::ofMaybe(-9876.5), - CompactValue(YGValue{-9876.5, YGUnitPoint})); - ASSERT_EQ( - CompactValue::ofMaybe(YGUndefined), - CompactValue(YGValueUndefined)); - ASSERT_EQ( - CompactValue::ofMaybe(123.456), - CompactValue(YGValue{123.456, YGUnitPercent})); - ASSERT_EQ( - CompactValue::ofMaybe(YGUndefined), - CompactValue(YGValueUndefined)); -} - -TEST(YogaTest, can_be_assigned_from_YGValue) { - CompactValue c{}; - - YGValue v{2.0, YGUnitPercent}; - c = v; - ASSERT_EQ((YGValue) c, v); - - c = YGValue{123, YGUnitPoint}; - ASSERT_EQ((YGValue) c, (YGValue{123, YGUnitPoint})); -} - -TEST(YogaTest, compact_value_bound_representations) { - ASSERT_EQ( - CompactValue::of(CompactValue::LOWER_BOUND).repr(), - uint64_t{0}); - ASSERT_EQ( - CompactValue::of(CompactValue::UPPER_BOUND_POINT).repr(), - uint64_t{0x3fffffffffffffff}); - ASSERT_EQ( - CompactValue::of(CompactValue::LOWER_BOUND).repr(), - uint64_t{0x4000000000000000}); - ASSERT_EQ( - CompactValue::of(CompactValue::UPPER_BOUND_PERCENT).repr(), - uint64_t{0x7f7fffffffffffff}); - - ASSERT_EQ( - CompactValue::of(-CompactValue::LOWER_BOUND).repr(), - uint64_t{0x8000000000000000}); - ASSERT_EQ( - CompactValue::of(-CompactValue::UPPER_BOUND_POINT).repr(), - uint64_t{0xbfffffffffffffff}); - ASSERT_EQ( - CompactValue::of(-CompactValue::LOWER_BOUND).repr(), - uint64_t{0xc000000000000000}); - ASSERT_EQ( - CompactValue::of(-CompactValue::UPPER_BOUND_PERCENT) - .repr(), - uint64_t{0xff7fffffffffffff}); -} diff --git a/tests/EventsTest.cpp b/tests/EventsTest.cpp index f67eb74245..f911b4b211 100644 --- a/tests/EventsTest.cpp +++ b/tests/EventsTest.cpp @@ -1,37 +1,34 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 #include -#include -#include #include #include #include #include -#include -namespace facebook { -namespace yoga { -namespace test { +#include "util/TestUtil.h" + +namespace facebook::yoga::test { template struct TypedEventTestData {}; template <> struct TypedEventTestData { - void* layoutContext; LayoutData layoutData; }; struct EventArgs { - const YGNode* node; + const YGNodeConstRef node; Event::Type type; std::unique_ptr> dataPtr; std::unique_ptr> eventTestDataPtr; @@ -48,12 +45,17 @@ struct EventArgs { }; class EventTest : public ::testing::Test { - ScopedEventSubscription subscription = {&EventTest::listen}; - static void listen(const YGNode&, Event::Type, Event::Data); + ScopedEventSubscription subscription{&EventTest::listen}; + static void listen( + YGNodeConstRef /*node*/, + Event::Type /*type*/, + Event::Data /*data*/); -public: + public: static std::vector events; - static EventArgs& lastEvent() { return events.back(); } + static EventArgs& lastEvent() { + return events.back(); + } void TearDown() override; }; @@ -231,9 +233,9 @@ TEST_F(EventTest, layout_events_has_max_measure_cache) { YGNodeInsertChild(root, a, 0); auto b = YGNodeNew(); YGNodeInsertChild(root, b, 1); - YGNodeStyleSetFlexBasis(a, 10.0); + YGNodeStyleSetFlexBasis(a, 10.0f); - for (auto s : {20, 30, 40}) { + for (auto s : {20.0f, 30.0f, 40.0f}) { YGNodeCalculateLayout(root, s, s, YGDirectionLTR); } @@ -251,7 +253,7 @@ TEST_F(EventTest, layout_events_has_max_measure_cache) { TEST_F(EventTest, measure_functions_get_wrapped) { auto root = YGNodeNew(); YGNodeSetMeasureFunc( - root, [](YGNodeRef, double, YGMeasureMode, double, YGMeasureMode) { + root, [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode) { return YGSize{}; }); @@ -269,7 +271,8 @@ TEST_F(EventTest, baseline_functions_get_wrapped) { auto child = YGNodeNew(); YGNodeInsertChild(root, child, 0); - YGNodeSetBaselineFunc(child, [](YGNodeRef, double, double) { return 0.0; }); + YGNodeSetBaselineFunc( + child, [](YGNodeConstRef, float, float) { return 0.0f; }); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); @@ -285,16 +288,16 @@ TEST_F(EventTest, baseline_functions_get_wrapped) { namespace { template -EventArgs createArgs(const YGNode& node, const Event::Data data) { +EventArgs createArgs(YGNodeConstRef node, const Event::Data data) { using Data = Event::TypedData; auto deleteData = [](void* x) { delete static_cast(x); }; - return {&node, E, {new Data{(data.get())}, deleteData}}; + return {node, E, {new Data{(data.get())}, deleteData}, nullptr}; } template EventArgs createArgs( - const YGNode& node, + YGNodeConstRef node, const Event::Data data, TypedEventTestData eventTestData) { using EventTestData = TypedEventTestData; @@ -310,7 +313,10 @@ EventArgs createArgs( } // namespace -void EventTest::listen(const YGNode& node, Event::Type type, Event::Data data) { +void EventTest::listen( + YGNodeConstRef node, + Event::Type type, + Event::Data data) { switch (type) { case Event::NodeAllocation: events.push_back(createArgs(node, data)); @@ -327,7 +333,7 @@ void EventTest::listen(const YGNode& node, Event::Type type, Event::Data data) { case Event::LayoutPassEnd: { auto& eventData = data.get(); events.push_back(createArgs( - node, data, {eventData.layoutContext, *eventData.layoutData})); + node, data, {*eventData.layoutData})); break; } @@ -352,6 +358,4 @@ void EventTest::TearDown() { std::vector EventTest::events{}; -} // namespace test -} // namespace yoga -} // namespace facebook +} // namespace facebook::yoga::test diff --git a/tests/FlexGapTest.cpp b/tests/FlexGapTest.cpp new file mode 100644 index 0000000000..e9cd392dfa --- /dev/null +++ b/tests/FlexGapTest.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +// TODO: move this to a fixture based test once it supports parsing negative +// values +TEST(FlexGap, gap_negative_value) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetGap(root, YGGutterAll, -20); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(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(80, 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGFloatOptionalTest.cpp b/tests/FloatOptionalTest.cpp similarity index 64% rename from tests/YGFloatOptionalTest.cpp rename to tests/FloatOptionalTest.cpp index 4bc34bfe69..2e1f37ce7d 100644 --- a/tests/YGFloatOptionalTest.cpp +++ b/tests/FloatOptionalTest.cpp @@ -1,28 +1,33 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 -#include #include +#include +#include + +using namespace facebook; +using namespace facebook::yoga; -constexpr auto empty = YGFloatOptional{}; -constexpr auto zero = YGFloatOptional{0.0}; -constexpr auto one = YGFloatOptional{1.0}; -constexpr auto positive = YGFloatOptional{1234.5}; -constexpr auto negative = YGFloatOptional{-9876.5}; +constexpr auto empty = FloatOptional{}; +constexpr auto zero = FloatOptional{0.0f}; +constexpr auto one = FloatOptional{1.0f}; +constexpr auto positive = FloatOptional{1234.5f}; +constexpr auto negative = FloatOptional{-9876.5f}; -TEST(YGFloatOptional, value) { +TEST(FloatOptional, value) { ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap())); - ASSERT_EQ(zero.unwrap(), 0.0); - ASSERT_EQ(one.unwrap(), 1.0); - ASSERT_EQ(positive.unwrap(), 1234.5); - ASSERT_EQ(negative.unwrap(), -9876.5); + ASSERT_EQ(zero.unwrap(), 0.0f); + ASSERT_EQ(one.unwrap(), 1.0f); + ASSERT_EQ(positive.unwrap(), 1234.5f); + ASSERT_EQ(negative.unwrap(), -9876.5f); ASSERT_TRUE(empty.isUndefined()); ASSERT_FALSE(zero.isUndefined()); @@ -31,20 +36,20 @@ TEST(YGFloatOptional, value) { ASSERT_FALSE(negative.isUndefined()); } -TEST(YGFloatOptional, equality) { +TEST(FloatOptional, equality) { ASSERT_TRUE(empty == empty); ASSERT_TRUE(empty == YGUndefined); ASSERT_FALSE(empty == zero); ASSERT_FALSE(empty == negative); - ASSERT_FALSE(empty == 12.3); + ASSERT_FALSE(empty == 12.3f); ASSERT_TRUE(zero == zero); - ASSERT_TRUE(zero == 0.0); + ASSERT_TRUE(zero == 0.0f); ASSERT_FALSE(zero == positive); - ASSERT_FALSE(zero == -5555.5); + ASSERT_FALSE(zero == -5555.5f); ASSERT_TRUE(one == one); - ASSERT_TRUE(one == 1.0); + ASSERT_TRUE(one == 1.0f); ASSERT_FALSE(one == positive); ASSERT_TRUE(positive == positive); @@ -56,20 +61,20 @@ TEST(YGFloatOptional, equality) { ASSERT_FALSE(negative == zero); } -TEST(YGFloatOptional, inequality) { +TEST(FloatOptional, inequality) { ASSERT_FALSE(empty != empty); ASSERT_FALSE(empty != YGUndefined); ASSERT_TRUE(empty != zero); ASSERT_TRUE(empty != negative); - ASSERT_TRUE(empty != 12.3); + ASSERT_TRUE(empty != 12.3f); ASSERT_FALSE(zero != zero); - ASSERT_FALSE(zero != 0.0); + ASSERT_FALSE(zero != 0.0f); ASSERT_TRUE(zero != positive); - ASSERT_TRUE(zero != -5555.5); + ASSERT_TRUE(zero != -5555.5f); ASSERT_FALSE(one != one); - ASSERT_FALSE(one != 1.0); + ASSERT_FALSE(one != 1.0f); ASSERT_TRUE(one != positive); ASSERT_FALSE(positive != positive); @@ -81,7 +86,7 @@ TEST(YGFloatOptional, inequality) { ASSERT_TRUE(negative != zero); } -TEST(YGFloatOptional, greater_than_with_undefined) { +TEST(FloatOptional, greater_than_with_undefined) { ASSERT_FALSE(empty > empty); ASSERT_FALSE(empty > zero); ASSERT_FALSE(empty > one); @@ -93,7 +98,7 @@ TEST(YGFloatOptional, greater_than_with_undefined) { ASSERT_FALSE(negative > empty); } -TEST(YGFloatOptional, greater_than) { +TEST(FloatOptional, greater_than) { ASSERT_TRUE(zero > negative); ASSERT_FALSE(zero > zero); ASSERT_FALSE(zero > positive); @@ -103,10 +108,10 @@ TEST(YGFloatOptional, greater_than) { ASSERT_TRUE(one > zero); ASSERT_FALSE(one > positive); - ASSERT_TRUE(negative > YGFloatOptional{-INFINITY}); + ASSERT_TRUE(negative > FloatOptional{-INFINITY}); } -TEST(YGFloatOptional, less_than_with_undefined) { +TEST(FloatOptional, less_than_with_undefined) { ASSERT_FALSE(empty < empty); ASSERT_FALSE(zero < empty); ASSERT_FALSE(one < empty); @@ -118,7 +123,7 @@ TEST(YGFloatOptional, less_than_with_undefined) { ASSERT_FALSE(empty < negative); } -TEST(YGFloatOptional, less_than) { +TEST(FloatOptional, less_than) { ASSERT_TRUE(negative < zero); ASSERT_FALSE(zero < zero); ASSERT_FALSE(positive < zero); @@ -128,10 +133,10 @@ TEST(YGFloatOptional, less_than) { ASSERT_TRUE(zero < one); ASSERT_FALSE(positive < one); - ASSERT_TRUE(YGFloatOptional{-INFINITY} < negative); + ASSERT_TRUE(FloatOptional{-INFINITY} < negative); } -TEST(YGFloatOptional, greater_than_equals_with_undefined) { +TEST(FloatOptional, greater_than_equals_with_undefined) { ASSERT_TRUE(empty >= empty); ASSERT_FALSE(empty >= zero); ASSERT_FALSE(empty >= one); @@ -143,7 +148,7 @@ TEST(YGFloatOptional, greater_than_equals_with_undefined) { ASSERT_FALSE(negative >= empty); } -TEST(YGFloatOptional, greater_than_equals) { +TEST(FloatOptional, greater_than_equals) { ASSERT_TRUE(zero >= negative); ASSERT_TRUE(zero >= zero); ASSERT_FALSE(zero >= positive); @@ -153,10 +158,10 @@ TEST(YGFloatOptional, greater_than_equals) { ASSERT_TRUE(one >= zero); ASSERT_FALSE(one >= positive); - ASSERT_TRUE(negative >= YGFloatOptional{-INFINITY}); + ASSERT_TRUE(negative >= FloatOptional{-INFINITY}); } -TEST(YGFloatOptional, less_than_equals_with_undefined) { +TEST(FloatOptional, less_than_equals_with_undefined) { ASSERT_TRUE(empty <= empty); ASSERT_FALSE(zero <= empty); ASSERT_FALSE(one <= empty); @@ -168,7 +173,7 @@ TEST(YGFloatOptional, less_than_equals_with_undefined) { ASSERT_FALSE(empty <= negative); } -TEST(YGFloatOptional, less_than_equals) { +TEST(FloatOptional, less_than_equals) { ASSERT_TRUE(negative <= zero); ASSERT_TRUE(zero <= zero); ASSERT_FALSE(positive <= zero); @@ -178,32 +183,32 @@ TEST(YGFloatOptional, less_than_equals) { ASSERT_TRUE(zero <= one); ASSERT_FALSE(positive <= one); - ASSERT_TRUE(YGFloatOptional{-INFINITY} <= negative); + ASSERT_TRUE(FloatOptional{-INFINITY} <= negative); } -TEST(YGFloatOptional, addition) { +TEST(FloatOptional, addition) { auto n = negative.unwrap(); auto p = positive.unwrap(); ASSERT_EQ(zero + one, one); - ASSERT_EQ(negative + positive, YGFloatOptional{n + p}); + ASSERT_EQ(negative + positive, FloatOptional{n + p}); ASSERT_EQ(empty + zero, empty); ASSERT_EQ(empty + empty, empty); ASSERT_EQ(negative + empty, empty); } -TEST(YGFloatOptionalTest, YGFloatOptionalMax) { - ASSERT_EQ(YGFloatOptionalMax(empty, empty), empty); - ASSERT_EQ(YGFloatOptionalMax(empty, positive), positive); - ASSERT_EQ(YGFloatOptionalMax(negative, empty), negative); - ASSERT_EQ(YGFloatOptionalMax(negative, YGFloatOptional{-INFINITY}), negative); +TEST(YGFloatOptiona, maxOrDefined) { + ASSERT_EQ(yoga::maxOrDefined(empty, empty), empty); + ASSERT_EQ(yoga::maxOrDefined(empty, positive), positive); + ASSERT_EQ(yoga::maxOrDefined(negative, empty), negative); + ASSERT_EQ(yoga::maxOrDefined(negative, FloatOptional{-INFINITY}), negative); ASSERT_EQ( - YGFloatOptionalMax(YGFloatOptional{1.0}, YGFloatOptional{1.125}), - YGFloatOptional{1.125}); + yoga::maxOrDefined(FloatOptional{1.0f}, FloatOptional{1.125f}), + FloatOptional{1.125f}); } -TEST(YGFloatOptionalTest, unwrap) { +TEST(FloatOptional, unwrap) { ASSERT_TRUE(YGFloatIsUndefined(empty.unwrap())); - ASSERT_EQ(zero.unwrap(), 0.0); - ASSERT_EQ(YGFloatOptional{123456.78}.unwrap(), 123456.78); + ASSERT_EQ(zero.unwrap(), 0.0f); + ASSERT_EQ(FloatOptional{123456.78f}.unwrap(), 123456.78f); } diff --git a/tests/InternalTest.cpp b/tests/InternalTest.cpp deleted file mode 100644 index 9a789086f3..0000000000 --- a/tests/InternalTest.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include - -using namespace facebook::yoga::internal; - -struct YogaInternalTest : public testing::Test { - void SetUp() override; -}; - -TEST_F(YogaInternalTest, experiments_are_initially_disabled) { - ASSERT_EQ(isEnabled(Experiment::kDoubleMeasureCallbacks), false); -} - -TEST_F(YogaInternalTest, experiments_are_can_be_enabled) { - enable(Experiment::kDoubleMeasureCallbacks); - ASSERT_EQ(isEnabled(Experiment::kDoubleMeasureCallbacks), true); -} - -TEST_F(YogaInternalTest, experiments_are_can_be_disabled) { - enable(Experiment::kDoubleMeasureCallbacks); - disable(Experiment::kDoubleMeasureCallbacks); - - ASSERT_EQ(isEnabled(Experiment::kDoubleMeasureCallbacks), false); -} - -TEST_F(YogaInternalTest, experiments_are_can_be_toggled_on) { - disable(Experiment::kDoubleMeasureCallbacks); - - ASSERT_EQ(toggle(Experiment::kDoubleMeasureCallbacks), false); - ASSERT_EQ(isEnabled(Experiment::kDoubleMeasureCallbacks), true); -} - -TEST_F(YogaInternalTest, experiments_are_can_be_toggled_off) { - enable(Experiment::kDoubleMeasureCallbacks); - - ASSERT_EQ(toggle(Experiment::kDoubleMeasureCallbacks), true); - ASSERT_EQ(isEnabled(Experiment::kDoubleMeasureCallbacks), false); -} - -void YogaInternalTest::SetUp() { - disableAllExperiments(); -} diff --git a/tests/OrdinalsTest.cpp b/tests/OrdinalsTest.cpp new file mode 100644 index 0000000000..8360b51351 --- /dev/null +++ b/tests/OrdinalsTest.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 facebook::yoga { + +TEST(Ordinals, iteration) { + std::deque expectedEdges{ + Edge::Left, + Edge::Top, + Edge::Right, + Edge::Bottom, + Edge::Start, + Edge::End, + Edge::Horizontal, + Edge::Vertical, + Edge::All}; + + for (auto edge : yoga::ordinals()) { + ASSERT_EQ(edge, expectedEdges.front()); + expectedEdges.pop_front(); + } + + ASSERT_TRUE(expectedEdges.empty()); +} + +} // namespace facebook::yoga diff --git a/tests/SmallValueBufferTest.cpp b/tests/SmallValueBufferTest.cpp new file mode 100644 index 0000000000..21f897e33d --- /dev/null +++ b/tests/SmallValueBufferTest.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +namespace facebook::yoga { + +constexpr size_t kBufferSize = 4; + +TEST(SmallValueBuffer, copy_assignment_with_overflow) { + std::array handles{}; + + SmallValueBuffer buffer1; + for (size_t i = 0; i < kBufferSize + 1; ++i) { + handles[i] = buffer1.push(static_cast(i)); + } + + SmallValueBuffer buffer2 = buffer1; + for (size_t i = 0; i < kBufferSize + 1; ++i) { + EXPECT_EQ(buffer2.get32(handles[i]), i); + } + + auto handle = buffer1.push(42u); + EXPECT_EQ(buffer1.get32(handle), 42); + + EXPECT_THROW({ buffer2.get32(handle); }, std::logic_error); +} + +TEST(SmallValueBuffer, push_32) { + uint32_t magic = 88567114u; + + SmallValueBuffer buffer; + auto handle = buffer.push(magic); + EXPECT_EQ(buffer.get32(handle), magic); +} + +TEST(SmallValueBuffer, push_overflow) { + uint32_t magic1 = 88567114u; + uint32_t magic2 = 351012214u; + uint32_t magic3 = 146122128u; + uint32_t magic4 = 2171092154u; + uint32_t magic5 = 2269016953u; + + SmallValueBuffer buffer; + EXPECT_EQ(buffer.get32(buffer.push(magic1)), magic1); + EXPECT_EQ(buffer.get32(buffer.push(magic2)), magic2); + EXPECT_EQ(buffer.get32(buffer.push(magic3)), magic3); + EXPECT_EQ(buffer.get32(buffer.push(magic4)), magic4); + EXPECT_EQ(buffer.get32(buffer.push(magic5)), magic5); +} + +TEST(SmallValueBuffer, push_64) { + uint64_t magic = 118138934255546108ull; + + SmallValueBuffer buffer; + auto handle = buffer.push(magic); + EXPECT_EQ(buffer.get64(handle), magic); +} + +TEST(SmallValueBuffer, push_64_overflow) { + uint64_t magic1 = 1401612388342512ull; + uint64_t magic2 = 118712305386210ull; + uint64_t magic3 = 752431801563359011ull; + uint64_t magic4 = 118138934255546108ull; + uint64_t magic5 = 237115443124116111ull; + + SmallValueBuffer buffer; + EXPECT_EQ(buffer.get64(buffer.push(magic1)), magic1); + EXPECT_EQ(buffer.get64(buffer.push(magic2)), magic2); + EXPECT_EQ(buffer.get64(buffer.push(magic3)), magic3); + EXPECT_EQ(buffer.get64(buffer.push(magic4)), magic4); + EXPECT_EQ(buffer.get64(buffer.push(magic5)), magic5); +} + +TEST(SmallValueBuffer, push_64_after_32) { + uint32_t magic32 = 88567114u; + uint64_t magic64 = 118712305386210ull; + + SmallValueBuffer buffer; + auto handle32 = buffer.push(magic32); + EXPECT_EQ(buffer.get32(handle32), magic32); + + auto handle64 = buffer.push(magic64); + EXPECT_EQ(buffer.get64(handle64), magic64); +} + +TEST(SmallValueBuffer, push_32_after_64) { + uint32_t magic32 = 88567114u; + uint64_t magic64 = 118712305386210ull; + + SmallValueBuffer buffer; + auto handle64 = buffer.push(magic64); + EXPECT_EQ(buffer.get64(handle64), magic64); + + auto handle32 = buffer.push(magic32); + EXPECT_EQ(buffer.get32(handle32), magic32); +} + +TEST(SmallValueBuffer, replace_32_with_32) { + uint32_t magic1 = 88567114u; + uint32_t magic2 = 351012214u; + + SmallValueBuffer buffer; + auto handle = buffer.push(magic1); + + EXPECT_EQ(buffer.get32(buffer.replace(handle, magic2)), magic2); +} + +TEST(SmallValueBuffer, replace_32_with_64) { + uint32_t magic32 = 88567114u; + uint64_t magic64 = 118712305386210ull; + + SmallValueBuffer buffer; + auto handle = buffer.push(magic32); + + EXPECT_EQ(buffer.get64(buffer.replace(handle, magic64)), magic64); +} + +TEST(SmallValueBuffer, replace_32_with_64_causes_overflow) { + uint32_t magic1 = 88567114u; + uint32_t magic2 = 351012214u; + uint32_t magic3 = 146122128u; + uint32_t magic4 = 2171092154u; + + uint64_t magic64 = 118712305386210ull; + + SmallValueBuffer buffer; + auto handle1 = buffer.push(magic1); + buffer.push(magic2); + buffer.push(magic3); + buffer.push(magic4); + + EXPECT_EQ(buffer.get64(buffer.replace(handle1, magic64)), magic64); +} + +TEST(SmallValueBuffer, replace_64_with_32) { + uint32_t magic32 = 88567114u; + uint64_t magic64 = 118712305386210ull; + + SmallValueBuffer buffer; + auto handle = buffer.push(magic64); + + EXPECT_EQ(buffer.get32(buffer.replace(handle, magic32)), magic32); +} + +TEST(SmallValueBuffer, replace_64_with_64) { + uint64_t magic1 = 1401612388342512ull; + uint64_t magic2 = 118712305386210ull; + + SmallValueBuffer buffer; + auto handle = buffer.push(magic1); + + EXPECT_EQ(buffer.get64(buffer.replace(handle, magic2)), magic2); +} + +} // namespace facebook::yoga diff --git a/tests/StyleTest.cpp b/tests/StyleTest.cpp new file mode 100644 index 0000000000..d44b73d50f --- /dev/null +++ b/tests/StyleTest.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +namespace facebook::yoga { + +TEST(Style, computed_padding_is_floored) { + yoga::Style style; + style.setPadding(Edge::All, StyleLength::points(-1.0f)); + auto paddingStart = style.computeInlineStartPadding( + FlexDirection::Row, Direction::LTR, 0.0f /*widthSize*/); + ASSERT_EQ(paddingStart, 0.0f); +} + +TEST(Style, computed_border_is_floored) { + yoga::Style style; + style.setBorder(Edge::All, StyleLength::points(-1.0f)); + auto borderStart = + style.computeInlineStartBorder(FlexDirection::Row, Direction::LTR); + ASSERT_EQ(borderStart, 0.0f); +} + +TEST(Style, computed_gap_is_floored) { + yoga::Style style; + style.setGap(Gutter::Column, StyleLength::points(-1.0f)); + auto gapBetweenColumns = style.computeGapForAxis(FlexDirection::Row, 0.0); + ASSERT_EQ(gapBetweenColumns, 0.0f); +} + +TEST(Style, computed_margin_is_not_floored) { + yoga::Style style; + style.setMargin(Edge::All, StyleLength::points(-1.0f)); + auto marginStart = style.computeInlineStartMargin( + FlexDirection::Row, Direction::LTR, 0.0f /*widthSize*/); + ASSERT_EQ(marginStart, -1.0f); +} + +} // namespace facebook::yoga diff --git a/tests/StyleValuePoolTest.cpp b/tests/StyleValuePoolTest.cpp new file mode 100644 index 0000000000..ff38acff36 --- /dev/null +++ b/tests/StyleValuePoolTest.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +namespace facebook::yoga { + +TEST(StyleValuePool, undefined_at_init) { + StyleValuePool pool; + StyleValueHandle handle; + + EXPECT_TRUE(handle.isUndefined()); + EXPECT_FALSE(handle.isDefined()); + EXPECT_EQ(pool.getLength(handle), StyleLength::undefined()); + EXPECT_EQ(pool.getNumber(handle), FloatOptional{}); +} + +TEST(StyleValuePool, auto_at_init) { + StyleValuePool pool; + auto handle = StyleValueHandle::ofAuto(); + + EXPECT_TRUE(handle.isAuto()); + EXPECT_EQ(pool.getLength(handle), StyleLength::ofAuto()); +} + +TEST(StyleValuePool, store_small_int_points) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::points(10)); + + EXPECT_EQ(pool.getLength(handle), StyleLength::points(10)); +} + +TEST(StyleValuePool, store_small_negative_int_points) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::points(-10)); + + EXPECT_EQ(pool.getLength(handle), StyleLength::points(-10)); +} + +TEST(StyleValuePool, store_small_int_percent) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::percent(10)); + + EXPECT_EQ(pool.getLength(handle), StyleLength::percent(10)); +} + +TEST(StyleValuePool, store_large_int_percent) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::percent(262144)); + + EXPECT_EQ(pool.getLength(handle), StyleLength::percent(262144)); +} + +TEST(StyleValuePool, store_large_int_after_small_int) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::percent(10)); + pool.store(handle, StyleLength::percent(262144)); + + EXPECT_EQ(pool.getLength(handle), StyleLength::percent(262144)); +} + +TEST(StyleValuePool, store_small_int_after_large_int) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::percent(262144)); + pool.store(handle, StyleLength::percent(10)); + + EXPECT_EQ(pool.getLength(handle), StyleLength::percent(10)); +} + +TEST(StyleValuePool, store_small_int_number) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, FloatOptional{10.0f}); + + EXPECT_EQ(pool.getNumber(handle), FloatOptional{10.0f}); +} + +TEST(StyleValuePool, store_undefined) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::undefined()); + + EXPECT_TRUE(handle.isUndefined()); + EXPECT_FALSE(handle.isDefined()); + EXPECT_EQ(pool.getLength(handle), StyleLength::undefined()); +} + +TEST(StyleValuePool, store_undefined_after_small_int) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::points(10)); + pool.store(handle, StyleLength::undefined()); + + EXPECT_TRUE(handle.isUndefined()); + EXPECT_FALSE(handle.isDefined()); + EXPECT_EQ(pool.getLength(handle), StyleLength::undefined()); +} + +TEST(StyleValuePool, store_undefined_after_large_int) { + StyleValuePool pool; + StyleValueHandle handle; + + pool.store(handle, StyleLength::points(262144)); + pool.store(handle, StyleLength::undefined()); + + EXPECT_TRUE(handle.isUndefined()); + EXPECT_FALSE(handle.isDefined()); + EXPECT_EQ(pool.getLength(handle), StyleLength::undefined()); +} + +TEST(StyleValuePool, store_keywords) { + StyleValuePool pool; + StyleValueHandle handleMaxContent; + StyleValueHandle handleFitContent; + StyleValueHandle handleStretch; + + pool.store(handleMaxContent, StyleSizeLength::ofMaxContent()); + pool.store(handleFitContent, StyleSizeLength::ofFitContent()); + pool.store(handleStretch, StyleSizeLength::ofStretch()); + + EXPECT_EQ(pool.getSize(handleMaxContent), StyleSizeLength::ofMaxContent()); + EXPECT_EQ(pool.getSize(handleFitContent), StyleSizeLength::ofFitContent()); + EXPECT_EQ(pool.getSize(handleStretch), StyleSizeLength::ofStretch()); +} + +} // namespace facebook::yoga diff --git a/tests/YGAlignBaselineTest.cpp b/tests/YGAlignBaselineTest.cpp index ffa652468c..e8c896ce39 100644 --- a/tests/YGAlignBaselineTest.cpp +++ b/tests/YGAlignBaselineTest.cpp @@ -1,43 +1,36 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 double _baselineFunc( - YGNodeRef node, - const double width, - const double height) { +static float _baselineFunc( + YGNodeConstRef /*node*/, + const float /*width*/, + const float height) { return height / 2; } static YGSize _measure1( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - return YGSize{ - .width = 42, - .height = 50, - }; + YGNodeConstRef /*node*/, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + return YGSize{42, 50}; } static YGSize _measure2( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - return YGSize{ - .width = 279, - .height = 126, - }; + YGNodeConstRef /*node*/, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + return YGSize{279, 126}; } static YGNodeRef createYGNode( @@ -46,13 +39,13 @@ static YGNodeRef createYGNode( int width, int height, bool alignBaseline) { - const YGNodeRef node = YGNodeNewWithConfig(config); + YGNodeRef node = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(node, direction); if (alignBaseline) { YGNodeStyleSetAlignItems(node, YGAlignBaseline); } - YGNodeStyleSetWidth(node, width); - YGNodeStyleSetHeight(node, height); + YGNodeStyleSetWidth(node, (float)width); + YGNodeStyleSetHeight(node, (float)height); return node; } @@ -60,7 +53,7 @@ static YGNodeRef createYGNode( TEST(YogaTest, align_baseline_parent_ht_not_specified) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root, YGAlignStretch); YGNodeStyleSetAlignItems(root, YGAlignBaseline); @@ -68,13 +61,13 @@ TEST(YogaTest, align_baseline_parent_ht_not_specified) { YGNodeStyleSetMaxHeight(root, 170); YGNodeStyleSetMinHeight(root, 0); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 0); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeSetMeasureFunc(root_child0, _measure1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 0); YGNodeStyleSetFlexShrink(root_child1, 1); YGNodeSetMeasureFunc(root_child1, _measure2); @@ -105,17 +98,17 @@ TEST(YogaTest, align_baseline_parent_ht_not_specified) { TEST(YogaTest, align_baseline_with_no_parent_ht) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 150); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 40); YGNodeSetBaselineFunc(root_child1, _baselineFunc); @@ -146,17 +139,17 @@ TEST(YogaTest, align_baseline_with_no_parent_ht) { TEST(YogaTest, align_baseline_with_no_baseline_func_and_no_parent_ht) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 150); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 80); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -186,24 +179,23 @@ TEST(YogaTest, align_baseline_with_no_baseline_func_and_no_parent_ht) { TEST(YogaTest, align_baseline_parent_using_child_in_column_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 800, false); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -231,24 +223,23 @@ TEST( align_baseline_parent_using_child_with_padding_in_column_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 800, false); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeStyleSetPadding(root_child1_child1, YGEdgeLeft, 100); YGNodeStyleSetPadding(root_child1_child1, YGEdgeRight, 100); @@ -280,14 +271,13 @@ TEST( align_baseline_parent_with_padding_using_child_in_column_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 800, false); YGNodeStyleSetPadding(root_child1, YGEdgeLeft, 100); YGNodeStyleSetPadding(root_child1, YGEdgeRight, 100); @@ -295,13 +285,13 @@ TEST( YGNodeStyleSetPadding(root_child1, YGEdgeBottom, 100); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -329,14 +319,13 @@ TEST( align_baseline_parent_with_margin_using_child_in_column_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 800, false); YGNodeStyleSetMargin(root_child1, YGEdgeLeft, 100); YGNodeStyleSetMargin(root_child1, YGEdgeRight, 100); @@ -344,13 +333,13 @@ TEST( YGNodeStyleSetMargin(root_child1, YGEdgeBottom, 100); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -378,24 +367,23 @@ TEST( align_baseline_parent_using_child_with_margin_in_column_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 800, false); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeStyleSetMargin(root_child1_child1, YGEdgeLeft, 100); YGNodeStyleSetMargin(root_child1_child1, YGEdgeRight, 100); @@ -425,24 +413,23 @@ TEST( TEST(YogaTest, align_baseline_parent_using_child_in_row_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionRow, 500, 800, true); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 500, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -470,24 +457,23 @@ TEST( align_baseline_parent_using_child_with_padding_in_row_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionRow, 500, 800, true); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 500, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeStyleSetPadding(root_child1_child1, YGEdgeLeft, 100); YGNodeStyleSetPadding(root_child1_child1, YGEdgeRight, 100); @@ -519,24 +505,23 @@ TEST( align_baseline_parent_using_child_with_margin_in_row_as_reference) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionRow, 500, 800, true); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 500, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeStyleSetMargin(root_child1_child1, YGEdgeLeft, 100); YGNodeStyleSetMargin(root_child1_child1, YGEdgeRight, 100); @@ -568,22 +553,21 @@ TEST( align_baseline_parent_using_child_in_column_as_reference_with_no_baseline_func) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 800, false); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -612,22 +596,21 @@ TEST( align_baseline_parent_using_child_in_row_as_reference_with_no_baseline_func) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = - createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); + YGNodeRef root = createYGNode(config, YGFlexDirectionRow, 1000, 1000, true); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = + YGNodeRef root_child1 = createYGNode(config, YGFlexDirectionRow, 500, 800, true); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 500, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -656,27 +639,27 @@ TEST( align_baseline_parent_using_child_in_column_as_reference_with_height_not_specified) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 1000); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionColumn); YGNodeStyleSetWidth(root_child1, 500); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -707,27 +690,27 @@ TEST( align_baseline_parent_using_child_in_row_as_reference_with_height_not_specified) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 1000); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); YGNodeStyleSetWidth(root_child1, 500); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 500, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); - root_child1_child1->setBaselineFunc(_baselineFunc); + YGNodeSetBaselineFunc(root_child1_child1, _baselineFunc); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -758,25 +741,25 @@ TEST( align_baseline_parent_using_child_in_column_as_reference_with_no_baseline_func_and_height_not_specified) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 1000); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionColumn); YGNodeStyleSetWidth(root_child1, 500); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 300, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); @@ -808,25 +791,25 @@ TEST( align_baseline_parent_using_child_in_row_as_reference_with_no_baseline_func_and_height_not_specified) { YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 1000); - const YGNodeRef root_child0 = + YGNodeRef root_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 600, false); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); YGNodeStyleSetWidth(root_child1, 500); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = + YGNodeRef root_child1_child0 = createYGNode(config, YGFlexDirectionColumn, 500, 500, false); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child1_child1 = + YGNodeRef root_child1_child1 = createYGNode(config, YGFlexDirectionColumn, 500, 400, false); YGNodeSetIsReferenceBaseline(root_child1_child1, true); YGNodeInsertChild(root_child1, root_child1_child1, 1); diff --git a/tests/YGAlignContentTest.cpp b/tests/YGAlignContentTest.cpp deleted file mode 100644 index 1bb3dce5ba..0000000000 --- a/tests/YGAlignContentTest.cpp +++ /dev/null @@ -1,1878 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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(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)); - - 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(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)); - - 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 --git a/tests/YGAndroidNewsFeed.cpp b/tests/YGAndroidNewsFeed.cpp deleted file mode 100644 index bb4125df9d..0000000000 --- a/tests/YGAndroidNewsFeed.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index 7a81720e6c..28ecf3f65f 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -1,33 +1,32 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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, - double width, + YGNodeConstRef /*node*/, + float width, YGMeasureMode widthMode, - double height, + float height, YGMeasureMode heightMode) { return YGSize{ - .width = widthMode == YGMeasureModeExactly ? width : 50, - .height = heightMode == YGMeasureModeExactly ? height : 50, + widthMode == YGMeasureModeExactly ? width : 50, + heightMode == YGMeasureModeExactly ? height : 50, }; } TEST(YogaTest, aspect_ratio_cross_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -43,12 +42,12 @@ TEST(YogaTest, aspect_ratio_cross_defined) { } TEST(YogaTest, aspect_ratio_main_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -64,13 +63,13 @@ TEST(YogaTest, aspect_ratio_main_defined) { } TEST(YogaTest, aspect_ratio_both_dimensions_defined_row) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -87,12 +86,12 @@ TEST(YogaTest, aspect_ratio_both_dimensions_defined_row) { } TEST(YogaTest, aspect_ratio_both_dimensions_defined_column) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -109,11 +108,11 @@ TEST(YogaTest, aspect_ratio_both_dimensions_defined_column) { } TEST(YogaTest, aspect_ratio_align_stretch) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -128,12 +127,12 @@ TEST(YogaTest, aspect_ratio_align_stretch) { } TEST(YogaTest, aspect_ratio_flex_grow) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -150,12 +149,12 @@ TEST(YogaTest, aspect_ratio_flex_grow) { } TEST(YogaTest, aspect_ratio_flex_shrink) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 150); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -172,17 +171,17 @@ TEST(YogaTest, aspect_ratio_flex_shrink) { } TEST(YogaTest, aspect_ratio_flex_shrink_2) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + 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(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetHeightPercent(root_child1, 100); YGNodeStyleSetFlexShrink(root_child1, 1); YGNodeStyleSetAspectRatio(root_child1, 1); @@ -204,12 +203,12 @@ TEST(YogaTest, aspect_ratio_flex_shrink_2) { } TEST(YogaTest, aspect_ratio_basis) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexBasis(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -225,11 +224,11 @@ TEST(YogaTest, aspect_ratio_basis) { } TEST(YogaTest, aspect_ratio_absolute_layout_width_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 0); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); @@ -248,11 +247,11 @@ TEST(YogaTest, aspect_ratio_absolute_layout_width_defined) { } TEST(YogaTest, aspect_ratio_absolute_layout_height_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 0); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); @@ -271,12 +270,12 @@ TEST(YogaTest, aspect_ratio_absolute_layout_height_defined) { } TEST(YogaTest, aspect_ratio_with_max_cross_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetMaxWidth(root_child0, 40); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -293,12 +292,12 @@ TEST(YogaTest, aspect_ratio_with_max_cross_defined) { } TEST(YogaTest, aspect_ratio_with_max_main_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetMaxHeight(root_child0, 40); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -315,12 +314,12 @@ TEST(YogaTest, aspect_ratio_with_max_main_defined) { } TEST(YogaTest, aspect_ratio_with_min_cross_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 30); YGNodeStyleSetMinWidth(root_child0, 40); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -337,12 +336,12 @@ TEST(YogaTest, aspect_ratio_with_min_cross_defined) { } TEST(YogaTest, aspect_ratio_with_min_main_defined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetMinHeight(root_child0, 40); YGNodeStyleSetAspectRatio(root_child0, 1); @@ -359,12 +358,12 @@ TEST(YogaTest, aspect_ratio_with_min_main_defined) { } TEST(YogaTest, aspect_ratio_double_cross) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 2); YGNodeInsertChild(root, root_child0, 0); @@ -380,12 +379,12 @@ TEST(YogaTest, aspect_ratio_double_cross) { } TEST(YogaTest, aspect_ratio_half_cross) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 100); YGNodeStyleSetAspectRatio(root_child0, 0.5); YGNodeInsertChild(root, root_child0, 0); @@ -401,12 +400,12 @@ TEST(YogaTest, aspect_ratio_half_cross) { } TEST(YogaTest, aspect_ratio_double_main) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 0.5); YGNodeInsertChild(root, root_child0, 0); @@ -422,12 +421,12 @@ TEST(YogaTest, aspect_ratio_double_main) { } TEST(YogaTest, aspect_ratio_half_main) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetAspectRatio(root_child0, 2); YGNodeInsertChild(root, root_child0, 0); @@ -443,13 +442,13 @@ TEST(YogaTest, aspect_ratio_half_main) { } TEST(YogaTest, aspect_ratio_with_measure_func) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); - root_child0->setMeasureFunc(_measure); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -464,13 +463,13 @@ TEST(YogaTest, aspect_ratio_with_measure_func) { } TEST(YogaTest, aspect_ratio_width_height_flex_grow_row) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetFlexGrow(root_child0, 1); @@ -488,12 +487,12 @@ TEST(YogaTest, aspect_ratio_width_height_flex_grow_row) { } TEST(YogaTest, aspect_ratio_width_height_flex_grow_column) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetFlexGrow(root_child0, 1); @@ -511,19 +510,19 @@ TEST(YogaTest, aspect_ratio_width_height_flex_grow_column) { } TEST(YogaTest, aspect_ratio_height_as_flex_basis) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNew(); + 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(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetHeight(root_child1, 100); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetAspectRatio(root_child1, 1); @@ -545,18 +544,18 @@ TEST(YogaTest, aspect_ratio_height_as_flex_basis) { } TEST(YogaTest, aspect_ratio_width_as_flex_basis) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNew(); + 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(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetWidth(root_child1, 100); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetAspectRatio(root_child1, 1); @@ -578,13 +577,13 @@ TEST(YogaTest, aspect_ratio_width_as_flex_basis) { } TEST(YogaTest, aspect_ratio_overrides_flex_grow_row) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetAspectRatio(root_child0, 0.5); @@ -601,12 +600,12 @@ TEST(YogaTest, aspect_ratio_overrides_flex_grow_row) { } TEST(YogaTest, aspect_ratio_overrides_flex_grow_column) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetAspectRatio(root_child0, 2); @@ -623,11 +622,11 @@ TEST(YogaTest, aspect_ratio_overrides_flex_grow_column) { } TEST(YogaTest, aspect_ratio_left_right_absolute) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); @@ -646,11 +645,11 @@ TEST(YogaTest, aspect_ratio_left_right_absolute) { } TEST(YogaTest, aspect_ratio_top_bottom_absolute) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); @@ -669,12 +668,12 @@ TEST(YogaTest, aspect_ratio_top_bottom_absolute) { } TEST(YogaTest, aspect_ratio_width_overrides_align_stretch_row) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -690,11 +689,11 @@ TEST(YogaTest, aspect_ratio_width_overrides_align_stretch_row) { } TEST(YogaTest, aspect_ratio_height_overrides_align_stretch_column) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -710,11 +709,11 @@ TEST(YogaTest, aspect_ratio_height_overrides_align_stretch_column) { } TEST(YogaTest, aspect_ratio_allow_child_overflow_parent_size) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 4); YGNodeInsertChild(root, root_child0, 0); @@ -731,13 +730,13 @@ TEST(YogaTest, aspect_ratio_allow_child_overflow_parent_size) { } TEST(YogaTest, aspect_ratio_defined_main_with_margin) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignCenter); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); @@ -756,13 +755,13 @@ TEST(YogaTest, aspect_ratio_defined_main_with_margin) { } TEST(YogaTest, aspect_ratio_defined_cross_with_margin) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignCenter); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); @@ -781,13 +780,13 @@ TEST(YogaTest, aspect_ratio_defined_cross_with_margin) { } TEST(YogaTest, aspect_ratio_defined_cross_with_main_margin) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignCenter); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); @@ -806,17 +805,17 @@ TEST(YogaTest, aspect_ratio_defined_cross_with_main_margin) { } TEST(YogaTest, aspect_ratio_should_prefer_explicit_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); YGConfigSetUseWebDefaults(config, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumn); YGNodeStyleSetHeight(root_child0_child0, 100); YGNodeStyleSetAspectRatio(root_child0_child0, 2); @@ -837,17 +836,17 @@ TEST(YogaTest, aspect_ratio_should_prefer_explicit_height) { } TEST(YogaTest, aspect_ratio_should_prefer_explicit_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); YGConfigSetUseWebDefaults(config, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); YGNodeStyleSetWidth(root_child0_child0, 100); YGNodeStyleSetAspectRatio(root_child0_child0, 0.5); @@ -868,18 +867,18 @@ TEST(YogaTest, aspect_ratio_should_prefer_explicit_width) { } TEST(YogaTest, aspect_ratio_should_prefer_flexed_dimension) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); YGConfigSetUseWebDefaults(config, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAspectRatio(root_child0_child0, 4); YGNodeStyleSetFlexGrow(root_child0_child0, 1); YGNodeInsertChild(root_child0, root_child0_child0, 0); diff --git a/tests/YGBaselineFuncTest.cpp b/tests/YGBaselineFuncTest.cpp index adfc07da8e..c2d9b08772 100644 --- a/tests/YGBaselineFuncTest.cpp +++ b/tests/YGBaselineFuncTest.cpp @@ -1,41 +1,41 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 double _baseline(YGNodeRef node, const double width, const double height) { - double* baseline = (double*) node->getContext(); +static float +_baseline(YGNodeConstRef node, const float /*width*/, const float /*height*/) { + auto* baseline = (float*)YGNodeGetContext(node); return *baseline; } TEST(YogaTest, align_baseline_customer_func) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - double baselineValue = 10; - const YGNodeRef root_child1_child0 = YGNodeNew(); - root_child1_child0->setContext(&baselineValue); + float baselineValue = 10; + YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeSetContext(root_child1_child0, &baselineValue); YGNodeStyleSetWidth(root_child1_child0, 50); - root_child1_child0->setBaselineFunc(_baseline); + YGNodeSetBaselineFunc(root_child1_child0, _baseline); YGNodeStyleSetHeight(root_child1_child0, 20); YGNodeInsertChild(root_child1, root_child1_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); diff --git a/tests/YGCloneNodeTest.cpp b/tests/YGCloneNodeTest.cpp new file mode 100644 index 0000000000..d029fbe027 --- /dev/null +++ b/tests/YGCloneNodeTest.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 recursivelyAssertProperNodeOwnership(YGNodeRef node) { + for (size_t i = 0; i < YGNodeGetChildCount(node); ++i) { + const auto child = YGNodeGetChild(node, i); + ASSERT_EQ(node, YGNodeGetOwner(child)); + recursivelyAssertProperNodeOwnership(child); + } +} + +TEST(YogaTest, absolute_node_cloned_with_static_parent) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0, 1); + YGNodeStyleSetHeight(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeRef clonedRoot = YGNodeClone(root); + YGNodeStyleSetWidth(clonedRoot, 110); + YGNodeCalculateLayout(clonedRoot, YGUndefined, YGUndefined, YGDirectionLTR); + + recursivelyAssertProperNodeOwnership(clonedRoot); + + YGNodeFreeRecursive(root); + YGNodeFreeRecursive(clonedRoot); +} + +TEST(YogaTest, absolute_node_cloned_with_static_ancestors) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 40); + YGNodeStyleSetHeight(root_child0_child0, 40); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0_child0, 30); + YGNodeStyleSetHeight(root_child0_child0_child0, 30); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType( + root_child0_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0_child0_child0, 1); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 1); + YGNodeInsertChild( + root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + YGNodeRef clonedRoot = YGNodeClone(root); + YGNodeStyleSetWidth(clonedRoot, 110); + YGNodeCalculateLayout(clonedRoot, YGUndefined, YGUndefined, YGDirectionLTR); + + recursivelyAssertProperNodeOwnership(clonedRoot); + + YGNodeFreeRecursive(root); + YGNodeFreeRecursive(clonedRoot); +} diff --git a/tests/YGComputedMarginTest.cpp b/tests/YGComputedMarginTest.cpp index 1ab9a9b9b4..943b6f68be 100644 --- a/tests/YGComputedMarginTest.cpp +++ b/tests/YGComputedMarginTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -10,7 +10,7 @@ #include TEST(YogaTest, computed_layout_margin) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetMarginPercent(root, YGEdgeStart, 10); @@ -37,13 +37,13 @@ TEST(YogaTest, margin_side_overrides_horizontal_and_vertical) { YGEdgeLeft, YGEdgeRight}}; - for (double edgeValue = 0; edgeValue < 2; ++edgeValue) { + for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { YGEdge horizontalOrVertical = edge == YGEdgeTop || edge == YGEdgeBottom ? YGEdgeVertical : YGEdgeHorizontal; - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetMargin(root, horizontalOrVertical, 10); @@ -67,9 +67,9 @@ TEST(YogaTest, margin_side_overrides_all) { YGEdgeLeft, YGEdgeRight}}; - for (double edgeValue = 0; edgeValue < 2; ++edgeValue) { + for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetMargin(root, YGEdgeAll, 10); @@ -87,9 +87,9 @@ TEST(YogaTest, margin_side_overrides_all) { TEST(YogaTest, margin_horizontal_and_vertical_overrides_all) { const std::array directions = {{YGEdgeHorizontal, YGEdgeVertical}}; - for (double directionValue = 0; directionValue < 2; ++directionValue) { + for (float directionValue = 0; directionValue < 2; ++directionValue) { for (const auto& direction : directions) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetMargin(root, YGEdgeAll, 10); diff --git a/tests/YGComputedPaddingTest.cpp b/tests/YGComputedPaddingTest.cpp index ac72a98b0b..2ea1e1da1f 100644 --- a/tests/YGComputedPaddingTest.cpp +++ b/tests/YGComputedPaddingTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -10,7 +10,7 @@ #include TEST(YogaTest, computed_layout_padding) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetPaddingPercent(root, YGEdgeStart, 10); @@ -37,13 +37,13 @@ TEST(YogaTest, padding_side_overrides_horizontal_and_vertical) { YGEdgeLeft, YGEdgeRight}}; - for (double edgeValue = 0; edgeValue < 2; ++edgeValue) { + for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { YGEdge horizontalOrVertical = edge == YGEdgeTop || edge == YGEdgeBottom ? YGEdgeVertical : YGEdgeHorizontal; - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetPadding(root, horizontalOrVertical, 10); @@ -67,9 +67,9 @@ TEST(YogaTest, padding_side_overrides_all) { YGEdgeLeft, YGEdgeRight}}; - for (double edgeValue = 0; edgeValue < 2; ++edgeValue) { + for (float edgeValue = 0; edgeValue < 2; ++edgeValue) { for (const auto& edge : edges) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetPadding(root, YGEdgeAll, 10); @@ -87,9 +87,9 @@ TEST(YogaTest, padding_side_overrides_all) { TEST(YogaTest, padding_horizontal_and_vertical_overrides_all) { const std::array directions = {{YGEdgeHorizontal, YGEdgeVertical}}; - for (double directionValue = 0; directionValue < 2; ++directionValue) { + for (float directionValue = 0; directionValue < 2; ++directionValue) { for (const auto& direction : directions) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetPadding(root, YGEdgeAll, 10); diff --git a/tests/YGConfigTest.cpp b/tests/YGConfigTest.cpp index a6b02adcd5..d19457bfde 100644 --- a/tests/YGConfigTest.cpp +++ b/tests/YGConfigTest.cpp @@ -1,34 +1,46 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * 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 -#include -#include +#include +#include #include #include +using namespace facebook; + struct ConfigCloningTest : public ::testing::Test { - std::unique_ptr> config; + std::unique_ptr> config; void SetUp() override; void TearDown() override; - static YGNode clonedNode; - static YGNodeRef cloneNode(YGNodeRef, YGNodeRef, int) { return &clonedNode; } - static YGNodeRef doNotClone(YGNodeRef, YGNodeRef, int) { return nullptr; } + static yoga::Node clonedNode; + static YGNodeRef cloneNode( + YGNodeConstRef /*unused*/, + YGNodeConstRef /*unused*/, + size_t /*unused*/) { + return &clonedNode; + } + static YGNodeRef doNotClone( + YGNodeConstRef /*unused*/, + YGNodeConstRef /*unused*/, + size_t /*unused*/) { + return nullptr; + } }; TEST_F(ConfigCloningTest, uses_values_provided_by_cloning_callback) { config->setCloneNodeCallback(cloneNode); - YGNode node{}, owner{}; - auto clone = config->cloneNode(&node, &owner, 0, nullptr); + yoga::Node node{}; + yoga::Node owner{}; + auto clone = config->cloneNode(&node, &owner, 0); ASSERT_EQ(clone, &clonedNode); } @@ -38,28 +50,20 @@ TEST_F( falls_back_to_regular_cloning_if_callback_returns_null) { config->setCloneNodeCallback(doNotClone); - YGNode node{}, owner{}; - auto clone = config->cloneNode(&node, &owner, 0, nullptr); + yoga::Node node{}; + yoga::Node owner{}; + auto clone = config->cloneNode(&node, &owner, 0); ASSERT_NE(clone, nullptr); YGNodeFree(clone); } -TEST_F(ConfigCloningTest, can_clone_with_context) { - config->setCloneNodeCallback([](YGNodeRef, YGNodeRef, int, void* context) { - return (YGNodeRef) context; - }); - - YGNode node{}, owner{}, clone{}; - ASSERT_EQ(config->cloneNode(&node, &owner, 0, &clone), &clone); -} - void ConfigCloningTest::SetUp() { - config = {YGConfigNew(), YGConfigFree}; + config = {static_cast(YGConfigNew()), YGConfigFree}; } void ConfigCloningTest::TearDown() { config.reset(); } -YGNode ConfigCloningTest::clonedNode = {}; +yoga::Node ConfigCloningTest::clonedNode = {}; diff --git a/tests/YGDefaultValuesTest.cpp b/tests/YGDefaultValuesTest.cpp index 12a70dd859..09c74ce8c6 100644 --- a/tests/YGDefaultValuesTest.cpp +++ b/tests/YGDefaultValuesTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,10 +9,10 @@ #include TEST(YogaTest, assert_default_values) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); ASSERT_EQ(0u, YGNodeGetChildCount(root)); - ASSERT_EQ(NULL, YGNodeGetChild(root, 1)); + ASSERT_EQ(nullptr, YGNodeGetChild(root, 1)); ASSERT_EQ(YGDirectionInherit, YGNodeStyleGetDirection(root)); ASSERT_EQ(YGFlexDirectionColumn, YGNodeStyleGetFlexDirection(root)); @@ -20,7 +20,7 @@ TEST(YogaTest, assert_default_values) { ASSERT_EQ(YGAlignFlexStart, YGNodeStyleGetAlignContent(root)); ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignItems(root)); ASSERT_EQ(YGAlignAuto, YGNodeStyleGetAlignSelf(root)); - ASSERT_EQ(YGPositionTypeStatic, YGNodeStyleGetPositionType(root)); + ASSERT_EQ(YGPositionTypeRelative, YGNodeStyleGetPositionType(root)); ASSERT_EQ(YGWrapNoWrap, YGNodeStyleGetFlexWrap(root)); ASSERT_EQ(YGOverflowVisible, YGNodeStyleGetOverflow(root)); ASSERT_FLOAT_EQ(0, YGNodeStyleGetFlexGrow(root)); @@ -92,11 +92,11 @@ TEST(YogaTest, assert_default_values) { TEST(YogaTest, assert_webdefault_values) { YGConfig* config = YGConfigNew(); YGConfigSetUseWebDefaults(config, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); ASSERT_EQ(YGFlexDirectionRow, YGNodeStyleGetFlexDirection(root)); ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignContent(root)); - ASSERT_FLOAT_EQ(1.0, YGNodeStyleGetFlexShrink(root)); + ASSERT_FLOAT_EQ(1.0f, YGNodeStyleGetFlexShrink(root)); YGNodeFreeRecursive(root); YGConfigFree(config); @@ -105,12 +105,12 @@ TEST(YogaTest, assert_webdefault_values) { TEST(YogaTest, assert_webdefault_values_reset) { YGConfig* config = YGConfigNew(); YGConfigSetUseWebDefaults(config, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeReset(root); ASSERT_EQ(YGFlexDirectionRow, YGNodeStyleGetFlexDirection(root)); ASSERT_EQ(YGAlignStretch, YGNodeStyleGetAlignContent(root)); - ASSERT_FLOAT_EQ(1.0, YGNodeStyleGetFlexShrink(root)); + ASSERT_FLOAT_EQ(1.0f, YGNodeStyleGetFlexShrink(root)); YGNodeFreeRecursive(root); YGConfigFree(config); @@ -118,21 +118,21 @@ TEST(YogaTest, assert_webdefault_values_reset) { TEST(YogaTest, assert_legacy_stretch_behaviour) { YGConfig* config = YGConfigNew(); - YGConfigSetUseLegacyStretchBehaviour(config, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGConfigSetErrata(config, YGErrataStretchFlexBasis); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); @@ -162,3 +162,14 @@ TEST(YogaTest, assert_legacy_stretch_behaviour) { YGConfigFree(config); } + +TEST(YogaTest, assert_box_sizing_border_box) { + YGConfig* config = YGConfigNew(); + YGNodeRef root = YGNodeNewWithConfig(config); + + ASSERT_EQ(YGBoxSizingBorderBox, YGNodeStyleGetBoxSizing(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGDirtiedTest.cpp b/tests/YGDirtiedTest.cpp index 8f0d5ed497..77db88cbba 100644 --- a/tests/YGDirtiedTest.cpp +++ b/tests/YGDirtiedTest.cpp @@ -1,20 +1,23 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 +#include -static void _dirtied(YGNodeRef node) { - int* dirtiedCount = (int*) node->getContext(); +using namespace facebook; + +static void _dirtied(YGNodeConstRef node) { + int* dirtiedCount = (int*)YGNodeGetContext(node); (*dirtiedCount)++; } TEST(YogaTest, dirtied) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); @@ -22,32 +25,32 @@ TEST(YogaTest, dirtied) { YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); int dirtiedCount = 0; - root->setContext(&dirtiedCount); - root->setDirtiedFunc(_dirtied); + YGNodeSetContext(root, &dirtiedCount); + YGNodeSetDirtiedFunc(root, _dirtied); ASSERT_EQ(0, dirtiedCount); // `_dirtied` MUST be called in case of explicit dirtying. - root->setDirty(true); + static_cast(root)->setDirty(true); ASSERT_EQ(1, dirtiedCount); // `_dirtied` MUST be called ONCE. - root->setDirty(true); + static_cast(root)->setDirty(true); ASSERT_EQ(1, dirtiedCount); } TEST(YogaTest, dirtied_propagation) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); @@ -55,32 +58,32 @@ TEST(YogaTest, dirtied_propagation) { YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); int dirtiedCount = 0; - root->setContext(&dirtiedCount); - root->setDirtiedFunc(_dirtied); + YGNodeSetContext(root, &dirtiedCount); + YGNodeSetDirtiedFunc(root, _dirtied); ASSERT_EQ(0, dirtiedCount); // `_dirtied` MUST be called for the first time. - root_child0->markDirtyAndPropogate(); + static_cast(root_child0)->markDirtyAndPropagate(); ASSERT_EQ(1, dirtiedCount); // `_dirtied` must NOT be called for the second time. - root_child0->markDirtyAndPropogate(); + static_cast(root_child0)->markDirtyAndPropagate(); ASSERT_EQ(1, dirtiedCount); } TEST(YogaTest, dirtied_hierarchy) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); @@ -88,20 +91,20 @@ TEST(YogaTest, dirtied_hierarchy) { YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); int dirtiedCount = 0; - root_child0->setContext(&dirtiedCount); - root_child0->setDirtiedFunc(_dirtied); + YGNodeSetContext(root_child0, &dirtiedCount); + YGNodeSetDirtiedFunc(root_child0, _dirtied); ASSERT_EQ(0, dirtiedCount); // `_dirtied` must NOT be called for descendants. - root->markDirtyAndPropogate(); + static_cast(root)->markDirtyAndPropagate(); ASSERT_EQ(0, dirtiedCount); // `_dirtied` must NOT be called for the sibling node. - root_child1->markDirtyAndPropogate(); + static_cast(root_child1)->markDirtyAndPropagate(); ASSERT_EQ(0, dirtiedCount); // `_dirtied` MUST be called in case of explicit dirtying. - root_child0->markDirtyAndPropogate(); + static_cast(root_child0)->markDirtyAndPropagate(); ASSERT_EQ(1, dirtiedCount); } diff --git a/tests/YGDirtyMarkingTest.cpp b/tests/YGDirtyMarkingTest.cpp index f17cf02847..b7da4fcaae 100644 --- a/tests/YGDirtyMarkingTest.cpp +++ b/tests/YGDirtyMarkingTest.cpp @@ -1,25 +1,25 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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, dirty_propagation) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); @@ -28,31 +28,31 @@ TEST(YogaTest, dirty_propagation) { YGNodeStyleSetWidth(root_child0, 20); - EXPECT_TRUE(root_child0->isDirty()); - EXPECT_FALSE(root_child1->isDirty()); - EXPECT_TRUE(root->isDirty()); + EXPECT_TRUE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_TRUE(YGNodeIsDirty(root)); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); - EXPECT_FALSE(root_child0->isDirty()); - EXPECT_FALSE(root_child1->isDirty()); - EXPECT_FALSE(root->isDirty()); + EXPECT_FALSE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root)); YGNodeFreeRecursive(root); } TEST(YogaTest, dirty_propagation_only_if_prop_changed) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); @@ -61,25 +61,118 @@ TEST(YogaTest, dirty_propagation_only_if_prop_changed) { YGNodeStyleSetWidth(root_child0, 50); - EXPECT_FALSE(root_child0->isDirty()); - EXPECT_FALSE(root_child1->isDirty()); - EXPECT_FALSE(root->isDirty()); + EXPECT_FALSE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root)); YGNodeFreeRecursive(root); } +TEST(YogaTest, dirty_propagation_changing_layout_config) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0_child0, 25); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root, root_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + EXPECT_FALSE(YGNodeIsDirty(root)); + EXPECT_FALSE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root_child0_child0)); + + YGConfigRef newConfig = YGConfigNew(); + YGConfigSetErrata(newConfig, YGErrataStretchFlexBasis); + YGNodeSetConfig(root_child0, newConfig); + + EXPECT_TRUE(YGNodeIsDirty(root)); + EXPECT_TRUE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + EXPECT_FALSE(YGNodeIsDirty(root)); + EXPECT_FALSE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root_child0_child0)); + + YGConfigFree(newConfig); + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, dirty_propagation_changing_benign_config) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0_child0, 25); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root, root_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + EXPECT_FALSE(YGNodeIsDirty(root)); + EXPECT_FALSE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root_child0_child0)); + + YGConfigRef newConfig = YGConfigNew(); + YGConfigSetLogger( + newConfig, + [](YGConfigConstRef, YGNodeConstRef, YGLogLevel, const char*, va_list) { + return 0; + }); + YGNodeSetConfig(root_child0, newConfig); + + EXPECT_FALSE(YGNodeIsDirty(root)); + EXPECT_FALSE(YGNodeIsDirty(root_child0)); + EXPECT_FALSE(YGNodeIsDirty(root_child1)); + EXPECT_FALSE(YGNodeIsDirty(root_child0_child0)); + + YGConfigFree(newConfig); + YGNodeFreeRecursive(root); +} + TEST(YogaTest, dirty_mark_all_children_as_dirty_when_display_changes) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetHeight(root, 100); - const YGNodeRef child0 = YGNodeNew(); + YGNodeRef child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(child0, 1); - const YGNodeRef child1 = YGNodeNew(); + YGNodeRef child1 = YGNodeNew(); YGNodeStyleSetFlexGrow(child1, 1); - const YGNodeRef child1_child0 = YGNodeNew(); - const YGNodeRef child1_child0_child0 = YGNodeNew(); + YGNodeRef child1_child0 = YGNodeNew(); + YGNodeRef child1_child0_child0 = YGNodeNew(); YGNodeStyleSetWidth(child1_child0_child0, 8); YGNodeStyleSetHeight(child1_child0_child0, 16); @@ -117,43 +210,42 @@ TEST(YogaTest, dirty_mark_all_children_as_dirty_when_display_changes) { } TEST(YogaTest, dirty_node_only_if_children_are_actually_removed) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 50); YGNodeStyleSetHeight(root, 50); - const YGNodeRef child0 = YGNodeNew(); + YGNodeRef child0 = YGNodeNew(); YGNodeStyleSetWidth(child0, 50); YGNodeStyleSetHeight(child0, 25); YGNodeInsertChild(root, child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); - const YGNodeRef child1 = YGNodeNew(); + YGNodeRef child1 = YGNodeNew(); YGNodeRemoveChild(root, child1); - EXPECT_FALSE(root->isDirty()); + EXPECT_FALSE(YGNodeIsDirty(root)); YGNodeFree(child1); YGNodeRemoveChild(root, child0); - EXPECT_TRUE(root->isDirty()); + EXPECT_TRUE(YGNodeIsDirty(root)); YGNodeFree(child0); YGNodeFreeRecursive(root); } TEST(YogaTest, dirty_node_only_if_undefined_values_gets_set_to_undefined) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 50); YGNodeStyleSetHeight(root, 50); YGNodeStyleSetMinWidth(root, YGUndefined); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); - - EXPECT_FALSE(root->isDirty()); + EXPECT_FALSE(YGNodeIsDirty(root)); YGNodeStyleSetMinWidth(root, YGUndefined); - EXPECT_FALSE(root->isDirty()); + EXPECT_FALSE(YGNodeIsDirty(root)); YGNodeFreeRecursive(root); } diff --git a/tests/YGDisplayTest.cpp b/tests/YGDisplayTest.cpp deleted file mode 100644 index edc533589e..0000000000 --- a/tests/YGDisplayTest.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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); - 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); -} - -TEST(YogaTest, display_none_with_position_absolute) { - 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); - YGNodeStyleSetWidth(root_child0, 100); - YGNodeStyleSetHeight(root_child0, 100); - YGNodeStyleSetDisplay(root_child0, YGDisplayNone); - 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(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(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)); - - YGNodeFreeRecursive(root); - - YGConfigFree(config); -} diff --git a/tests/YGEdgeTest.cpp b/tests/YGEdgeTest.cpp index 47725926f4..15990eddaa 100644 --- a/tests/YGEdgeTest.cpp +++ b/tests/YGEdgeTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,12 +9,12 @@ #include TEST(YogaTest, start_overrides) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); @@ -33,12 +33,12 @@ TEST(YogaTest, start_overrides) { } TEST(YogaTest, end_overrides) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); @@ -57,12 +57,12 @@ TEST(YogaTest, end_overrides) { } TEST(YogaTest, horizontal_overridden) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeHorizontal, 10); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); @@ -76,12 +76,12 @@ TEST(YogaTest, horizontal_overridden) { } TEST(YogaTest, vertical_overridden) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeVertical, 10); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20); @@ -95,12 +95,12 @@ TEST(YogaTest, vertical_overridden) { } TEST(YogaTest, horizontal_overrides_all) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeHorizontal, 10); YGNodeStyleSetMargin(root_child0, YGEdgeAll, 20); @@ -116,12 +116,12 @@ TEST(YogaTest, horizontal_overrides_all) { } TEST(YogaTest, vertical_overrides_all) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeVertical, 10); YGNodeStyleSetMargin(root_child0, YGEdgeAll, 20); @@ -137,12 +137,12 @@ TEST(YogaTest, vertical_overrides_all) { } TEST(YogaTest, all_overridden) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); diff --git a/tests/YGFlexDirectionTest.cpp b/tests/YGFlexDirectionTest.cpp deleted file mode 100644 index 976ca82aec..0000000000 --- a/tests/YGFlexDirectionTest.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 --git a/tests/YGHadOverflowTest.cpp b/tests/YGHadOverflowTest.cpp index ca16a79def..bbeefe7ee4 100644 --- a/tests/YGHadOverflowTest.cpp +++ b/tests/YGHadOverflowTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -11,9 +11,8 @@ using namespace ::testing; class YogaTest_HadOverflowTests : public Test { -protected: - YogaTest_HadOverflowTests() { - config = YGConfigNew(); + protected: + YogaTest_HadOverflowTests() : config(YGConfigNew()) { root = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); @@ -21,7 +20,7 @@ class YogaTest_HadOverflowTests : public Test { YGNodeStyleSetFlexWrap(root, YGWrapNoWrap); } - ~YogaTest_HadOverflowTests() { + ~YogaTest_HadOverflowTests() override { YGNodeFreeRecursive(root); YGConfigFree(config); } @@ -33,13 +32,13 @@ class YogaTest_HadOverflowTests : public Test { TEST_F( YogaTest_HadOverflowTests, children_overflow_no_wrap_and_no_flex_children) { - const YGNodeRef child0 = YGNodeNewWithConfig(config); + YGNodeRef child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child0, 80); YGNodeStyleSetHeight(child0, 40); YGNodeStyleSetMargin(child0, YGEdgeTop, 10); YGNodeStyleSetMargin(child0, YGEdgeBottom, 15); YGNodeInsertChild(root, child0, 0); - const YGNodeRef child1 = YGNodeNewWithConfig(config); + YGNodeRef child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child1, 80); YGNodeStyleSetHeight(child1, 40); YGNodeStyleSetMargin(child1, YGEdgeBottom, 5); @@ -53,13 +52,13 @@ TEST_F( TEST_F( YogaTest_HadOverflowTests, spacing_overflow_no_wrap_and_no_flex_children) { - const YGNodeRef child0 = YGNodeNewWithConfig(config); + YGNodeRef child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child0, 80); YGNodeStyleSetHeight(child0, 40); YGNodeStyleSetMargin(child0, YGEdgeTop, 10); YGNodeStyleSetMargin(child0, YGEdgeBottom, 10); YGNodeInsertChild(root, child0, 0); - const YGNodeRef child1 = YGNodeNewWithConfig(config); + YGNodeRef child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child1, 80); YGNodeStyleSetHeight(child1, 40); YGNodeStyleSetMargin(child1, YGEdgeBottom, 5); @@ -71,13 +70,13 @@ TEST_F( } TEST_F(YogaTest_HadOverflowTests, no_overflow_no_wrap_and_flex_children) { - const YGNodeRef child0 = YGNodeNewWithConfig(config); + YGNodeRef child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child0, 80); YGNodeStyleSetHeight(child0, 40); YGNodeStyleSetMargin(child0, YGEdgeTop, 10); YGNodeStyleSetMargin(child0, YGEdgeBottom, 10); YGNodeInsertChild(root, child0, 0); - const YGNodeRef child1 = YGNodeNewWithConfig(config); + YGNodeRef child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child1, 80); YGNodeStyleSetHeight(child1, 40); YGNodeStyleSetMargin(child1, YGEdgeBottom, 5); @@ -90,13 +89,13 @@ TEST_F(YogaTest_HadOverflowTests, no_overflow_no_wrap_and_flex_children) { } TEST_F(YogaTest_HadOverflowTests, hadOverflow_gets_reset_if_not_logger_valid) { - const YGNodeRef child0 = YGNodeNewWithConfig(config); + YGNodeRef child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child0, 80); YGNodeStyleSetHeight(child0, 40); YGNodeStyleSetMargin(child0, YGEdgeTop, 10); YGNodeStyleSetMargin(child0, YGEdgeBottom, 10); YGNodeInsertChild(root, child0, 0); - const YGNodeRef child1 = YGNodeNewWithConfig(config); + YGNodeRef child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child1, 80); YGNodeStyleSetHeight(child1, 40); YGNodeStyleSetMargin(child1, YGEdgeBottom, 5); @@ -114,17 +113,17 @@ TEST_F(YogaTest_HadOverflowTests, hadOverflow_gets_reset_if_not_logger_valid) { } TEST_F(YogaTest_HadOverflowTests, spacing_overflow_in_nested_nodes) { - const YGNodeRef child0 = YGNodeNewWithConfig(config); + YGNodeRef child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child0, 80); YGNodeStyleSetHeight(child0, 40); YGNodeStyleSetMargin(child0, YGEdgeTop, 10); YGNodeStyleSetMargin(child0, YGEdgeBottom, 10); YGNodeInsertChild(root, child0, 0); - const YGNodeRef child1 = YGNodeNewWithConfig(config); + YGNodeRef child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child1, 80); YGNodeStyleSetHeight(child1, 40); YGNodeInsertChild(root, child1, 1); - const YGNodeRef child1_1 = YGNodeNewWithConfig(config); + YGNodeRef child1_1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(child1_1, 80); YGNodeStyleSetHeight(child1_1, 40); YGNodeStyleSetMargin(child1_1, YGEdgeBottom, 5); diff --git a/tests/YGInfiniteHeightTest.cpp b/tests/YGInfiniteHeightTest.cpp deleted file mode 100644 index 34300fd996..0000000000 --- a/tests/YGInfiniteHeightTest.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 --git a/tests/YGLayoutDiffingTest.cpp b/tests/YGLayoutDiffingTest.cpp deleted file mode 100644 index c8dc5fa7fc..0000000000 --- a/tests/YGLayoutDiffingTest.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 -#include - -using facebook::yoga::test::TestUtil; - -TEST(YogaTest, assert_layout_trees_are_same) { - TestUtil::startCountingNodes(); - - 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 = TestUtil::nodeCount(); - - YGNodeCalculateLayout(root1, YGUndefined, YGUndefined, YGDirectionLTR); - - ASSERT_EQ(YGConfigGetInstanceCount(), cal1_configInstanceCount); - ASSERT_EQ(TestUtil::nodeCount(), 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 = TestUtil::nodeCount(); - - YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); - - ASSERT_EQ(YGConfigGetInstanceCount(), cal2_configInstanceCount); - ASSERT_EQ(TestUtil::nodeCount(), 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 = TestUtil::nodeCount(); - - YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR); - - ASSERT_EQ(YGConfigGetInstanceCount(), cal3_configInstanceCount); - ASSERT_EQ(TestUtil::stopCountingNodes(), cal3_nodeInstanceCount); - - ASSERT_FALSE(root1->isLayoutTreeEqualToNode(*root2)); - - YGNodeFreeRecursive(root1); - YGNodeFreeRecursive(root2); - - YGConfigFree(config); -} diff --git a/tests/YGLayoutableChildrenTest.cpp b/tests/YGLayoutableChildrenTest.cpp new file mode 100644 index 0000000000..1a3a3f609d --- /dev/null +++ b/tests/YGLayoutableChildrenTest.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include + +TEST(YogaTest, layoutable_children_single_contents_node) { + YGNodeRef root = YGNodeNew(); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child2 = YGNodeNew(); + + YGNodeRef root_grandchild0 = YGNodeNew(); + YGNodeRef root_grandchild1 = YGNodeNew(); + + YGNodeInsertChild(root, root_child0, 0); + YGNodeInsertChild(root, root_child1, 1); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeInsertChild(root_child1, root_grandchild0, 0); + YGNodeInsertChild(root_child1, root_grandchild1, 1); + + YGNodeStyleSetDisplay(root_child1, YGDisplayContents); + + std::vector order = { + facebook::yoga::resolveRef(root_child0), + facebook::yoga::resolveRef(root_grandchild0), + facebook::yoga::resolveRef(root_grandchild1), + facebook::yoga::resolveRef(root_child2), + }; + auto correctOrderIt = order.begin(); + + for (auto node : facebook::yoga::resolveRef(root)->getLayoutChildren()) { + ASSERT_EQ(node, *correctOrderIt); + correctOrderIt++; + } + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, layoutable_children_multiple_contents_nodes) { + YGNodeRef root = YGNodeNew(); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child2 = YGNodeNew(); + + YGNodeRef root_grandchild0 = YGNodeNew(); + YGNodeRef root_grandchild1 = YGNodeNew(); + YGNodeRef root_grandchild2 = YGNodeNew(); + YGNodeRef root_grandchild3 = YGNodeNew(); + YGNodeRef root_grandchild4 = YGNodeNew(); + YGNodeRef root_grandchild5 = YGNodeNew(); + + YGNodeInsertChild(root, root_child0, 0); + YGNodeInsertChild(root, root_child1, 1); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeInsertChild(root_child0, root_grandchild0, 0); + YGNodeInsertChild(root_child0, root_grandchild1, 1); + YGNodeInsertChild(root_child1, root_grandchild2, 0); + YGNodeInsertChild(root_child1, root_grandchild3, 1); + YGNodeInsertChild(root_child2, root_grandchild4, 0); + YGNodeInsertChild(root_child2, root_grandchild5, 1); + + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeStyleSetDisplay(root_child1, YGDisplayContents); + YGNodeStyleSetDisplay(root_child2, YGDisplayContents); + + std::vector order = { + facebook::yoga::resolveRef(root_grandchild0), + facebook::yoga::resolveRef(root_grandchild1), + facebook::yoga::resolveRef(root_grandchild2), + facebook::yoga::resolveRef(root_grandchild3), + facebook::yoga::resolveRef(root_grandchild4), + facebook::yoga::resolveRef(root_grandchild5), + }; + auto correctOrderIt = order.begin(); + + for (auto node : facebook::yoga::resolveRef(root)->getLayoutChildren()) { + ASSERT_EQ(node, *correctOrderIt); + correctOrderIt++; + } + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, layoutable_children_nested_contents_nodes) { + YGNodeRef root = YGNodeNew(); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child2 = YGNodeNew(); + + YGNodeRef root_grandchild0 = YGNodeNew(); + YGNodeRef root_grandchild1 = YGNodeNew(); + + YGNodeRef root_great_grandchild0 = YGNodeNew(); + YGNodeRef root_great_grandchild1 = YGNodeNew(); + + YGNodeInsertChild(root, root_child0, 0); + YGNodeInsertChild(root, root_child1, 1); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeInsertChild(root_child1, root_grandchild0, 0); + YGNodeInsertChild(root_child1, root_grandchild1, 1); + + YGNodeInsertChild(root_grandchild1, root_great_grandchild0, 0); + YGNodeInsertChild(root_grandchild1, root_great_grandchild1, 1); + + YGNodeStyleSetDisplay(root_child1, YGDisplayContents); + YGNodeStyleSetDisplay(root_grandchild1, YGDisplayContents); + + std::vector order = { + facebook::yoga::resolveRef(root_child0), + facebook::yoga::resolveRef(root_grandchild0), + facebook::yoga::resolveRef(root_great_grandchild0), + facebook::yoga::resolveRef(root_great_grandchild1), + facebook::yoga::resolveRef(root_child2), + }; + auto correctOrderIt = order.begin(); + + for (auto node : facebook::yoga::resolveRef(root)->getLayoutChildren()) { + ASSERT_EQ(node, *correctOrderIt); + correctOrderIt++; + } + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, layoutable_children_contents_leaf_node) { + YGNodeRef root = YGNodeNew(); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child2 = YGNodeNew(); + + YGNodeInsertChild(root, root_child0, 0); + YGNodeInsertChild(root, root_child1, 1); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeStyleSetDisplay(root_child1, YGDisplayContents); + + std::vector order = { + facebook::yoga::resolveRef(root_child0), + facebook::yoga::resolveRef(root_child2), + }; + auto correctOrderIt = order.begin(); + + for (auto node : facebook::yoga::resolveRef(root)->getLayoutChildren()) { + ASSERT_EQ(node, *correctOrderIt); + correctOrderIt++; + } + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, layoutable_children_contents_root_node) { + YGNodeRef root = YGNodeNew(); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child1 = YGNodeNew(); + YGNodeRef root_child2 = YGNodeNew(); + + YGNodeInsertChild(root, root_child0, 0); + YGNodeInsertChild(root, root_child1, 1); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeStyleSetDisplay(root, YGDisplayContents); + + std::vector order = { + facebook::yoga::resolveRef(root_child0), + facebook::yoga::resolveRef(root_child1), + facebook::yoga::resolveRef(root_child2), + }; + auto correctOrderIt = order.begin(); + + for (auto node : facebook::yoga::resolveRef(root)->getLayoutChildren()) { + ASSERT_EQ(node, *correctOrderIt); + correctOrderIt++; + } + + YGNodeFreeRecursive(root); +} diff --git a/tests/YGLoggerTest.cpp b/tests/YGLoggerTest.cpp deleted file mode 100644 index f9d8002cd5..0000000000 --- a/tests/YGLoggerTest.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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); -} -} // namespace - -TEST(YogaTest, config_print_tree_enabled) { - writeBuffer[0] = '\0'; - const YGConfigRef config = YGConfigNew(); - YGConfigSetPrintTreeFlag(config, true); - 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); - YGConfigSetLogger(config, NULL); - YGNodeFreeRecursive(root); - - const char* expected = - "
\n " - "
\n
\n
"; - ASSERT_STREQ(expected, writeBuffer); -} - -TEST(YogaTest, config_print_tree_disabled) { - writeBuffer[0] = '\0'; - const YGConfigRef config = YGConfigNew(); - YGConfigSetPrintTreeFlag(config, false); - 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); - YGConfigSetLogger(config, NULL); - YGNodeFreeRecursive(root); - - const char* expected = ""; - ASSERT_STREQ(expected, writeBuffer); -} - -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 --git a/tests/YGMeasureCacheTest.cpp b/tests/YGMeasureCacheTest.cpp index 233bfdb54c..850c17e6d7 100644 --- a/tests/YGMeasureCacheTest.cpp +++ b/tests/YGMeasureCacheTest.cpp @@ -1,43 +1,42 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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, - double width, + YGNodeConstRef node, + float width, YGMeasureMode widthMode, - double height, + float height, YGMeasureMode heightMode) { - int* measureCount = (int*) node->getContext(); + int* measureCount = (int*)YGNodeGetContext(node); (*measureCount)++; return YGSize{ - .width = widthMode == YGMeasureModeUndefined ? 10 : width, - .height = heightMode == YGMeasureModeUndefined ? 10 : height, + widthMode == YGMeasureModeUndefined ? 10 : width, + heightMode == YGMeasureModeUndefined ? 10 : height, }; } static YGSize _measureMin( - YGNodeRef node, - double width, + YGNodeConstRef node, + float width, YGMeasureMode widthMode, - double height, + float height, YGMeasureMode heightMode) { - int* measureCount = (int*) node->getContext(); + int* measureCount = (int*)YGNodeGetContext(node); *measureCount = *measureCount + 1; return YGSize{ - .width = widthMode == YGMeasureModeUndefined || + widthMode == YGMeasureModeUndefined || (widthMode == YGMeasureModeAtMost && width > 10) ? 10 : width, - .height = heightMode == YGMeasureModeUndefined || + heightMode == YGMeasureModeUndefined || (heightMode == YGMeasureModeAtMost && height > 10) ? 10 : height, @@ -45,33 +44,30 @@ static YGSize _measureMin( } static YGSize _measure_84_49( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - int* measureCount = (int*) node->getContext(); - if (measureCount) { + YGNodeConstRef node, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + int* measureCount = (int*)YGNodeGetContext(node); + if (measureCount != nullptr) { (*measureCount)++; } - return YGSize{ - .width = 84, - .height = 49, - }; + return YGSize{84.f, 49.f}; } TEST(YogaTest, measure_once_single_flexible_child) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); int measureCount = 0; - root_child0->setContext(&measureCount); - root_child0->setMeasureFunc(_measureMax); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measureMax); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -83,12 +79,12 @@ TEST(YogaTest, measure_once_single_flexible_child) { } TEST(YogaTest, remeasure_with_same_exact_width_larger_than_needed_height) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); int measureCount = 0; - root_child0->setContext(&measureCount); - root_child0->setMeasureFunc(_measureMin); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measureMin); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); @@ -100,13 +96,13 @@ TEST(YogaTest, remeasure_with_same_exact_width_larger_than_needed_height) { } TEST(YogaTest, remeasure_with_same_atmost_width_larger_than_needed_height) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); int measureCount = 0; - root_child0->setContext(&measureCount); - root_child0->setMeasureFunc(_measureMin); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measureMin); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); @@ -118,13 +114,13 @@ TEST(YogaTest, remeasure_with_same_atmost_width_larger_than_needed_height) { } TEST(YogaTest, remeasure_with_computed_width_larger_than_needed_height) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); int measureCount = 0; - root_child0->setContext(&measureCount); - root_child0->setMeasureFunc(_measureMin); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measureMin); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, 100, 100, YGDirectionLTR); @@ -137,13 +133,13 @@ TEST(YogaTest, remeasure_with_computed_width_larger_than_needed_height) { } TEST(YogaTest, remeasure_with_atmost_computed_width_undefined_height) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); int measureCount = 0; - root_child0->setContext(&measureCount); - root_child0->setMeasureFunc(_measureMin); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measureMin); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, 100, YGUndefined, YGDirectionLTR); @@ -159,19 +155,19 @@ TEST( remeasure_with_already_measured_value_smaller_but_still_float_equal) { int measureCount = 0; - const YGNodeRef root = YGNodeNew(); - YGNodeStyleSetWidth(root, 288); - YGNodeStyleSetHeight(root, 288); + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 288.f); + YGNodeStyleSetHeight(root, 288.f); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); - const YGNodeRef root_child0 = YGNodeNew(); - YGNodeStyleSetPadding(root_child0, YGEdgeAll, 2.88); + 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); + YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeSetContext(root_child0_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0_child0, _measure_84_49); YGNodeInsertChild(root_child0, root_child0_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); diff --git a/tests/YGMeasureModeTest.cpp b/tests/YGMeasureModeTest.cpp index 2f73c7543f..f42ee060a4 100644 --- a/tests/YGMeasureModeTest.cpp +++ b/tests/YGMeasureModeTest.cpp @@ -1,18 +1,17 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 { - double width; + float width; YGMeasureMode widthMode; - double height; + float height; YGMeasureMode heightMode; }; @@ -22,13 +21,12 @@ struct _MeasureConstraintList { }; static YGSize _measure( - YGNodeRef node, - double width, + YGNodeConstRef node, + float width, YGMeasureMode widthMode, - double height, + float height, YGMeasureMode heightMode) { - struct _MeasureConstraintList* constraintList = - (struct _MeasureConstraintList*) node->getContext(); + auto* constraintList = (struct _MeasureConstraintList*)YGNodeGetContext(node); struct _MeasureConstraint* constraints = constraintList->constraints; uint32_t currentIndex = constraintList->length; (&constraints[currentIndex])->width = width; @@ -38,27 +36,25 @@ static YGSize _measure( constraintList->length = currentIndex + 1; return YGSize{ - .width = widthMode == YGMeasureModeUndefined ? 10 : width, - .height = heightMode == YGMeasureModeUndefined ? 10 : width, + widthMode == YGMeasureModeUndefined ? 10 : width, + heightMode == YGMeasureModeUndefined ? 10 : width, }; } TEST(YogaTest, exactly_measure_stretched_child_column) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); - // root_child0->setMeasureFunc(_measure); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -73,21 +69,20 @@ TEST(YogaTest, exactly_measure_stretched_child_column) { } TEST(YogaTest, exactly_measure_stretched_child_row) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -102,19 +97,19 @@ TEST(YogaTest, exactly_measure_stretched_child_row) { } TEST(YogaTest, at_most_main_axis_column) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); - root_child0->setContext(&constraintList); - root_child0->setMeasureFunc(_measure); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -129,20 +124,20 @@ TEST(YogaTest, at_most_main_axis_column) { } TEST(YogaTest, at_most_cross_axis_column) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -157,20 +152,20 @@ TEST(YogaTest, at_most_cross_axis_column) { } TEST(YogaTest, at_most_main_axis_row) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -185,21 +180,21 @@ TEST(YogaTest, at_most_main_axis_row) { } TEST(YogaTest, at_most_cross_axis_row) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -214,19 +209,19 @@ TEST(YogaTest, at_most_cross_axis_row) { } TEST(YogaTest, flex_child) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); - root_child0->setContext(&constraintList); - root_child0->setMeasureFunc(_measure); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -244,20 +239,20 @@ TEST(YogaTest, flex_child) { } TEST(YogaTest, flex_child_with_flex_basis) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 0); - root_child0->setContext(&constraintList); - root_child0->setMeasureFunc(_measure); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -272,21 +267,21 @@ TEST(YogaTest, flex_child_with_flex_basis) { } TEST(YogaTest, overflow_scroll_column) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -304,22 +299,22 @@ TEST(YogaTest, overflow_scroll_column) { } TEST(YogaTest, overflow_scroll_row) { - struct _MeasureConstraintList constraintList = _MeasureConstraintList{ - .length = 0, - .constraints = (struct _MeasureConstraint*) malloc( + auto constraintList = _MeasureConstraintList{ + 0, + (struct _MeasureConstraint*)malloc( 10 * sizeof(struct _MeasureConstraint)), }; - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &constraintList); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index 5a9dc56144..c88e882624 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -1,72 +1,62 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - int* measureCount = (int*) node->getContext(); - if (measureCount) { + YGNodeConstRef node, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + int* measureCount = (int*)YGNodeGetContext(node); + if (measureCount != nullptr) { (*measureCount)++; } - return YGSize{ - .width = 10, - .height = 10, - }; + return YGSize{10, 10}; } static YGSize _simulate_wrapping_text( - YGNodeRef node, - double width, + YGNodeConstRef /*node*/, + float width, YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { + float /*height*/, + YGMeasureMode /*heightMode*/) { if (widthMode == YGMeasureModeUndefined || width >= 68) { - return YGSize{.width = 68, .height = 16}; + return YGSize{68, 16}; } - return YGSize{ - .width = 50, - .height = 32, - }; + return YGSize{50, 32}; } static YGSize _measure_assert_negative( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { + YGNodeConstRef /*node*/, + float width, + YGMeasureMode /*widthMode*/, + float height, + YGMeasureMode /*heightMode*/) { EXPECT_GE(width, 0); EXPECT_GE(height, 0); - return YGSize{ - .width = 0, - .height = 0, - }; + return YGSize{0, 0}; } TEST(YogaTest, dont_measure_single_grow_shrink_child) { - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); @@ -79,17 +69,17 @@ TEST(YogaTest, dont_measure_single_grow_shrink_child) { } TEST(YogaTest, measure_absolute_child_with_no_constraints) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeInsertChild(root, root_child0, 0); int measureCount = 0; - const YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeRef root_child0_child0 = YGNodeNew(); YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); - root_child0_child0->setContext(&measureCount); - root_child0_child0->setMeasureFunc(_measure); + YGNodeSetContext(root_child0_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0_child0, _measure); YGNodeInsertChild(root_child0, root_child0_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -100,16 +90,16 @@ TEST(YogaTest, measure_absolute_child_with_no_constraints) { } TEST(YogaTest, dont_measure_when_min_equals_max) { - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetMinWidth(root_child0, 10); YGNodeStyleSetMaxWidth(root_child0, 10); YGNodeStyleSetMinHeight(root_child0, 10); @@ -128,16 +118,16 @@ TEST(YogaTest, dont_measure_when_min_equals_max) { } TEST(YogaTest, dont_measure_when_min_equals_max_percentages) { - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetMinWidthPercent(root_child0, 10); YGNodeStyleSetMaxWidthPercent(root_child0, 10); YGNodeStyleSetMinHeightPercent(root_child0, 10); @@ -156,12 +146,12 @@ TEST(YogaTest, dont_measure_when_min_equals_max_percentages) { } TEST(YogaTest, measure_nodes_with_margin_auto_and_stretch) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNew(); - root_child0->setMeasureFunc(_measure); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); YGNodeInsertChild(root, root_child0, 0); @@ -176,16 +166,16 @@ TEST(YogaTest, measure_nodes_with_margin_auto_and_stretch) { } TEST(YogaTest, dont_measure_when_min_equals_max_mixed_width_percent) { - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetMinWidthPercent(root_child0, 10); YGNodeStyleSetMaxWidthPercent(root_child0, 10); YGNodeStyleSetMinHeight(root_child0, 10); @@ -204,16 +194,16 @@ TEST(YogaTest, dont_measure_when_min_equals_max_mixed_width_percent) { } TEST(YogaTest, dont_measure_when_min_equals_max_mixed_height_percent) { - const YGNodeRef root = YGNodeNew(); + 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); + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeStyleSetMinWidth(root_child0, 10); YGNodeStyleSetMaxWidth(root_child0, 10); YGNodeStyleSetMinHeightPercent(root_child0, 10); @@ -232,12 +222,12 @@ TEST(YogaTest, dont_measure_when_min_equals_max_mixed_height_percent) { } TEST(YogaTest, measure_enough_size_should_be_in_single_line) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); - root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeInsertChild(root, root_child0, 0); @@ -250,13 +240,13 @@ TEST(YogaTest, measure_enough_size_should_be_in_single_line) { } TEST(YogaTest, measure_not_enough_size_should_wrap) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetWidth(root, 55); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); - root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -268,18 +258,18 @@ TEST(YogaTest, measure_not_enough_size_should_wrap) { } TEST(YogaTest, measure_zero_space_should_grow) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetHeight(root, 200); YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn); YGNodeStyleSetFlexGrow(root, 0); int measureCount = 0; - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn); YGNodeStyleSetPadding(root_child0, YGEdgeAll, 100); - root_child0->setContext(&measureCount); - root_child0->setMeasureFunc(_measure); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure); YGNodeInsertChild(root, root_child0, 0); @@ -292,9 +282,9 @@ TEST(YogaTest, measure_zero_space_should_grow) { } TEST(YogaTest, measure_flex_direction_row_and_padding) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetPadding(root, YGEdgeLeft, 25); YGNodeStyleSetPadding(root, YGEdgeTop, 25); @@ -303,12 +293,11 @@ TEST(YogaTest, measure_flex_direction_row_and_padding) { YGNodeStyleSetWidth(root, 50); YGNodeStyleSetHeight(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - root_child0->setMeasureFunc(_simulate_wrapping_text); - // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -335,20 +324,20 @@ TEST(YogaTest, measure_flex_direction_row_and_padding) { } TEST(YogaTest, measure_flex_direction_column_and_padding) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -375,20 +364,20 @@ TEST(YogaTest, measure_flex_direction_column_and_padding) { } TEST(YogaTest, measure_flex_direction_row_no_padding) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetMargin(root, YGEdgeTop, 20); YGNodeStyleSetWidth(root, 50); YGNodeStyleSetHeight(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); - root_child0->setMeasureFunc(_simulate_wrapping_text); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -415,20 +404,20 @@ TEST(YogaTest, measure_flex_direction_row_no_padding) { } TEST(YogaTest, measure_flex_direction_row_no_padding_align_items_flexstart) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -455,21 +444,21 @@ TEST(YogaTest, measure_flex_direction_row_no_padding_align_items_flexstart) { } TEST(YogaTest, measure_with_fixed_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -496,20 +485,20 @@ TEST(YogaTest, measure_with_fixed_size) { } TEST(YogaTest, measure_with_flex_shrink) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -536,19 +525,19 @@ TEST(YogaTest, measure_with_flex_shrink) { } TEST(YogaTest, measure_no_padding) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 5); YGNodeStyleSetHeight(root_child1, 5); YGNodeInsertChild(root, root_child1, 1); @@ -576,43 +565,52 @@ TEST(YogaTest, measure_no_padding) { #if GTEST_HAS_DEATH_TEST TEST(YogaDeathTest, cannot_add_child_to_node_with_measure_func) { - const YGNodeRef root = YGNodeNew(); - root->setMeasureFunc(_measure); + YGNodeRef root = YGNodeNew(); + YGNodeSetMeasureFunc(root, _measure); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); +#if defined(__cpp_exceptions) ASSERT_THROW(YGNodeInsertChild(root, root_child0, 0), std::logic_error); +#else // !defined(__cpp_exceptions) + ASSERT_DEATH(YGNodeInsertChild(root, root_child0, 0), "Cannot add child.*"); +#endif // defined(__cpp_exceptions) 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(); + YGNodeRef root = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeInsertChild(root, root_child0, 0); - ASSERT_THROW(root->setMeasureFunc(_measure), std::logic_error); +#if defined(__cpp_exceptions) + ASSERT_THROW(YGNodeSetMeasureFunc(root, _measure), std::logic_error); +#else // !defined(__cpp_exceptions) + ASSERT_DEATH( + YGNodeSetMeasureFunc(root, _measure), "Cannot set measure function.*"); +#endif // defined(__cpp_exceptions) YGNodeFreeRecursive(root); } #endif TEST(YogaTest, can_nullify_measure_func_on_any_node) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeInsertChild(root, YGNodeNew(), 0); - root->setMeasureFunc(nullptr); - ASSERT_TRUE(!root->hasMeasureFunc()); + YGNodeSetMeasureFunc(root, nullptr); + ASSERT_TRUE(!YGNodeHasMeasureFunc(root)); YGNodeFreeRecursive(root); } TEST(YogaTest, cant_call_negative_measure) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _measure_assert_negative); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20); YGNodeInsertChild(root, root_child0, 0); @@ -623,15 +621,15 @@ TEST(YogaTest, cant_call_negative_measure) { } TEST(YogaTest, cant_call_negative_measure_horizontal) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _measure_assert_negative); YGNodeStyleSetMargin(root_child0, YGEdgeStart, 20); YGNodeInsertChild(root, root_child0, 0); @@ -642,46 +640,38 @@ TEST(YogaTest, cant_call_negative_measure_horizontal) { } static YGSize _measure_90_10( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - - return YGSize{ - .width = 90, - .height = 10, - }; + YGNodeConstRef /*node*/, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + return YGSize{90, 10}; } static YGSize _measure_100_100( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - - return YGSize{ - .width = 100, - .height = 100, - }; + YGNodeConstRef /*node*/, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + return YGSize{100, 100}; } TEST(YogaTest, percent_with_text_node) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); - root_child1->setMeasureFunc(_measure_90_10); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child1, _measure_90_10); YGNodeStyleSetMaxWidthPercent(root_child1, 50); YGNodeStyleSetPaddingPercent(root_child1, YGEdgeTop, 50); YGNodeInsertChild(root, root_child1, 1); @@ -709,39 +699,39 @@ TEST(YogaTest, percent_with_text_node) { } TEST(YogaTest, percent_margin_with_measure_func) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 100); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 0); - root_child0->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child0, _measure_100_100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 100); YGNodeStyleSetHeight(root_child1, 100); YGNodeStyleSetMargin(root_child1, YGEdgeTop, 100); - root_child1->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child1, _measure_100_100); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 100); YGNodeStyleSetHeight(root_child2, 100); YGNodeStyleSetMarginPercent(root_child2, YGEdgeTop, 10); - root_child2->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child2, _measure_100_100); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 100); YGNodeStyleSetHeight(root_child3, 100); YGNodeStyleSetMarginPercent(root_child3, YGEdgeTop, 20); - root_child3->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child3, _measure_100_100); YGNodeInsertChild(root, root_child3, 3); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -777,37 +767,37 @@ TEST(YogaTest, percent_margin_with_measure_func) { } TEST(YogaTest, percent_padding_with_measure_func) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetAlignContent(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 100); YGNodeStyleSetPadding(root_child0, YGEdgeTop, 0); - root_child0->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child0, _measure_100_100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 100); YGNodeStyleSetHeight(root_child1, 100); YGNodeStyleSetPadding(root_child1, YGEdgeTop, 100); - root_child1->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child1, _measure_100_100); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetPaddingPercent(root_child2, YGEdgeTop, 10); - root_child2->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child2, _measure_100_100); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetPaddingPercent(root_child3, YGEdgeTop, 20); - root_child3->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child3, _measure_100_100); YGNodeInsertChild(root, root_child3, 3); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -843,39 +833,39 @@ TEST(YogaTest, percent_padding_with_measure_func) { } TEST(YogaTest, percent_padding_and_percent_margin_with_measure_func) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetAlignContent(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 100); YGNodeStyleSetPadding(root_child0, YGEdgeTop, 0); - root_child0->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child0, _measure_100_100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 100); YGNodeStyleSetHeight(root_child1, 100); YGNodeStyleSetPadding(root_child1, YGEdgeTop, 100); - root_child1->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child1, _measure_100_100); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetPaddingPercent(root_child2, YGEdgeTop, 10); YGNodeStyleSetMarginPercent(root_child2, YGEdgeTop, 10); - root_child2->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child2, _measure_100_100); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetPaddingPercent(root_child3, YGEdgeTop, 20); YGNodeStyleSetMarginPercent(root_child3, YGEdgeTop, 20); - root_child3->setMeasureFunc(_measure_100_100); + YGNodeSetMeasureFunc(root_child3, _measure_100_100); YGNodeInsertChild(root, root_child3, 3); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -909,3 +899,81 @@ TEST(YogaTest, percent_padding_and_percent_margin_with_measure_func) { YGConfigFree(config); } + +static YGSize _measure_half_width_height( + YGNodeConstRef node, + float width, + YGMeasureMode /*widthMode*/, + float height, + YGMeasureMode /*heightMode*/) { + int* measureCount = (int*)YGNodeGetContext(node); + if (measureCount != nullptr) { + (*measureCount)++; + } + + return YGSize{0.5f * width, 0.5f * height}; +} + +TEST(YogaTest, measure_content_box) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + YGNodeStyleSetPadding(root, YGEdgeAll, 5); + YGNodeStyleSetBorder(root, YGEdgeAll, 10); + + int measureCount = 0; + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure_half_width_height); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(230, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(15, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, measure_border_box) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetBoxSizing(root, YGBoxSizingBorderBox); + YGNodeStyleSetPadding(root, YGEdgeAll, 5); + YGNodeStyleSetBorder(root, YGEdgeAll, 10); + + int measureCount = 0; + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeSetContext(root_child0, &measureCount); + YGNodeSetMeasureFunc(root_child0, _measure_half_width_height); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(1, measureCount); + + ASSERT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_EQ(15, YGNodeLayoutGetLeft(root_child0)); + ASSERT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_EQ(70, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(85, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); +} diff --git a/tests/YGNodeCallbackTest.cpp b/tests/YGNodeCallbackTest.cpp index 0f67bed939..f40d7e0fa4 100644 --- a/tests/YGNodeCallbackTest.cpp +++ b/tests/YGNodeCallbackTest.cpp @@ -1,89 +1,51 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 #include +using namespace facebook::yoga; + inline bool operator==(const YGSize& lhs, const YGSize& rhs) { return lhs.width == rhs.width && lhs.height == rhs.height; } -void PrintTo(const YGSize&, std::ostream*); - -TEST(YGNode, hasMeasureFunc_initial) { - auto n = YGNode{}; +TEST(Node, hasMeasureFunc_initial) { + auto n = Node{}; ASSERT_FALSE(n.hasMeasureFunc()); } -TEST(YGNode, hasMeasureFunc_with_measure_fn) { - auto n = YGNode{}; - n.setMeasureFunc([](YGNode*, double, YGMeasureMode, double, YGMeasureMode) { - return YGSize{}; - }); - ASSERT_TRUE(n.hasMeasureFunc()); -} - -TEST(YGNode, measure_with_measure_fn) { - auto n = YGNode{}; - +TEST(Node, hasMeasureFunc_with_measure_fn) { + auto n = Node{}; n.setMeasureFunc( - [](YGNode*, double w, YGMeasureMode wm, double h, YGMeasureMode hm) { - return YGSize{w * wm, h / hm}; + [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode) { + return YGSize{}; }); - - ASSERT_EQ( - n.measure(23, YGMeasureModeExactly, 24, YGMeasureModeAtMost, nullptr), - (YGSize{23, 12})); + ASSERT_TRUE(n.hasMeasureFunc()); } -TEST(YGNode, measure_with_context_measure_fn) { - auto n = YGNode{}; - n.setMeasureFunc( - [](YGNode*, double, YGMeasureMode, double, YGMeasureMode, void* ctx) { - return *(YGSize*) ctx; - }); +TEST(Node, measure_with_measure_fn) { + auto n = Node{}; - auto result = YGSize{123.4, -56.7}; - ASSERT_EQ( - n.measure(0, YGMeasureModeUndefined, 0, YGMeasureModeUndefined, &result), - result); -} - -TEST(YGNode, switching_measure_fn_types) { - auto n = YGNode{}; - n.setMeasureFunc( - [](YGNode*, double, YGMeasureMode, double, YGMeasureMode, void*) { - return YGSize{}; - }); n.setMeasureFunc( - [](YGNode*, double w, YGMeasureMode wm, double h, YGMeasureMode hm) { - return YGSize{w * wm, h / hm}; + [](YGNodeConstRef, float w, YGMeasureMode wm, float h, YGMeasureMode hm) { + return YGSize{w * static_cast(wm), h / static_cast(hm)}; }); ASSERT_EQ( - n.measure(23, YGMeasureModeExactly, 24, YGMeasureModeAtMost, nullptr), + n.measure(23, MeasureMode::Exactly, 24, MeasureMode::AtMost), (YGSize{23, 12})); } -TEST(YGNode, hasMeasureFunc_after_unset) { - auto n = YGNode{}; - n.setMeasureFunc([](YGNode*, double, YGMeasureMode, double, YGMeasureMode) { - return YGSize{}; - }); - - n.setMeasureFunc(nullptr); - ASSERT_FALSE(n.hasMeasureFunc()); -} - -TEST(YGNode, hasMeasureFunc_after_unset_context) { - auto n = YGNode{}; +TEST(Node, hasMeasureFunc_after_unset) { + auto n = Node{}; n.setMeasureFunc( - [](YGNode*, double, YGMeasureMode, double, YGMeasureMode, void*) { + [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode) { return YGSize{}; }); @@ -91,57 +53,28 @@ TEST(YGNode, hasMeasureFunc_after_unset_context) { ASSERT_FALSE(n.hasMeasureFunc()); } -TEST(YGNode, hasBaselineFunc_initial) { - auto n = YGNode{}; +TEST(Node, hasBaselineFunc_initial) { + auto n = Node{}; ASSERT_FALSE(n.hasBaselineFunc()); } -TEST(YGNode, hasBaselineFunc_with_baseline_fn) { - auto n = YGNode{}; - n.setBaselineFunc([](YGNode*, double, double) { return 0.0; }); +TEST(Node, hasBaselineFunc_with_baseline_fn) { + auto n = Node{}; + n.setBaselineFunc([](YGNodeConstRef, float, float) { return 0.0f; }); ASSERT_TRUE(n.hasBaselineFunc()); } -TEST(YGNode, baseline_with_baseline_fn) { - auto n = YGNode{}; - n.setBaselineFunc([](YGNode*, double w, double h) { return w + h; }); - - ASSERT_EQ(n.baseline(1.25, 2.5, nullptr), 3.75); -} - -TEST(YGNode, baseline_with_context_baseline_fn) { - auto n = YGNode{}; - n.setBaselineFunc([](YGNode*, double w, double h, void* ctx) { - return w + h + *(double*) ctx; - }); +TEST(Node, baseline_with_baseline_fn) { + auto n = Node{}; + n.setBaselineFunc([](YGNodeConstRef, float w, float h) { return w + h; }); - auto ctx = -10.0; - ASSERT_EQ(n.baseline(1.25, 2.5, &ctx), -6.25); + ASSERT_EQ(n.baseline(1.25f, 2.5f), 3.75f); } -TEST(YGNode, hasBaselineFunc_after_unset) { - auto n = YGNode{}; - n.setBaselineFunc([](YGNode*, double, double) { return 0.0; }); +TEST(Node, hasBaselineFunc_after_unset) { + auto n = Node{}; + n.setBaselineFunc([](YGNodeConstRef, float, float) { return 0.0f; }); n.setBaselineFunc(nullptr); ASSERT_FALSE(n.hasBaselineFunc()); } - -TEST(YGNode, hasBaselineFunc_after_unset_context) { - auto n = YGNode{}; - n.setBaselineFunc([](YGNode*, double, double, void*) { return 0.0; }); - - n.setMeasureFunc(nullptr); - ASSERT_FALSE(n.hasMeasureFunc()); -} - -TEST(YGNode, switching_baseline_fn_types) { - auto n = YGNode{}; - n.setBaselineFunc([](YGNode*, double, double, void*) { return 0.0; }); - n.setBaselineFunc([](YGNode*, double, double) { return 1.0; }); - ASSERT_EQ(n.baseline(1, 2, nullptr), 1.0); -} - -void PrintTo(const YGSize& size, std::ostream* os) { - *os << "YGSize{" << size.width << ", " << size.height << "}"; -} diff --git a/tests/YGNodeChildTest.cpp b/tests/YGNodeChildTest.cpp index cce9f33b51..b61c1322fe 100644 --- a/tests/YGNodeChildTest.cpp +++ b/tests/YGNodeChildTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,9 +9,9 @@ #include TEST(YogaTest, reset_layout_when_child_removed) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); @@ -31,4 +31,5 @@ TEST(YogaTest, reset_layout_when_child_removed) { ASSERT_TRUE(YGFloatIsUndefined(YGNodeLayoutGetHeight(root_child0))); YGNodeFreeRecursive(root); + YGNodeFreeRecursive(root_child0); } diff --git a/tests/YGPersistenceTest.cpp b/tests/YGPersistenceTest.cpp index 5ee6bf810f..929aee07ec 100644 --- a/tests/YGPersistenceTest.cpp +++ b/tests/YGPersistenceTest.cpp @@ -1,30 +1,32 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 -#include +#include +#include "util/TestUtil.h" + +using namespace facebook; using facebook::yoga::test::TestUtil; TEST(YogaTest, cloning_shared_root) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -44,7 +46,7 @@ TEST(YogaTest, cloning_shared_root) { ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); - const YGNodeRef root2 = YGNodeClone(root); + YGNodeRef root2 = YGNodeClone(root); YGNodeStyleSetWidth(root2, 100); ASSERT_EQ(2u, YGNodeGetChildCount(root2)); @@ -65,8 +67,8 @@ TEST(YogaTest, cloning_shared_root) { ASSERT_EQ(2u, 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); + YGNodeRef root2_child0 = YGNodeGetChild(root2, 0); + YGNodeRef root2_child1 = YGNodeGetChild(root2, 1); ASSERT_NE(root_child0, root2_child0); ASSERT_NE(root_child1, root2_child1); @@ -110,33 +112,33 @@ TEST(YogaTest, cloning_shared_root) { } TEST(YogaTest, mutating_children_of_a_clone_clones_only_after_layout) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); ASSERT_EQ(0u, YGNodeGetChildCount(root)); - const YGNodeRef root2 = YGNodeClone(root); + YGNodeRef root2 = YGNodeClone(root); ASSERT_EQ(0u, YGNodeGetChildCount(root2)); - const YGNodeRef root2_child0 = YGNodeNewWithConfig(config); + YGNodeRef root2_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root2, root2_child0, 0); ASSERT_EQ(0u, YGNodeGetChildCount(root)); ASSERT_EQ(1u, YGNodeGetChildCount(root2)); - const YGNodeRef root3 = YGNodeClone(root2); + YGNodeRef root3 = YGNodeClone(root2); ASSERT_EQ(1u, YGNodeGetChildCount(root2)); ASSERT_EQ(1u, YGNodeGetChildCount(root3)); ASSERT_EQ(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0)); - const YGNodeRef root3_child1 = YGNodeNewWithConfig(config); + YGNodeRef root3_child1 = YGNodeNewWithConfig(config); YGNodeInsertChild(root3, root3_child1, 1); ASSERT_EQ(1u, YGNodeGetChildCount(root2)); ASSERT_EQ(2u, YGNodeGetChildCount(root3)); ASSERT_EQ(root3_child1, YGNodeGetChild(root3, 1)); ASSERT_EQ(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0)); - const YGNodeRef root4 = YGNodeClone(root3); + YGNodeRef root4 = YGNodeClone(root3); ASSERT_EQ(root3_child1, YGNodeGetChild(root4, 1)); YGNodeRemoveChild(root4, root3_child1); @@ -158,27 +160,27 @@ TEST(YogaTest, mutating_children_of_a_clone_clones_only_after_layout) { } TEST(YogaTest, cloning_two_levels) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 15); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1_1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasis(root_child1_1, 25); YGNodeInsertChild(root_child1, root_child1_1, 1); @@ -189,9 +191,9 @@ TEST(YogaTest, cloning_two_levels) { 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); + YGNodeRef root2_child0 = YGNodeClone(root_child0); + YGNodeRef root2_child1 = YGNodeClone(root_child1); + YGNodeRef root2 = YGNodeClone(root); YGNodeStyleSetFlexGrow(root2_child0, 0); YGNodeStyleSetFlexBasis(root2_child0, 40); @@ -226,19 +228,19 @@ TEST(YogaTest, cloning_two_levels) { TEST(YogaTest, cloning_and_freeing) { TestUtil::startCountingNodes(); - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); - const YGNodeRef root2 = YGNodeClone(root); + YGNodeRef root2 = YGNodeClone(root); // Freeing the original root should be safe as long as we don't free its // children. @@ -272,9 +274,10 @@ TEST(YogaTest, mixed_shared_and_owned_children) { YGNodeInsertChild(root1, root1_child0, 0); YGNodeInsertChild(root1, root1_child2, 1); - auto children = root1->getChildren(); - children.insert(children.begin() + 1, root0_child0); - root1->setChildren(children); + auto children = static_cast(root1)->getChildren(); + children.insert(children.begin() + 1, static_cast(root0_child0)); + static_cast(root1)->setChildren(children); + auto secondChild = YGNodeGetChild(root1, 1); ASSERT_EQ(secondChild, YGNodeGetChild(root0, 0)); ASSERT_EQ(YGNodeGetChild(secondChild, 0), YGNodeGetChild(root0_child0, 0)); diff --git a/tests/YGRelayoutTest.cpp b/tests/YGRelayoutTest.cpp index 7a4d1d6434..c4c0adde23 100644 --- a/tests/YGRelayoutTest.cpp +++ b/tests/YGRelayoutTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,15 +9,15 @@ #include TEST(YogaTest, dont_cache_computed_flex_basis_between_layouts) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); YGConfigSetExperimentalFeatureEnabled( config, YGExperimentalFeatureWebFlexBasis, true); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetHeightPercent(root, 100); YGNodeStyleSetWidthPercent(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasisPercent(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); @@ -32,9 +32,9 @@ TEST(YogaTest, dont_cache_computed_flex_basis_between_layouts) { } TEST(YogaTest, recalculate_resolvedDimonsion_onchange) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); - const YGNodeRef root_child0 = YGNodeNew(); + YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetMinHeight(root_child0, 10); YGNodeStyleSetMaxHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -49,3 +49,207 @@ TEST(YogaTest, recalculate_resolvedDimonsion_onchange) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, relayout_containing_block_size_changes) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeRelative); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 63); + 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(279, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-2, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + // Relayout starts here + YGNodeStyleSetWidth(root_child0, 456); + YGNodeStyleSetHeight(root_child0, 432); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(469, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(438, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(456, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(432, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(182, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(263, 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(469, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(438, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(456, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(432, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(235, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(182, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(263, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, has_new_layout_flag_set_static) { + YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child1, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child1, 5); + YGNodeStyleSetHeight(root_child0_child1, 5); + YGNodeInsertChild(root_child0, root_child0_child1, 0); + + YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 5); + YGNodeStyleSetHeight(root_child0_child0, 5); + YGNodeInsertChild(root_child0, root_child0_child0, 1); + + YGNodeRef root_child0_child0_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 1); + YGNodeStyleSetHeight(root_child0_child0_child0, 1); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + YGNodeSetHasNewLayout(root, false); + YGNodeSetHasNewLayout(root_child0, false); + YGNodeSetHasNewLayout(root_child0_child0, false); + YGNodeSetHasNewLayout(root_child0_child0_child0, false); + + YGNodeStyleSetWidth(root, 110); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_TRUE(YGNodeGetHasNewLayout(root)); + ASSERT_TRUE(YGNodeGetHasNewLayout(root_child0)); + ASSERT_TRUE(YGNodeGetHasNewLayout(root_child0_child0)); + ASSERT_TRUE(YGNodeGetHasNewLayout(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); +} diff --git a/tests/YGRoundingFunctionTest.cpp b/tests/YGRoundingFunctionTest.cpp index 5543ca7b67..55b5e86dee 100644 --- a/tests/YGRoundingFunctionTest.cpp +++ b/tests/YGRoundingFunctionTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -7,7 +7,8 @@ #include #include -#include + +#include TEST(YogaTest, rounding_value) { // Test that whole numbers are rounded to whole despite ceil/floor flags @@ -40,37 +41,75 @@ TEST(YogaTest, rounding_value) { ASSERT_FLOAT_EQ(-6.0, YGRoundValueToPixelGrid(-5.99, 2.0, false, false)); ASSERT_FLOAT_EQ(-5.5, YGRoundValueToPixelGrid(-5.99, 2.0, true, false)); ASSERT_FLOAT_EQ(-6.0, YGRoundValueToPixelGrid(-5.99, 2.0, false, true)); + + // Rounding up/down halfway values is as expected for both positive and + // negative numbers + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.5, 1.0, false, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.4, 1.0, false, false)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.6, 1.0, false, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.499999, 1.0, false, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.500001, 1.0, false, false)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.5001, 1.0, false, false)); + + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.5, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.4, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.6, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.499999, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.500001, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.5001, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.00001, 1.0, true, false)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3, 1.0, true, false)); + + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.5, 1.0, false, true)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.4, 1.0, false, true)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.6, 1.0, false, true)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.499999, 1.0, false, true)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.500001, 1.0, false, true)); + ASSERT_FLOAT_EQ(-4, YGRoundValueToPixelGrid(-3.5001, 1.0, false, true)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3.00001, 1.0, false, true)); + ASSERT_FLOAT_EQ(-3, YGRoundValueToPixelGrid(-3, 1.0, false, true)); + + // NAN is treated as expected: + ASSERT_TRUE(std::isnan(YGRoundValueToPixelGrid( + std::numeric_limits::quiet_NaN(), 1.5, false, false))); + ASSERT_TRUE(std::isnan(YGRoundValueToPixelGrid( + 1.5, std::numeric_limits::quiet_NaN(), false, false))); + ASSERT_TRUE(std::isnan(YGRoundValueToPixelGrid( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), + false, + false))); } static YGSize measureText( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - return (YGSize){.width = 10, .height = 10}; + YGNodeConstRef /*node*/, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + return YGSize{10, 10}; } // Regression test for https://github.com/facebook/yoga/issues/824 TEST(YogaTest, consistent_rounding_during_repeated_layouts) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); YGConfigSetPointScaleFactor(config, 2); - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetMargin(root, YGEdgeTop, -1.49); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root, YGEdgeTop, -1.49f); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef node0 = YGNodeNewWithConfig(config); + YGNodeRef node0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, node0, 0); - const YGNodeRef node1 = YGNodeNewWithConfig(config); + YGNodeRef node1 = YGNodeNewWithConfig(config); YGNodeSetMeasureFunc(node1, measureText); YGNodeInsertChild(node0, node1, 0); for (int i = 0; i < 5; i++) { // Dirty the tree so YGRoundToPixelGrid runs again - YGNodeStyleSetMargin(root, YGEdgeLeft, i + 1); + YGNodeStyleSetMargin(root, YGEdgeLeft, (float)(i + 1)); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(node1)); @@ -80,3 +119,45 @@ TEST(YogaTest, consistent_rounding_during_repeated_layouts) { YGConfigFree(config); } + +TEST(YogaTest, per_node_point_scale_factor) { + YGConfigRef config1 = YGConfigNew(); + YGConfigSetPointScaleFactor(config1, 2); + + YGConfigRef config2 = YGConfigNew(); + YGConfigSetPointScaleFactor(config2, 1); + + YGConfigRef config3 = YGConfigNew(); + YGConfigSetPointScaleFactor(config3, 0.5f); + + YGNodeRef root = YGNodeNewWithConfig(config1); + YGNodeStyleSetWidth(root, 11.5); + YGNodeStyleSetHeight(root, 11.5); + + YGNodeRef node0 = YGNodeNewWithConfig(config2); + YGNodeStyleSetWidth(node0, 9.5); + YGNodeStyleSetHeight(node0, 9.5); + YGNodeInsertChild(root, node0, 0); + + YGNodeRef node1 = YGNodeNewWithConfig(config3); + YGNodeStyleSetWidth(node1, 7); + YGNodeStyleSetHeight(node1, 7); + YGNodeInsertChild(node0, node1, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_EQ(YGNodeLayoutGetWidth(root), 11.5); + ASSERT_EQ(YGNodeLayoutGetHeight(root), 11.5); + + ASSERT_EQ(YGNodeLayoutGetWidth(node0), 10); + ASSERT_EQ(YGNodeLayoutGetHeight(node0), 10); + + ASSERT_EQ(YGNodeLayoutGetWidth(node1), 8); + ASSERT_EQ(YGNodeLayoutGetHeight(node1), 8); + + YGNodeFreeRecursive(root); + + YGConfigFree(config1); + YGConfigFree(config2); + YGConfigFree(config3); +} diff --git a/tests/YGRoundingMeasureFuncTest.cpp b/tests/YGRoundingMeasureFuncTest.cpp index 397cf316d7..c654a280ec 100644 --- a/tests/YGRoundingMeasureFuncTest.cpp +++ b/tests/YGRoundingMeasureFuncTest.cpp @@ -1,87 +1,86 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { + YGNodeConstRef /*node*/, + float width, + YGMeasureMode /*widthMode*/, + float height, + YGMeasureMode /*heightMode*/) { return YGSize{ - width = 10.2, - height = 10.2, + width = 10.2f, + height = 10.2f, }; } static YGSize _measureCeil( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { + YGNodeConstRef /*node*/, + float width, + YGMeasureMode /*widthMode*/, + float height, + YGMeasureMode /*heightMode*/) { return YGSize{ - width = 10.5, - height = 10.5, + width = 10.5f, + height = 10.5f, }; } static YGSize _measureFractial( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { + YGNodeConstRef /*node*/, + float width, + YGMeasureMode /*widthMode*/, + float height, + YGMeasureMode /*heightMode*/) { return YGSize{ - width = 0.5, - height = 0.5, + width = 0.5f, + height = 0.5f, }; } TEST(YogaTest, rounding_feature_with_custom_measure_func_floor) { - const YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGConfigRef config = YGConfigNew(); + YGNodeRef root = YGNodeNewWithConfig(config); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - root_child0->setMeasureFunc(_measureFloor); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _measureFloor); YGNodeInsertChild(root, root_child0, 0); - YGConfigSetPointScaleFactor(config, 0.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)); + ASSERT_FLOAT_EQ(10.2f, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10.2f, YGNodeLayoutGetHeight(root_child0)); - YGConfigSetPointScaleFactor(config, 1.0); + 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.0); + 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.0); + 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.0 / 3.0); + YGConfigSetPointScaleFactor(config, 1.0f / 3.0f); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); @@ -94,14 +93,14 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_floor) { } TEST(YogaTest, rounding_feature_with_custom_measure_func_ceil) { - const YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGConfigRef config = YGConfigNew(); + YGNodeRef root = YGNodeNewWithConfig(config); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - root_child0->setMeasureFunc(_measureCeil); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeSetMeasureFunc(root_child0, _measureCeil); YGNodeInsertChild(root, root_child0, 0); - YGConfigSetPointScaleFactor(config, 1.0); + YGConfigSetPointScaleFactor(config, 1.0f); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -116,15 +115,17 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_ceil) { TEST( YogaTest, rounding_feature_with_custom_measure_and_fractial_matching_scale) { - const YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGConfigRef config = YGConfigNew(); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 73.625); - root_child0->setMeasureFunc(_measureFractial); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeRelative); + YGNodeSetMeasureFunc(root_child0, _measureFractial); YGNodeInsertChild(root, root_child0, 0); - YGConfigSetPointScaleFactor(config, 2.0); + YGConfigSetPointScaleFactor(config, 2.0f); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); diff --git a/tests/YGScaleChangeTest.cpp b/tests/YGScaleChangeTest.cpp new file mode 100644 index 0000000000..11de9c079c --- /dev/null +++ b/tests/YGScaleChangeTest.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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, scale_change_invalidates_layout) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGConfigSetPointScaleFactor(config, 1.0f); + + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + 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_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + + YGConfigSetPointScaleFactor(config, 1.5f); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + // Left should change due to pixel alignment of new scale factor + ASSERT_FLOAT_EQ(25.333334f, YGNodeLayoutGetLeft(root_child1)); + + YGNodeFreeRecursive(root); + YGConfigFree(config); +} + +TEST(YogaTest, errata_config_change_relayout) { + YGConfig* config = YGConfigNew(); + YGConfigSetErrata(config, YGErrataStretchFlexBasis); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + 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)); + + YGConfigSetErrata(config, YGErrataNone); + 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)); + // This should be modified by the lack of the errata + 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)); + // This should be modified by the lack of the errata + 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)); + // This should be modified by the lack of the errata + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, setting_compatible_config_maintains_layout_cache) { + static uint32_t measureCallCount = 0; + auto measureCustom = [](YGNodeConstRef /*node*/, + float /*width*/, + YGMeasureMode /*widthMode*/, + float /*height*/, + YGMeasureMode /*heightMode*/) { + measureCallCount++; + return YGSize{ + .width = 25.0f, + .height = 25.0f, + }; + }; + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGConfigSetPointScaleFactor(config, 1.0f); + + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + EXPECT_EQ(0, measureCallCount); + + YGNodeSetMeasureFunc(root_child0, measureCustom); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + EXPECT_EQ(1, measureCallCount); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + + YGConfigRef config2 = YGConfigNew(); + // Calling YGConfigSetPointScaleFactor multiple times, ensures that config2 + // gets a different config version that config1 + YGConfigSetPointScaleFactor(config2, 1.0f); + YGConfigSetPointScaleFactor(config2, 1.5f); + YGConfigSetPointScaleFactor(config2, 1.0f); + + YGNodeSetConfig(root, config2); + YGNodeSetConfig(root_child0, config2); + YGNodeSetConfig(root_child1, config2); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + // Measure should not be called again, as layout should have been cached since + // config is functionally the same as before + EXPECT_EQ(1, measureCallCount); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1)); + + YGNodeFreeRecursive(root); + YGConfigFree(config); + YGConfigFree(config2); +} diff --git a/tests/YGStyleAccessorsTest.cpp b/tests/YGStyleAccessorsTest.cpp deleted file mode 100644 index 19fb029627..0000000000 --- a/tests/YGStyleAccessorsTest.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 -#include -#include -#include - -#define ACCESSOR_TESTS_1(NAME, X) \ - style.NAME() = X; \ - ASSERT_EQ(style.NAME(), X); -#define ACCESSOR_TESTS_2(NAME, X, ...) \ - ACCESSOR_TESTS_1(NAME, X); \ - ACCESSOR_TESTS_1(NAME, __VA_ARGS__); -#define ACCESSOR_TESTS_3(NAME, X, ...) \ - ACCESSOR_TESTS_1(NAME, X); \ - ACCESSOR_TESTS_2(NAME, __VA_ARGS__); -#define ACCESSOR_TESTS_4(NAME, X, ...) \ - ACCESSOR_TESTS_1(NAME, X); \ - ACCESSOR_TESTS_3(NAME, __VA_ARGS__); -#define ACCESSOR_TESTS_5(NAME, X, ...) \ - ACCESSOR_TESTS_1(NAME, X); \ - ACCESSOR_TESTS_4(NAME, __VA_ARGS__) - -#define ACCESSOR_TESTS_N(a, b, c, d, e, COUNT, ...) ACCESSOR_TESTS_##COUNT -#define ACCESSOR_TESTS(...) ACCESSOR_TESTS_N(__VA_ARGS__, 5, 4, 3, 2, 1) - -#define INDEX_ACCESSOR_TESTS_1(NAME, IDX, X) \ - { \ - auto style = YGStyle{}; \ - style.NAME()[IDX] = X; \ - ASSERT_EQ(style.NAME()[IDX], X); \ - auto asArray = decltype(std::declval().NAME()){X}; \ - style.NAME() = asArray; \ - ASSERT_EQ(static_cast(style.NAME()), asArray); \ - } - -#define INDEX_ACCESSOR_TESTS_2(NAME, IDX, X, Y) \ - INDEX_ACCESSOR_TESTS_1(NAME, IDX, X) \ - INDEX_ACCESSOR_TESTS_1(NAME, IDX, Y) - -#define INDEX_ACCESSOR_TESTS_3(NAME, IDX, X, ...) \ - INDEX_ACCESSOR_TESTS_1(NAME, IDX, X) \ - INDEX_ACCESSOR_TESTS_2(NAME, IDX, __VA_ARGS__) - -#define INDEX_ACCESSOR_TESTS_4(NAME, IDX, X, ...) \ - INDEX_ACCESSOR_TESTS_1(NAME, IDX, X) \ - INDEX_ACCESSOR_TESTS_3(NAME, IDX, __VA_ARGS__) - -#define INDEX_ACCESSOR_TESTS_5(NAME, IDX, X, ...) \ - INDEX_ACCESSOR_TESTS_1(NAME, IDX, X) \ - INDEX_ACCESSOR_TESTS_4(NAME, IDX, __VA_ARGS__) - -#define INDEX_ACCESSOR_TESTS_N(a, b, c, d, e, COUNT, ...) \ - INDEX_ACCESSOR_TESTS_##COUNT -#define INDEX_ACCESSOR_TESTS(...) \ - INDEX_ACCESSOR_TESTS_N(__VA_ARGS__, 5, 4, 3, 2, 1) - -// test macro for up to 5 values. If more are needed, extend the macros above. -#define ACCESSOR_TEST(NAME, DEFAULT_VAL, ...) \ - TEST(YGStyle, style_##NAME##_access) { \ - auto style = YGStyle{}; \ - ASSERT_EQ(style.NAME(), DEFAULT_VAL); \ - ACCESSOR_TESTS(__VA_ARGS__)(NAME, __VA_ARGS__) \ - } - -#define INDEX_ACCESSOR_TEST(NAME, DEFAULT_VAL, IDX, ...) \ - TEST(YGStyle, style_##NAME##_access) { \ - ASSERT_EQ(YGStyle{}.NAME()[IDX], DEFAULT_VAL); \ - INDEX_ACCESSOR_TESTS(__VA_ARGS__)(NAME, IDX, __VA_ARGS__) \ - } - -namespace facebook { -namespace yoga { - -using CompactValue = detail::CompactValue; - -ACCESSOR_TEST( - direction, - YGDirectionInherit, - YGDirectionLTR, - YGDirectionRTL, - YGDirectionInherit); - -ACCESSOR_TEST( - flexDirection, - YGFlexDirectionColumn, - YGFlexDirectionColumnReverse, - YGFlexDirectionRowReverse, - YGFlexDirectionRow) - -ACCESSOR_TEST( - justifyContent, - YGJustifyFlexStart, - YGJustifyFlexEnd, - YGJustifySpaceAround, - YGJustifyFlexStart, - YGJustifySpaceEvenly) - -ACCESSOR_TEST( - alignContent, - YGAlignFlexStart, - YGAlignAuto, - YGAlignFlexStart, - YGAlignCenter, - YGAlignFlexEnd, - YGAlignStretch) - -ACCESSOR_TEST( - alignItems, - YGAlignStretch, - YGAlignFlexStart, - YGAlignFlexEnd, - YGAlignBaseline, - YGAlignSpaceBetween, - YGAlignSpaceAround) - -ACCESSOR_TEST( - alignSelf, - YGAlignAuto, - YGAlignFlexStart, - YGAlignCenter, - YGAlignAuto, - YGAlignFlexEnd, - YGAlignStretch) - -ACCESSOR_TEST( - positionType, - YGPositionTypeStatic, - YGPositionTypeAbsolute, - YGPositionTypeRelative, - YGPositionTypeStatic) - -ACCESSOR_TEST( - flexWrap, - YGWrapNoWrap, - YGWrapWrap, - YGWrapWrapReverse, - YGWrapNoWrap) - -ACCESSOR_TEST( - overflow, - YGOverflowVisible, - YGOverflowHidden, - YGOverflowScroll, - YGOverflowVisible) - -ACCESSOR_TEST(display, YGDisplayFlex, YGDisplayNone, YGDisplayFlex) - -ACCESSOR_TEST( - flex, - YGFloatOptional{}, - YGFloatOptional{123.45}, - YGFloatOptional{-9.87}, - YGFloatOptional{}) - -ACCESSOR_TEST( - flexGrow, - YGFloatOptional{}, - YGFloatOptional{123.45}, - YGFloatOptional{-9.87}, - YGFloatOptional{}) - -ACCESSOR_TEST( - flexShrink, - YGFloatOptional{}, - YGFloatOptional{123.45}, - YGFloatOptional{-9.87}, - YGFloatOptional{}) - -ACCESSOR_TEST( - flexBasis, - CompactValue::ofAuto(), - CompactValue::ofUndefined(), - CompactValue::ofAuto(), - CompactValue::of(7777.77), - CompactValue::of(-100.0)) - -INDEX_ACCESSOR_TEST( - position, - CompactValue::ofUndefined(), - YGEdgeBottom, - CompactValue::ofAuto(), - CompactValue::ofUndefined(), - CompactValue::of(7777.77), - CompactValue::of(-100.0)) - -INDEX_ACCESSOR_TEST( - margin, - CompactValue::ofUndefined(), - YGEdgeTop, - CompactValue::ofAuto(), - CompactValue::ofUndefined(), - CompactValue::of(7777.77), - CompactValue::of(-100.0)) - -INDEX_ACCESSOR_TEST( - padding, - CompactValue::ofUndefined(), - YGEdgeAll, - CompactValue::of(7777.77), - CompactValue::ofUndefined(), - CompactValue::of(-100.0)) - -INDEX_ACCESSOR_TEST( - border, - CompactValue::ofUndefined(), - YGEdgeHorizontal, - CompactValue::of(-7777.77), - CompactValue::ofUndefined()) - -INDEX_ACCESSOR_TEST( - dimensions, - CompactValue::ofAuto(), - YGDimensionWidth, - CompactValue::ofUndefined(), - CompactValue::ofAuto(), - CompactValue::of(7777.77), - CompactValue::of(-100.0)) - -INDEX_ACCESSOR_TEST( - minDimensions, - CompactValue::ofUndefined(), - YGDimensionHeight, - CompactValue::ofAuto(), - CompactValue::ofUndefined(), - CompactValue::of(7777.77), - CompactValue::of(-100.0)) - -INDEX_ACCESSOR_TEST( - maxDimensions, - CompactValue::ofUndefined(), - YGDimensionHeight, - CompactValue::ofAuto(), - CompactValue::ofUndefined(), - CompactValue::of(7777.77), - CompactValue::of(-100.0)) - -ACCESSOR_TEST( - aspectRatio, - YGFloatOptional{}, - YGFloatOptional{-123.45}, - YGFloatOptional{9876.5}, - YGFloatOptional{0.0}, - YGFloatOptional{}); - -} // namespace yoga -} // namespace facebook diff --git a/tests/YGStyleTest.cpp b/tests/YGStyleTest.cpp index 56aa299dad..afeb0d3f75 100644 --- a/tests/YGStyleTest.cpp +++ b/tests/YGStyleTest.cpp @@ -1,38 +1,33 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 +#include TEST(YogaTest, copy_style_same) { - const YGNodeRef node0 = YGNodeNew(); - const YGNodeRef node1 = YGNodeNew(); - ASSERT_FALSE(node0->isDirty()); + YGNodeRef node0 = YGNodeNew(); + YGNodeRef node1 = YGNodeNew(); YGNodeCopyStyle(node0, node1); - ASSERT_FALSE(node0->isDirty()); YGNodeFree(node0); YGNodeFree(node1); } TEST(YogaTest, copy_style_modified) { - const YGNodeRef node0 = YGNodeNew(); - ASSERT_FALSE(node0->isDirty()); + YGNodeRef node0 = YGNodeNew(); ASSERT_EQ(YGFlexDirectionColumn, YGNodeStyleGetFlexDirection(node0)); ASSERT_FALSE(YGNodeStyleGetMaxHeight(node0).unit != YGUnitUndefined); - const YGNodeRef node1 = YGNodeNew(); + 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); @@ -41,25 +36,23 @@ TEST(YogaTest, copy_style_modified) { } TEST(YogaTest, copy_style_modified_same) { - const YGNodeRef node0 = YGNodeNew(); + YGNodeRef node0 = YGNodeNew(); YGNodeStyleSetFlexDirection(node0, YGFlexDirectionRow); YGNodeStyleSetMaxHeight(node0, 10); YGNodeCalculateLayout(node0, YGUndefined, YGUndefined, YGDirectionLTR); - ASSERT_FALSE(node0->isDirty()); - const YGNodeRef node1 = YGNodeNew(); + 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(); + YGNodeRef node0 = YGNodeNew(); YGNodeStyleSetFlexShrink(node0, 1); ASSERT_EQ(1, YGNodeStyleGetFlexShrink(node0)); diff --git a/tests/YGTraversalTest.cpp b/tests/YGTraversalTest.cpp deleted file mode 100644 index 6b39a22f4c..0000000000 --- a/tests/YGTraversalTest.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 --git a/tests/YGTreeMutationTest.cpp b/tests/YGTreeMutationTest.cpp index 26f0b90046..301d0989f7 100644 --- a/tests/YGTreeMutationTest.cpp +++ b/tests/YGTreeMutationTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,10 +9,10 @@ #include static std::vector getChildren(YGNodeRef const node) { - const uint32_t count = YGNodeGetChildCount(node); + const auto count = YGNodeGetChildCount(node); std::vector children; children.reserve(count); - for (uint32_t i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { children.push_back(YGNodeGetChild(node, i)); } return children; @@ -23,11 +23,11 @@ TEST(YogaTest, set_children_adds_children_to_parent) { YGNodeRef const root_child0 = YGNodeNew(); YGNodeRef const root_child1 = YGNodeNew(); - YGNodeSetChildren(root, {root_child0, root_child1}); + YGNodeRef children[] = {root_child0, root_child1}; + YGNodeSetChildren(root, children, 2); - const std::vector children = getChildren(root); const std::vector expectedChildren = {root_child0, root_child1}; - ASSERT_EQ(children, expectedChildren); + ASSERT_EQ(getChildren(root), expectedChildren); const std::vector owners = { YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; @@ -42,12 +42,12 @@ TEST(YogaTest, set_children_to_empty_removes_old_children) { YGNodeRef const root_child0 = YGNodeNew(); YGNodeRef const root_child1 = YGNodeNew(); - YGNodeSetChildren(root, {root_child0, root_child1}); - YGNodeSetChildren(root, {}); + YGNodeRef children[] = {root_child0, root_child1}; + YGNodeSetChildren(root, children, 2); + YGNodeSetChildren(root, nullptr, 0); - const std::vector children = getChildren(root); const std::vector expectedChildren = {}; - ASSERT_EQ(children, expectedChildren); + ASSERT_EQ(getChildren(root), expectedChildren); const std::vector owners = { YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; @@ -62,16 +62,17 @@ TEST(YogaTest, set_children_replaces_non_common_children) { YGNodeRef const root_child0 = YGNodeNew(); YGNodeRef const root_child1 = YGNodeNew(); - YGNodeSetChildren(root, {root_child0, root_child1}); + YGNodeRef children1[] = {root_child0, root_child1}; + YGNodeSetChildren(root, children1, 2); YGNodeRef const root_child2 = YGNodeNew(); YGNodeRef const root_child3 = YGNodeNew(); - YGNodeSetChildren(root, {root_child2, root_child3}); + YGNodeRef children2[] = {root_child2, root_child3}; + YGNodeSetChildren(root, children2, 2); - const std::vector children = getChildren(root); const std::vector expectedChildren = {root_child2, root_child3}; - ASSERT_EQ(children, expectedChildren); + ASSERT_EQ(getChildren(root), expectedChildren); const std::vector owners = { YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; @@ -89,16 +90,17 @@ TEST(YogaTest, set_children_keeps_and_reorders_common_children) { YGNodeRef const root_child1 = YGNodeNew(); YGNodeRef const root_child2 = YGNodeNew(); - YGNodeSetChildren(root, {root_child0, root_child1, root_child2}); + YGNodeRef children1[] = {root_child0, root_child1, root_child2}; + YGNodeSetChildren(root, children1, 3); YGNodeRef const root_child3 = YGNodeNew(); - YGNodeSetChildren(root, {root_child2, root_child1, root_child3}); + YGNodeRef children2[] = {root_child2, root_child1, root_child3}; + YGNodeSetChildren(root, children2, 3); - const std::vector children = getChildren(root); const std::vector expectedChildren = { root_child2, root_child1, root_child3}; - ASSERT_EQ(children, expectedChildren); + ASSERT_EQ(getChildren(root), expectedChildren); const std::vector owners = { YGNodeGetOwner(root_child0), diff --git a/tests/YGValueTest.cpp b/tests/YGValueTest.cpp index 379c33f2fa..3a64d6eac7 100644 --- a/tests/YGValueTest.cpp +++ b/tests/YGValueTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -10,40 +10,14 @@ #include TEST(YGValue, supports_equality) { - ASSERT_EQ((YGValue{12.5, YGUnitPercent}), (YGValue{12.5, YGUnitPercent})); - ASSERT_NE((YGValue{12.5, YGUnitPercent}), (YGValue{56.7, YGUnitPercent})); - ASSERT_NE((YGValue{12.5, YGUnitPercent}), (YGValue{12.5, YGUnitPoint})); - ASSERT_NE((YGValue{12.5, YGUnitPercent}), (YGValue{12.5, YGUnitAuto})); - ASSERT_NE((YGValue{12.5, YGUnitPercent}), (YGValue{12.5, YGUnitUndefined})); + ASSERT_EQ((YGValue{12.5f, YGUnitPercent}), (YGValue{12.5f, YGUnitPercent})); + ASSERT_NE((YGValue{12.5f, YGUnitPercent}), (YGValue{56.7f, YGUnitPercent})); + ASSERT_NE((YGValue{12.5f, YGUnitPercent}), (YGValue{12.5f, YGUnitPoint})); + ASSERT_NE((YGValue{12.5f, YGUnitPercent}), (YGValue{12.5f, YGUnitAuto})); + ASSERT_NE((YGValue{12.5f, YGUnitPercent}), (YGValue{12.5f, YGUnitUndefined})); ASSERT_EQ( - (YGValue{12.5, YGUnitUndefined}), + (YGValue{12.5f, YGUnitUndefined}), (YGValue{YGUndefined, YGUnitUndefined})); ASSERT_EQ((YGValue{0, YGUnitAuto}), (YGValue{-1, YGUnitAuto})); } - -using namespace facebook::yoga::literals; - -TEST(YGValue, supports_double_point_literals) { - ASSERT_EQ(12.5_pt, (YGValue{12.5, YGUnitPoint})); -} - -TEST(YGValue, supports_double_percent_literals) { - ASSERT_EQ(12.5_percent, (YGValue{12.5, YGUnitPercent})); -} - -TEST(YGValue, supports_integral_point_literals) { - ASSERT_EQ(34_pt, (YGValue{34, YGUnitPoint})); -} - -TEST(YGValue, supports_integral_percent_literals) { - ASSERT_EQ(125_percent, (YGValue{125, YGUnitPercent})); -} - -TEST(YGValue, supports_negative_point_literals) { - ASSERT_EQ(-34.5_pt, (YGValue{-34.5, YGUnitPoint})); -} - -TEST(YGValue, supports_negative_percent_literals) { - ASSERT_EQ(-34.5_percent, (YGValue{-34.5, YGUnitPercent})); -} diff --git a/tests/YGZeroOutLayoutRecursivlyTest.cpp b/tests/YGZeroOutLayoutRecursivelyTest.cpp similarity index 88% rename from tests/YGZeroOutLayoutRecursivlyTest.cpp rename to tests/YGZeroOutLayoutRecursivelyTest.cpp index 84e1944195..2f2789a54e 100644 --- a/tests/YGZeroOutLayoutRecursivlyTest.cpp +++ b/tests/YGZeroOutLayoutRecursivelyTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,12 +9,12 @@ #include TEST(YogaTest, zero_out_layout) { - const YGNodeRef root = YGNodeNew(); + YGNodeRef root = YGNodeNew(); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef child = YGNodeNew(); + YGNodeRef child = YGNodeNew(); YGNodeInsertChild(root, child, 0); YGNodeStyleSetWidth(child, 100); YGNodeStyleSetHeight(child, 100); diff --git a/tests/YGAbsolutePositionTest.cpp b/tests/generated/YGAbsolutePositionTest.cpp similarity index 53% rename from tests/YGAbsolutePositionTest.cpp rename to tests/generated/YGAbsolutePositionTest.cpp index eea5613289..c3d5302927 100644 --- a/tests/YGAbsolutePositionTest.cpp +++ b/tests/generated/YGAbsolutePositionTest.cpp @@ -1,23 +1,27 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<499316b3f7b7ec5c406abf5ac77837f1>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAbsolutePositionTest.html */ -// @Generated by gentest/gentest.rb from -// gentest/fixtures/YGAbsolutePositionTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, absolute_layout_width_height_start_top) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeStart, 10); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); @@ -53,14 +57,147 @@ TEST(YogaTest, absolute_layout_width_height_start_top) { YGConfigFree(config); } +TEST(YogaTest, absolute_layout_width_height_left_auto_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, 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(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(80, 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, absolute_layout_width_height_left_right_auto) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPositionAuto(root_child0, YGEdgeRight); + 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(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(10, 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, absolute_layout_width_height_left_auto_right_auto) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetPositionAuto(root_child0, YGEdgeRight); + 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, absolute_layout_width_height_end_bottom) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeEnd, 10); YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); @@ -97,13 +234,14 @@ TEST(YogaTest, absolute_layout_width_height_end_bottom) { } TEST(YogaTest, absolute_layout_start_top_end_bottom) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeStart, 10); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); @@ -140,13 +278,14 @@ TEST(YogaTest, absolute_layout_start_top_end_bottom) { } TEST(YogaTest, absolute_layout_width_height_start_top_end_bottom) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeStart, 10); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); @@ -184,24 +323,23 @@ TEST(YogaTest, absolute_layout_width_height_start_top_end_bottom) { YGConfigFree(config); } -TEST( - YogaTest, - do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetOverflow(root, YGOverflowHidden); YGNodeStyleSetWidth(root, 50); YGNodeStyleSetHeight(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 100); YGNodeStyleSetHeight(root_child0_child0, 100); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -245,9 +383,10 @@ TEST( } TEST(YogaTest, absolute_layout_within_border) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeLeft, 10); YGNodeStyleSetMargin(root, YGEdgeTop, 10); YGNodeStyleSetMargin(root, YGEdgeRight, 10); @@ -263,7 +402,7 @@ TEST(YogaTest, absolute_layout_within_border) { YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 0); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 0); @@ -271,7 +410,7 @@ TEST(YogaTest, absolute_layout_within_border) { YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child1, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child1, YGEdgeRight, 0); YGNodeStyleSetPosition(root_child1, YGEdgeBottom, 0); @@ -279,7 +418,7 @@ TEST(YogaTest, absolute_layout_within_border) { YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child2, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child2, YGEdgeLeft, 0); YGNodeStyleSetPosition(root_child2, YGEdgeTop, 0); @@ -291,7 +430,7 @@ TEST(YogaTest, absolute_layout_within_border) { YGNodeStyleSetHeight(root_child2, 50); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child3, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child3, YGEdgeRight, 0); YGNodeStyleSetPosition(root_child3, YGEdgeBottom, 0); @@ -362,16 +501,17 @@ TEST(YogaTest, absolute_layout_within_border) { } TEST(YogaTest, absolute_layout_align_items_and_justify_content_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 60); YGNodeStyleSetHeight(root_child0, 40); @@ -406,16 +546,17 @@ TEST(YogaTest, absolute_layout_align_items_and_justify_content_center) { } TEST(YogaTest, absolute_layout_align_items_and_justify_content_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 60); YGNodeStyleSetHeight(root_child0, 40); @@ -450,15 +591,16 @@ TEST(YogaTest, absolute_layout_align_items_and_justify_content_flex_end) { } TEST(YogaTest, absolute_layout_justify_content_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 60); YGNodeStyleSetHeight(root_child0, 40); @@ -493,15 +635,16 @@ TEST(YogaTest, absolute_layout_justify_content_center) { } TEST(YogaTest, absolute_layout_align_items_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 60); YGNodeStyleSetHeight(root_child0, 40); @@ -536,14 +679,15 @@ TEST(YogaTest, absolute_layout_align_items_center) { } TEST(YogaTest, absolute_layout_align_items_center_on_child_only) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignCenter); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 60); @@ -578,19 +722,18 @@ TEST(YogaTest, absolute_layout_align_items_center_on_child_only) { YGConfigFree(config); } -TEST( - YogaTest, - absolute_layout_align_items_and_justify_content_center_and_top_position) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_top_position) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); YGNodeStyleSetWidth(root_child0, 60); @@ -625,19 +768,18 @@ TEST( YGConfigFree(config); } -TEST( - YogaTest, - absolute_layout_align_items_and_justify_content_center_and_bottom_position) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_bottom_position) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10); YGNodeStyleSetWidth(root_child0, 60); @@ -672,19 +814,18 @@ TEST( YGConfigFree(config); } -TEST( - YogaTest, - absolute_layout_align_items_and_justify_content_center_and_left_position) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_left_position) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 5); YGNodeStyleSetWidth(root_child0, 60); @@ -719,19 +860,18 @@ TEST( YGConfigFree(config); } -TEST( - YogaTest, - absolute_layout_align_items_and_justify_content_center_and_right_position) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_right_position) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 110); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root_child0, YGEdgeRight, 5); YGNodeStyleSetWidth(root_child0, 60); @@ -767,9 +907,10 @@ TEST( } TEST(YogaTest, position_root_with_rtl_should_position_withoutdirection) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPosition(root, YGEdgeLeft, 72); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); @@ -793,27 +934,28 @@ TEST(YogaTest, position_root_with_rtl_should_position_withoutdirection) { } TEST(YogaTest, absolute_layout_percentage_bottom_based_on_parent_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child2, YGPositionTypeAbsolute); YGNodeStyleSetPositionPercent(root_child2, YGEdgeTop, 10); YGNodeStyleSetPositionPercent(root_child2, YGEdgeBottom, 10); @@ -869,14 +1011,15 @@ TEST(YogaTest, absolute_layout_percentage_bottom_based_on_parent_height) { } TEST(YogaTest, absolute_layout_in_wrap_reverse_column_container) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 20); YGNodeStyleSetHeight(root_child0, 20); @@ -911,15 +1054,16 @@ TEST(YogaTest, absolute_layout_in_wrap_reverse_column_container) { } TEST(YogaTest, absolute_layout_in_wrap_reverse_row_container) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 20); YGNodeStyleSetHeight(root_child0, 20); @@ -954,14 +1098,15 @@ TEST(YogaTest, absolute_layout_in_wrap_reverse_row_container) { } TEST(YogaTest, absolute_layout_in_wrap_reverse_column_container_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 20); @@ -997,15 +1142,16 @@ TEST(YogaTest, absolute_layout_in_wrap_reverse_column_container_flex_end) { } TEST(YogaTest, absolute_layout_in_wrap_reverse_row_container_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root_child0, 20); @@ -1039,3 +1185,528 @@ TEST(YogaTest, absolute_layout_in_wrap_reverse_row_container_flex_end) { YGConfigFree(config); } + +TEST(YogaTest, percent_absolute_position_infinite_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 300); + YGNodeInsertChild(root, root_child0, 0); + + 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(0, 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(0, 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)); + + 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(0, 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(0, 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); +} + +TEST(YogaTest, absolute_layout_percentage_height_based_on_padded_parent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 100); + 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(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(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(45, 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(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_percentage_height_based_on_padded_parent_and_align_items_center) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPadding(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 100); + 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_padding_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(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(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)); + + 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_padding_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeRight, 100); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(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(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)); + + 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(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_padding_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeTop, 100); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(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(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(50, 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(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_padding_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(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(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)); + + 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_padding) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + 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, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(220, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, 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)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(220, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, 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)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_border) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + 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, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(220, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, 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)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(220, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, 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)); + + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, absolute_layout_column_reverse_margin_border) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 3); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 4); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 1); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(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(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(8, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, 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(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(143, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGAlignContentTest.cpp b/tests/generated/YGAlignContentTest.cpp new file mode 100644 index 0000000000..b47741344e --- /dev/null +++ b/tests/generated/YGAlignContentTest.cpp @@ -0,0 +1,5557 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAlignContentTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, align_content_flex_start_nowrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_start_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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(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(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, 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(40, 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(90, 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(40, 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(90, 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_wrap_singleline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_start_wrapped_negative_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_start_wrapped_negative_space_gap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeStyleSetGap(root_child0, YGGutterColumn, 10); + YGNodeStyleSetGap(root_child0, YGGutterRow, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_start_without_height_on_children) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + 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); + + 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_nowrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_end_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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(90, 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(90, 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(100, 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(100, 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(110, 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(90, 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(90, 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(100, 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(100, 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(110, 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_end_wrap_singleline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(110, 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(110, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + 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(110, 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(110, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_end_wrapped_negative_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignFlexEnd); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_end_wrapped_negative_space_gap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignFlexEnd); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeStyleSetGap(root_child0, YGGutterColumn, 10); + YGNodeStyleSetGap(root_child0, YGGutterRow, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-70, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-40, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-70, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-40, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_center_nowrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_center_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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(45, 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(45, 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(65, 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(45, 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(45, 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(65, 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_center_wrap_singleline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(55, 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(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + 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(55, 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(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_center_wrapped_negative_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignCenter); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-25, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-25, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_center_wrapped_negative_space_gap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignCenter); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeStyleSetGap(root_child0, YGGutterColumn, 10); + YGNodeStyleSetGap(root_child0, YGGutterRow, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-35, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(-35, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_between_nowrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_between_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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(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(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(110, 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(0, 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(0, 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(110, 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_space_between_wrap_singleline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_between_wrapped_negative_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceBetween); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_between_wrapped_negative_space_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceBetween); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_between_wrapped_negative_space_gap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceBetween); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeStyleSetGap(root_child0, YGGutterColumn, 10); + YGNodeStyleSetGap(root_child0, YGGutterRow, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_nowrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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_space_around_wrap_singleline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(55, 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(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + 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(55, 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(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_wrapped_negative_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceAround); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_wrapped_negative_space_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceAround); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_wrapped_negative_space_gap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceAround); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeStyleSetGap(root_child0, YGGutterColumn, 10); + YGNodeStyleSetGap(root_child0, YGGutterRow, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_nowrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, 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(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)); + + 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(0, 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(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 10); + YGNodeInsertChild(root, root_child3, 3); + + 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(23, 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(23, 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(88, 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(23, 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(23, 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(88, 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_space_evenly_wrap_singleline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 140); + YGNodeStyleSetHeight(root, 120); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(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(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(55, 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(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + 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(55, 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(55, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_wrapped_negative_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceEvenly); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_wrapped_negative_space_gap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 60); + YGNodeStyleSetBorder(root, YGEdgeTop, 60); + YGNodeStyleSetBorder(root, YGEdgeRight, 60); + YGNodeStyleSetBorder(root, YGEdgeBottom, 60); + YGNodeStyleSetWidth(root, 320); + YGNodeStyleSetHeight(root, 320); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0, YGAlignSpaceEvenly); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeStyleSetGap(root_child0, YGGutterColumn, 10); + YGNodeStyleSetGap(root_child0, YGGutterRow, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 80); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child1, 80); + YGNodeStyleSetHeight(root_child0_child1, 20); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child2, 80); + YGNodeStyleSetHeight(root_child0_child2, 20); + YGNodeInsertChild(root_child0, root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_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(320, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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_stretch_row) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + 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); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetFlexBasisPercent(root_child3, 0); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + 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); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + 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); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 60); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetMaxHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetMinHeight(root_child1, 80); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 150); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + 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); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + 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); + + 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); +} + +TEST(YogaTest, align_content_stretch_with_min_cross_axis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMinHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(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(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_with_max_cross_axis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, 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(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_with_max_cross_axis_and_border_padding) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root, YGEdgeTop, 2); + YGNodeStyleSetPadding(root, YGEdgeRight, 2); + YGNodeStyleSetPadding(root, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root, YGEdgeTop, 5); + YGNodeStyleSetBorder(root, YGEdgeRight, 5); + YGNodeStyleSetBorder(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(414, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(207, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(414, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(207, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_min_cross_axis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMinHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(267, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(267, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_max_cross_axis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, 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(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_max_cross_axis_violated) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, 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(400, 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(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_max_cross_axis_violated_padding_and_border) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root, YGEdgeTop, 2); + YGNodeStyleSetPadding(root, YGEdgeRight, 2); + YGNodeStyleSetPadding(root, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root, YGEdgeTop, 5); + YGNodeStyleSetBorder(root, YGEdgeRight, 5); + YGNodeStyleSetBorder(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(207, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(207, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_and_align_items_flex_end_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(88, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(88, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_and_align_items_center_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(63, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(63, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_and_align_items_flex_start_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_flex_start_stretch_doesnt_influence_line_box_dim) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 20); + YGNodeStyleSetPadding(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeRight, 20); + YGNodeStyleSetPadding(root, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root, 400); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child0, 30); + YGNodeStyleSetHeight(root_child1_child0, 30); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child1, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child1, 30); + YGNodeStyleSetHeight(root_child1_child1, 30); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child2, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child2, 30); + YGNodeStyleSetHeight(root_child1_child2, 30); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child3, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child3, 30); + YGNodeStyleSetHeight(root_child1_child3, 30); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + + YGNodeRef root_child1_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child4, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child4, 30); + YGNodeStyleSetHeight(root_child1_child4, 30); + YGNodeInsertChild(root_child1, root_child1_child4, 4); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child2, YGEdgeLeft, 20); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(170, 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(30, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child4)); + + ASSERT_FLOAT_EQ(330, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(260, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child3)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child4)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_stretch_does_influence_line_box_dim) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 20); + YGNodeStyleSetPadding(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeRight, 20); + YGNodeStyleSetPadding(root, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root, 400); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child1, YGAlignStretch); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child0, 30); + YGNodeStyleSetHeight(root_child1_child0, 30); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child1, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child1, 30); + YGNodeStyleSetHeight(root_child1_child1, 30); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child2, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child2, 30); + YGNodeStyleSetHeight(root_child1_child2, 30); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child3, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child3, 30); + YGNodeStyleSetHeight(root_child1_child3, 30); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + + YGNodeRef root_child1_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child4, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child4, 30); + YGNodeStyleSetHeight(root_child1_child4, 30); + YGNodeInsertChild(root_child1, root_child1_child4, 4); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child2, YGEdgeLeft, 20); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(170, 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(30, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child4)); + + ASSERT_FLOAT_EQ(330, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(260, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child3)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child4)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_stretch_does_influence_line_box_dim) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 20); + YGNodeStyleSetPadding(root, YGEdgeTop, 20); + YGNodeStyleSetPadding(root, YGEdgeRight, 20); + YGNodeStyleSetPadding(root, YGEdgeBottom, 20); + YGNodeStyleSetWidth(root, 400); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child1, YGAlignStretch); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child0, 30); + YGNodeStyleSetHeight(root_child1_child0, 30); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child1, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child1, 30); + YGNodeStyleSetHeight(root_child1_child1, 30); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + YGNodeRef root_child1_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child2, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child2, 30); + YGNodeStyleSetHeight(root_child1_child2, 30); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child3, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child3, 30); + YGNodeStyleSetHeight(root_child1_child3, 30); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + + YGNodeRef root_child1_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1_child4, YGEdgeRight, 20); + YGNodeStyleSetWidth(root_child1_child4, 30); + YGNodeStyleSetHeight(root_child1_child4, 30); + YGNodeInsertChild(root_child1, root_child1_child4, 4); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child2, YGEdgeLeft, 20); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(170, 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(30, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child4)); + + ASSERT_FLOAT_EQ(330, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(260, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child3)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1_child4)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child1_child4)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_and_align_items_flex_end_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(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(150, 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(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_and_align_items_flex_start_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, 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(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(175, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(175, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_and_align_items_center_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_and_align_items_stretch_with_flex_wrap) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, 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(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(175, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(175, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGAlignItemsTest.cpp b/tests/generated/YGAlignItemsTest.cpp similarity index 84% rename from tests/YGAlignItemsTest.cpp rename to tests/generated/YGAlignItemsTest.cpp index 2a581da811..4a4f48ecde 100644 --- a/tests/YGAlignItemsTest.cpp +++ b/tests/generated/YGAlignItemsTest.cpp @@ -1,22 +1,27 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<71295a398c89ea424490884a05e2c77c>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAlignItemsTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignItemsTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, align_items_stretch) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -49,14 +54,15 @@ TEST(YogaTest, align_items_stretch) { } TEST(YogaTest, align_items_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -90,14 +96,15 @@ TEST(YogaTest, align_items_center) { } TEST(YogaTest, align_items_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -131,14 +138,15 @@ TEST(YogaTest, align_items_flex_start) { } TEST(YogaTest, align_items_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -172,20 +180,21 @@ TEST(YogaTest, align_items_flex_end) { } TEST(YogaTest, align_baseline) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); @@ -229,25 +238,26 @@ TEST(YogaTest, align_baseline) { } TEST(YogaTest, align_baseline_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child0, 50); YGNodeStyleSetHeight(root_child1_child0, 10); YGNodeInsertChild(root_child1, root_child1_child0, 0); @@ -301,42 +311,43 @@ TEST(YogaTest, align_baseline_child) { } TEST(YogaTest, align_baseline_child_multiline) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child3, 25); YGNodeStyleSetHeight(root_child1_child3, 10); YGNodeInsertChild(root_child1, root_child1_child3, 3); @@ -420,43 +431,44 @@ TEST(YogaTest, align_baseline_child_multiline) { } TEST(YogaTest, align_baseline_child_multiline_override) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child1_child3, YGAlignBaseline); YGNodeStyleSetWidth(root_child1_child3, 25); YGNodeStyleSetHeight(root_child1_child3, 10); @@ -541,42 +553,43 @@ TEST(YogaTest, align_baseline_child_multiline_override) { } TEST(YogaTest, align_baseline_child_multiline_no_override_on_secondline) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child1_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child1_child3, YGAlignBaseline); YGNodeStyleSetWidth(root_child1_child3, 25); YGNodeStyleSetHeight(root_child1_child3, 10); @@ -661,26 +674,27 @@ TEST(YogaTest, align_baseline_child_multiline_no_override_on_secondline) { } TEST(YogaTest, align_baseline_child_top) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child0, 50); YGNodeStyleSetHeight(root_child1_child0, 10); YGNodeInsertChild(root_child1, root_child1_child0, 0); @@ -734,26 +748,27 @@ TEST(YogaTest, align_baseline_child_top) { } TEST(YogaTest, align_baseline_child_top2) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child0, 50); YGNodeStyleSetHeight(root_child1_child0, 10); YGNodeInsertChild(root_child1, root_child1_child0, 0); @@ -807,30 +822,31 @@ TEST(YogaTest, align_baseline_child_top2) { } TEST(YogaTest, align_baseline_double_nested_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child0, 50); YGNodeStyleSetHeight(root_child1_child0, 15); YGNodeInsertChild(root_child1, root_child1_child0, 0); @@ -894,19 +910,20 @@ TEST(YogaTest, align_baseline_double_nested_child) { } TEST(YogaTest, align_baseline_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); @@ -950,15 +967,16 @@ TEST(YogaTest, align_baseline_column) { } TEST(YogaTest, align_baseline_child_margin) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 5); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5); @@ -967,12 +985,12 @@ TEST(YogaTest, align_baseline_child_margin) { YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child1_child0, YGEdgeLeft, 1); YGNodeStyleSetMargin(root_child1_child0, YGEdgeTop, 1); YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 1); @@ -1030,11 +1048,12 @@ TEST(YogaTest, align_baseline_child_margin) { } TEST(YogaTest, align_baseline_child_padding) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPadding(root, YGEdgeLeft, 5); YGNodeStyleSetPadding(root, YGEdgeTop, 5); YGNodeStyleSetPadding(root, YGEdgeRight, 5); @@ -1042,12 +1061,12 @@ TEST(YogaTest, align_baseline_child_padding) { YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetPadding(root_child1, YGEdgeLeft, 5); YGNodeStyleSetPadding(root_child1, YGEdgeTop, 5); YGNodeStyleSetPadding(root_child1, YGEdgeRight, 5); @@ -1056,7 +1075,7 @@ TEST(YogaTest, align_baseline_child_padding) { YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child0, 50); YGNodeStyleSetHeight(root_child1_child0, 10); YGNodeInsertChild(root_child1, root_child1_child0, 0); @@ -1110,41 +1129,42 @@ TEST(YogaTest, align_baseline_child_padding) { } TEST(YogaTest, align_baseline_multiline) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 50); YGNodeStyleSetHeight(root_child3, 50); YGNodeInsertChild(root, root_child3, 3); @@ -1228,40 +1248,43 @@ TEST(YogaTest, align_baseline_multiline) { } TEST(YogaTest, align_baseline_multiline_column) { - const YGConfigRef config = YGConfigNew(); + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 50); YGNodeStyleSetHeight(root_child3, 20); YGNodeInsertChild(root, root_child3, 3); @@ -1314,7 +1337,7 @@ TEST(YogaTest, align_baseline_multiline_column) { 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, YGNodeLayoutGetLeft(root_child1)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); @@ -1324,7 +1347,7 @@ TEST(YogaTest, align_baseline_multiline_column) { 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, YGNodeLayoutGetLeft(root_child2)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); @@ -1345,40 +1368,43 @@ TEST(YogaTest, align_baseline_multiline_column) { } TEST(YogaTest, align_baseline_multiline_column2) { - const YGConfigRef config = YGConfigNew(); + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 50); YGNodeStyleSetHeight(root_child3, 20); YGNodeInsertChild(root, root_child3, 3); @@ -1431,7 +1457,7 @@ TEST(YogaTest, align_baseline_multiline_column2) { 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, YGNodeLayoutGetLeft(root_child1)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); @@ -1441,7 +1467,7 @@ TEST(YogaTest, align_baseline_multiline_column2) { 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, YGNodeLayoutGetLeft(root_child2)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); @@ -1462,41 +1488,42 @@ TEST(YogaTest, align_baseline_multiline_column2) { } TEST(YogaTest, align_baseline_multiline_row_and_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 50); YGNodeStyleSetHeight(root_child3, 20); YGNodeInsertChild(root, root_child3, 3); @@ -1580,19 +1607,20 @@ TEST(YogaTest, align_baseline_multiline_row_and_column) { } TEST(YogaTest, align_items_center_child_with_margin_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignCenter); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 10); YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 10); YGNodeStyleSetWidth(root_child0_child0, 52); @@ -1638,19 +1666,20 @@ TEST(YogaTest, align_items_center_child_with_margin_bigger_than_parent) { } TEST(YogaTest, align_items_flex_end_child_with_margin_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignFlexEnd); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 10); YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 10); YGNodeStyleSetWidth(root_child0_child0, 52); @@ -1696,19 +1725,20 @@ TEST(YogaTest, align_items_flex_end_child_with_margin_bigger_than_parent) { } TEST(YogaTest, align_items_center_child_without_margin_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignCenter); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 72); YGNodeStyleSetHeight(root_child0_child0, 72); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -1752,19 +1782,20 @@ TEST(YogaTest, align_items_center_child_without_margin_bigger_than_parent) { } TEST(YogaTest, align_items_flex_end_child_without_margin_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignFlexEnd); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 72); YGNodeStyleSetHeight(root_child0_child0, 72); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -1808,25 +1839,26 @@ TEST(YogaTest, align_items_flex_end_child_without_margin_bigger_than_parent) { } TEST(YogaTest, align_center_should_size_based_on_content) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeTop, 20); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); @@ -1879,25 +1911,26 @@ TEST(YogaTest, align_center_should_size_based_on_content) { YGConfigFree(config); } -TEST(YogaTest, align_strech_should_size_based_on_parent) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, align_stretch_should_size_based_on_parent) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeTop, 20); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); @@ -1951,22 +1984,23 @@ TEST(YogaTest, align_strech_should_size_based_on_parent) { } TEST(YogaTest, align_flex_start_with_shrinking_children) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); @@ -2020,21 +2054,22 @@ TEST(YogaTest, align_flex_start_with_shrinking_children) { } TEST(YogaTest, align_flex_start_with_stretching_children) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); @@ -2088,22 +2123,23 @@ TEST(YogaTest, align_flex_start_with_stretching_children) { } TEST(YogaTest, align_flex_start_with_shrinking_children_with_stretch) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); @@ -2155,3 +2191,122 @@ TEST(YogaTest, align_flex_start_with_shrinking_children_with_stretch) { YGConfigFree(config); } + +TEST(YogaTest, align_flex_end_with_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 75); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 3); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(3, 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(58, 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, 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(-8, 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, align_stretch_with_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 75); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 3); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(3, 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(58, 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, 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(-8, 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); +} diff --git a/tests/YGAlignSelfTest.cpp b/tests/generated/YGAlignSelfTest.cpp similarity index 85% rename from tests/YGAlignSelfTest.cpp rename to tests/generated/YGAlignSelfTest.cpp index afa3870abd..81da59d6f9 100644 --- a/tests/YGAlignSelfTest.cpp +++ b/tests/generated/YGAlignSelfTest.cpp @@ -1,22 +1,27 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<43d956746b16865dfacb7b25e8fe367f>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAlignSelfTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignSelfTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, align_self_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignCenter); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); @@ -51,13 +56,14 @@ TEST(YogaTest, align_self_center) { } TEST(YogaTest, align_self_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); @@ -92,13 +98,14 @@ TEST(YogaTest, align_self_flex_end) { } TEST(YogaTest, align_self_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); @@ -133,14 +140,15 @@ TEST(YogaTest, align_self_flex_start) { } TEST(YogaTest, align_self_flex_end_override_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexEnd); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); @@ -175,26 +183,27 @@ TEST(YogaTest, align_self_flex_end_override_flex_start) { } TEST(YogaTest, align_self_baseline) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1_child0, 50); YGNodeStyleSetHeight(root_child1_child0, 10); YGNodeInsertChild(root_child1, root_child1_child0, 0); diff --git a/tests/generated/YGAndroidNewsFeed.cpp b/tests/generated/YGAndroidNewsFeed.cpp new file mode 100644 index 0000000000..ce21b45a61 --- /dev/null +++ b/tests/generated/YGAndroidNewsFeed.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<98875d3d64ab8d1a568e81773281be5c>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAndroidNewsFeed.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, android_news_feed) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 1080); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0_child0, YGAlignStretch); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + 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); + + 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); + + 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); + + 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); + + 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); + + 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); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root_child0_child0_child1, YGAlignStretch); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + 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); + + 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); + + 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); + + 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); + + 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); + + 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 --git a/tests/generated/YGAspectRatioTest.cpp b/tests/generated/YGAspectRatioTest.cpp new file mode 100644 index 0000000000..b4f879c993 --- /dev/null +++ b/tests/generated/YGAspectRatioTest.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<0894aa78d01d5194e4c042491128cd1c>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAspectRatioTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, aspect_ratio_does_not_stretch_cross_axis_dim) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetOverflow(root_child0, YGOverflowScroll); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child0, 2); + YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0_child0, 0); + YGNodeStyleSetAspectRatio(root_child0_child0_child0, 1 / 1); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child1, 5); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child2, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child2, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0_child2, 0); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child2_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child2_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0_child2_child0, 0); + YGNodeStyleSetAspectRatio(root_child0_child0_child2_child0, 1 / 1); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + + YGNodeRef root_child0_child0_child2_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child2_child0_child0, 5); + YGNodeInsertChild(root_child0_child0_child2_child0, root_child0_child0_child2_child0_child0, 0); + + YGNodeRef root_child0_child0_child2_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child2_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child2_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0_child2_child0_child1, 0); + YGNodeStyleSetAspectRatio(root_child0_child0_child2_child0_child1, 1 / 1); + YGNodeInsertChild(root_child0_child0_child2_child0, root_child0_child0_child2_child0_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(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(197, 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(197, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child2_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2_child0_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child0_child0_child2_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child2_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child2_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2_child0_child1)); + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetWidth(root_child0_child0_child2_child0_child1)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child2_child0_child1)); + + 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(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(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(103, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child0_child0_child2_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2_child0_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child0_child0_child2_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0_child2_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child2_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child2_child0_child1)); + ASSERT_FLOAT_EQ(98, YGNodeLayoutGetWidth(root_child0_child0_child2_child0_child1)); + ASSERT_FLOAT_EQ(197, YGNodeLayoutGetHeight(root_child0_child0_child2_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, zero_aspect_ratio_behaves_like_auto) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetAspectRatio(root_child0, 0 / 1); + 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(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(50, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGAutoTest.cpp b/tests/generated/YGAutoTest.cpp new file mode 100644 index 0000000000..e1426a7c92 --- /dev/null +++ b/tests/generated/YGAutoTest.cpp @@ -0,0 +1,311 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<00e4ee58a2a66a3fcd064d3c517d8330>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAutoTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, auto_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidthAuto(root); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + 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(150, 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(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)); + + 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(50, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, auto_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeightAuto(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + 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(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_child1)); + ASSERT_FLOAT_EQ(50, 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(100, 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(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_child1)); + ASSERT_FLOAT_EQ(50, 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(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, auto_flex_basis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + 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(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_child1)); + ASSERT_FLOAT_EQ(50, 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(100, 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(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_child1)); + ASSERT_FLOAT_EQ(50, 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(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, auto_position) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 25); + YGNodeStyleSetHeight(root_child0, 25); + 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(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(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_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(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, auto_margin) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 50); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetWidth(root_child0, 25); + YGNodeStyleSetHeight(root_child0, 25); + 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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_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(25, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGBorderTest.cpp b/tests/generated/YGBorderTest.cpp similarity index 84% rename from tests/YGBorderTest.cpp rename to tests/generated/YGBorderTest.cpp index 3931821445..b775e8af89 100644 --- a/tests/YGBorderTest.cpp +++ b/tests/generated/YGBorderTest.cpp @@ -1,18 +1,23 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<6b9e472d3a0bac5e3a5501788c9971c6>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGBorderTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGBorderTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, border_no_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetBorder(root, YGEdgeLeft, 10); YGNodeStyleSetBorder(root, YGEdgeTop, 10); YGNodeStyleSetBorder(root, YGEdgeRight, 10); @@ -37,15 +42,16 @@ TEST(YogaTest, border_no_size) { } TEST(YogaTest, border_container_match_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetBorder(root, YGEdgeLeft, 10); YGNodeStyleSetBorder(root, YGEdgeTop, 10); YGNodeStyleSetBorder(root, YGEdgeRight, 10); YGNodeStyleSetBorder(root, YGEdgeBottom, 10); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -79,9 +85,10 @@ TEST(YogaTest, border_container_match_child) { } TEST(YogaTest, border_flex_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetBorder(root, YGEdgeLeft, 10); YGNodeStyleSetBorder(root, YGEdgeTop, 10); YGNodeStyleSetBorder(root, YGEdgeRight, 10); @@ -89,7 +96,7 @@ TEST(YogaTest, border_flex_child) { YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -123,9 +130,10 @@ TEST(YogaTest, border_flex_child) { } TEST(YogaTest, border_stretch_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetBorder(root, YGEdgeLeft, 10); YGNodeStyleSetBorder(root, YGEdgeTop, 10); YGNodeStyleSetBorder(root, YGEdgeRight, 10); @@ -133,7 +141,7 @@ TEST(YogaTest, border_stretch_child) { YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -166,18 +174,19 @@ TEST(YogaTest, border_stretch_child) { } TEST(YogaTest, border_center_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetBorder(root, YGEdgeStart, 10); YGNodeStyleSetBorder(root, YGEdgeEnd, 20); YGNodeStyleSetBorder(root, YGEdgeBottom, 20); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); diff --git a/tests/generated/YGBoxSizingTest.cpp b/tests/generated/YGBoxSizingTest.cpp new file mode 100644 index 0000000000..e7ee6643f4 --- /dev/null +++ b/tests/generated/YGBoxSizingTest.cpp @@ -0,0 +1,2543 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<24bf988fec7e7f72a8f46ba74df63399>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGBoxSizingTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, box_sizing_content_box_simple) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + 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(130, YGNodeLayoutGetHeight(root)); + + 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(130, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_simple) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 4); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 4); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 16); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 16); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 16); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 16); + YGNodeStyleSetWidthPercent(root_child0, 50); + YGNodeStyleSetHeightPercent(root_child0, 25); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, 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(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 4); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 4); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 16); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 16); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 16); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 16); + YGNodeStyleSetWidthPercent(root_child0, 50); + YGNodeStyleSetHeightPercent(root_child0, 25); + 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(40, 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(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_absolute) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 12); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 12); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 12); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 12); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetHeightPercent(root_child0, 25); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, 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(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_absolute) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 12); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 12); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 12); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 12); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetHeightPercent(root_child0, 25); + 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(40, 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_comtaining_block) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 12); + YGNodeStyleSetPadding(root, YGEdgeTop, 12); + YGNodeStyleSetPadding(root, YGEdgeRight, 12); + YGNodeStyleSetPadding(root, YGEdgeBottom, 12); + YGNodeStyleSetBorder(root, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root, YGEdgeTop, 8); + YGNodeStyleSetBorder(root, YGEdgeRight, 8); + YGNodeStyleSetBorder(root, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeightPercent(root_child0_child0, 25); + 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(140, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, 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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(31, YGNodeLayoutGetHeight(root_child0_child0)); + + 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(140, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, 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(31, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_comtaining_block) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 12); + YGNodeStyleSetPadding(root, YGEdgeTop, 12); + YGNodeStyleSetPadding(root, YGEdgeRight, 12); + YGNodeStyleSetPadding(root, YGEdgeBottom, 12); + YGNodeStyleSetBorder(root, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root, YGEdgeTop, 8); + YGNodeStyleSetBorder(root, YGEdgeRight, 8); + YGNodeStyleSetBorder(root, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeightPercent(root_child0_child0, 25); + 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(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, 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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(21, 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(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_padding_only) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + 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(110, YGNodeLayoutGetHeight(root)); + + 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(110, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_padding_only_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 150); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeRight, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 75); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(150, 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(95, 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(150, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(95, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_padding_only) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_padding_only_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 150); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeRight, 10); + YGNodeStyleSetPaddingPercent(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 75); + 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(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(75, 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(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(75, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_border_only) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + 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(120, YGNodeLayoutGetHeight(root)); + + 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(120, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_border_only_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(0, 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(0, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_border_only) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_border_only_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(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(50, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_no_padding_no_border) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + 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)); + + 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_no_padding_no_border) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_children) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 25); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + YGNodeStyleSetHeight(root_child2, 25); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 25); + YGNodeStyleSetHeight(root_child3, 25); + 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(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child3)); + + 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(130, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_children) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root, YGEdgeTop, 10); + YGNodeStyleSetBorder(root, YGEdgeRight, 10); + YGNodeStyleSetBorder(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 25); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + YGNodeStyleSetHeight(root_child2, 25); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 25); + YGNodeStyleSetHeight(root_child3, 25); + 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(15, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, 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(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_siblings) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 25); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeInsertChild(root, root_child0, 0); + + 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); + YGNodeStyleSetBorder(root_child1, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child1, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child1, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child1, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeStyleSetBoxSizing(root_child1, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + YGNodeStyleSetHeight(root_child2, 25); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 25); + YGNodeStyleSetHeight(root_child3, 25); + 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(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(115, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, 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(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(115, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_siblings) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 25); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeInsertChild(root, root_child0, 0); + + 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); + YGNodeStyleSetBorder(root_child1, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child1, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child1, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child1, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + YGNodeStyleSetHeight(root_child2, 25); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 25); + YGNodeStyleSetHeight(root_child3, 25); + 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(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, 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(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_max_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetMaxWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(90, 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(25, 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(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_max_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetMaxWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, 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(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(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_max_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetMaxHeight(root_child0, 50); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(90, 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(25, 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(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_max_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetMaxHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, 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(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(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_min_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetMinWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, 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(65, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_min_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetMinWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, 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(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_min_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetMinHeight(root_child0, 50); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, 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(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_min_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 15); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 15); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetMinHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 25); + YGNodeStyleSetHeight(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(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(25, 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(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(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_no_height_no_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 7); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(18, 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(18, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_no_height_no_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 7); + 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(18, 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(18, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_nested) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 15); + YGNodeStyleSetPadding(root, YGEdgeTop, 15); + YGNodeStyleSetPadding(root, YGEdgeRight, 15); + YGNodeStyleSetPadding(root, YGEdgeBottom, 15); + YGNodeStyleSetBorder(root, YGEdgeLeft, 3); + YGNodeStyleSetBorder(root, YGEdgeTop, 3); + YGNodeStyleSetBorder(root, YGEdgeRight, 3); + YGNodeStyleSetBorder(root, YGEdgeBottom, 3); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 7); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 5); + YGNodeStyleSetBoxSizing(root_child0_child0, YGBoxSizingContentBox); + 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(136, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(136, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(136, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(136, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(13, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_nested) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 15); + YGNodeStyleSetPadding(root, YGEdgeTop, 15); + YGNodeStyleSetPadding(root, YGEdgeRight, 15); + YGNodeStyleSetPadding(root, YGEdgeBottom, 15); + YGNodeStyleSetBorder(root, YGEdgeLeft, 3); + YGNodeStyleSetBorder(root, YGEdgeTop, 3); + YGNodeStyleSetBorder(root, YGEdgeRight, 3); + YGNodeStyleSetBorder(root, YGEdgeBottom, 3); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 7); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 5); + 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(18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(6, 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(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(6, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_nested_alternating) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root, YGEdgeTop, 3); + YGNodeStyleSetPadding(root, YGEdgeRight, 3); + YGNodeStyleSetPadding(root, YGEdgeBottom, 3); + YGNodeStyleSetBorder(root, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root, YGEdgeTop, 2); + YGNodeStyleSetBorder(root, YGEdgeRight, 2); + YGNodeStyleSetBorder(root, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 3); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 6); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 6); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 6); + YGNodeStyleSetWidth(root_child0_child0, 20); + YGNodeStyleSetHeight(root_child0_child0, 25); + YGNodeStyleSetBoxSizing(root_child0_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 1); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0_child0, 5); + 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(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(43, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(5, 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(110, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-8, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(43, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(19, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_nested_alternating) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root, YGEdgeTop, 3); + YGNodeStyleSetPadding(root, YGEdgeRight, 3); + YGNodeStyleSetPadding(root, YGEdgeBottom, 3); + YGNodeStyleSetBorder(root, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root, YGEdgeTop, 2); + YGNodeStyleSetBorder(root, YGEdgeRight, 2); + YGNodeStyleSetBorder(root, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeStyleSetHeight(root_child0, 40); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 3); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 6); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 6); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 6); + YGNodeStyleSetWidth(root_child0_child0, 20); + YGNodeStyleSetHeight(root_child0_child0, 25); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 1); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0_child0, 5); + YGNodeStyleSetBoxSizing(root_child0_child0_child0, YGBoxSizingContentBox); + 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(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(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(14, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(9, 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(35, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-3, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(14, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_flex_basis_row) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(55, 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(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_flex_basis_row) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetHeight(root_child0, 25); + 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(30, 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(30, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_flex_basis_column) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetHeight(root_child0, 25); + YGNodeStyleSetBoxSizing(root_child0, YGBoxSizingContentBox); + 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(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(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_flex_basis_column) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexBasis(root_child0, 50); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 10); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetHeight(root_child0, 25); + 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(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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_padding_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeStart, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(105, 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(105, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_padding_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeStart, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_padding_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeEnd, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(105, 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(105, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_padding_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeEnd, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_border_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeStart, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(105, 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(105, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_border_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeStart, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_content_box_border_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeEnd, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(105, 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(105, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, box_sizing_border_box_border_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeEnd, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(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(100, 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(100, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGDimensionTest.cpp b/tests/generated/YGDimensionTest.cpp similarity index 80% rename from tests/YGDimensionTest.cpp rename to tests/generated/YGDimensionTest.cpp index c4e50718e1..829f2b6a80 100644 --- a/tests/YGDimensionTest.cpp +++ b/tests/generated/YGDimensionTest.cpp @@ -1,20 +1,25 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<029b6e60daca98deb68e91f06cbd8c76>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGDimensionTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGDimensionTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, wrap_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); @@ -48,14 +53,15 @@ TEST(YogaTest, wrap_child) { } TEST(YogaTest, wrap_grandchild) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 100); YGNodeStyleSetHeight(root_child0_child0, 100); YGNodeInsertChild(root_child0, root_child0_child0, 0); diff --git a/tests/generated/YGDisplayContentsTest.cpp b/tests/generated/YGDisplayContentsTest.cpp new file mode 100644 index 0000000000..a619d14577 --- /dev/null +++ b/tests/generated/YGDisplayContentsTest.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayContentsTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, test1) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child1, 20); + 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(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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, 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(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(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGDisplayTest.cpp b/tests/generated/YGDisplayTest.cpp new file mode 100644 index 0000000000..ec6f805ed1 --- /dev/null +++ b/tests/generated/YGDisplayTest.cpp @@ -0,0 +1,1025 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGDisplayTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, display_none) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + 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); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + + 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); + + 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); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + 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); +} + +TEST(YogaTest, display_none_with_position_absolute) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeStyleSetDisplay(root_child0, YGDisplayNone); + 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(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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child1, 20); + 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(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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, 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(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(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents_fixed_size) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child1, 20); + 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(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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, 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(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(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents_with_margin) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + 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, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + 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_contents_with_padding) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 10); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child1, 20); + 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(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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, 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(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(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents_with_position) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child1, 20); + 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(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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, 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(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(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents_with_position_absolute) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child1, 20); + 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(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(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, 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(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(50, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents_nested) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetDisplay(root_child0, YGDisplayContents); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetDisplay(root_child0_child0, YGDisplayContents); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child0, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0_child0, 0); + YGNodeStyleSetHeight(root_child0_child0_child0, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0_child0_child1, 1); + YGNodeStyleSetFlexShrink(root_child0_child0_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child0_child0_child1, 0); + YGNodeStyleSetHeight(root_child0_child0_child1, 20); + 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(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)); + + 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(10, 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(20, 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(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)); + + 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(10, 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(20, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, display_contents_with_siblings) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetHeight(root_child0, 30); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetDisplay(root_child1, YGDisplayContents); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child0, 1); + YGNodeStyleSetFlexShrink(root_child1_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child1_child0, 0); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + YGNodeRef root_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1_child1, 1); + YGNodeStyleSetFlexShrink(root_child1_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1_child1, 0); + YGNodeStyleSetHeight(root_child1_child1, 20); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetFlexShrink(root_child2, 1); + YGNodeStyleSetFlexBasisPercent(root_child2, 0); + YGNodeStyleSetHeight(root_child2, 30); + 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(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, 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(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, 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(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, 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(50, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, 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(20, YGNodeLayoutGetHeight(root_child1_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(30, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGFlexDirectionTest.cpp b/tests/generated/YGFlexDirectionTest.cpp new file mode 100644 index 0000000000..d7b249dede --- /dev/null +++ b/tests/generated/YGFlexDirectionTest.cpp @@ -0,0 +1,4330 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<52e047e144a63ab101701faf9b0cf06d>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGFlexDirectionTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, flex_direction_column_no_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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); +} + +TEST(YogaTest, flex_direction_row_reverse_margin_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(100, 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(100, 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); +} + +TEST(YogaTest, flex_direction_row_reverse_margin_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root, YGEdgeStart, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 10); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(100, 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); +} + +TEST(YogaTest, flex_direction_row_reverse_margin_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root, YGEdgeRight, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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); +} + +TEST(YogaTest, flex_direction_row_reverse_margin_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root, YGEdgeEnd, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, 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); +} + +TEST(YogaTest, flex_direction_column_reverse_margin_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root, YGEdgeTop, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, 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(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_column_reverse_margin_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, 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(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_padding_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, 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(110, 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(120, 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_row_reverse_padding_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeStart, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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); +} + +TEST(YogaTest, flex_direction_row_reverse_padding_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeRight, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(-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)); + + ASSERT_FLOAT_EQ(-20, 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(-30, 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); +} + +TEST(YogaTest, flex_direction_row_reverse_padding_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeEnd, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(-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)); + + ASSERT_FLOAT_EQ(-20, 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(-30, 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(100, 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(110, 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(120, 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_padding_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeTop, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, 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(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_column_reverse_padding_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, 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(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, 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(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_border_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, 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(110, 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(120, 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_row_reverse_border_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeStart, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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); +} + +TEST(YogaTest, flex_direction_row_reverse_border_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeRight, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(-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)); + + ASSERT_FLOAT_EQ(-20, 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(-30, 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); +} + +TEST(YogaTest, flex_direction_row_reverse_border_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeEnd, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(-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)); + + ASSERT_FLOAT_EQ(-20, 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(-30, 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(100, 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(110, 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(120, 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_border_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeTop, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, 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(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_column_reverse_border_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 10); + YGNodeInsertChild(root, root_child1, 1); + + 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(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, 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(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, 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(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_pos_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(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(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(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(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_pos_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetPosition(root_child0, YGEdgeStart, 100); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(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(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(-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(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_pos_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, 100); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(-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(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(-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(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_pos_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetPosition(root_child0, YGEdgeEnd, 100); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(-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(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(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(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_column_reverse_pos_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 100); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, 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(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, 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(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_column_reverse_pos_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(-100, 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(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(-100, 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(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_pos_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_pos_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_pos_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_pos_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_pos_start) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeStart, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_pos_end) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0, YGEdgeEnd, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_margin_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_margin_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_margin_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_margin_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_marign_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeStart, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_margin_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeEnd, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(10, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_border_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_border_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_border_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_border_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_border_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_border_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_padding_left) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_padding_right) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_padding_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_col_reverse_inner_padding_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_padding_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeStart, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_row_reverse_inner_padding_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeEnd, 10); + YGNodeStyleSetWidth(root_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0, 10); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 10); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 10); + YGNodeInsertChild(root_child0, root_child0_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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(90, 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)); + + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_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(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, flex_direction_alternating_with_percent) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPositionPercent(root_child0, YGEdgeTop, 10); + 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(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGFlexTest.cpp b/tests/generated/YGFlexTest.cpp similarity index 74% rename from tests/YGFlexTest.cpp rename to tests/generated/YGFlexTest.cpp index 3066ac28aa..965b31453e 100644 --- a/tests/YGFlexTest.cpp +++ b/tests/generated/YGFlexTest.cpp @@ -1,27 +1,32 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<66f3152eedefd8718b50d16ea931e255>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGFlexTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, flex_basis_flex_grow_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -64,20 +69,21 @@ TEST(YogaTest, flex_basis_flex_grow_column) { } TEST(YogaTest, flex_shrink_flex_grow_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetWidth(root_child0, 500); YGNodeStyleSetHeight(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child1, 1); YGNodeStyleSetWidth(root_child1, 500); YGNodeStyleSetHeight(root_child1, 100); @@ -122,20 +128,21 @@ TEST(YogaTest, flex_shrink_flex_grow_row) { } TEST(YogaTest, flex_shrink_flex_grow_child_flex_shrink_other_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetWidth(root_child0, 500); YGNodeStyleSetHeight(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetFlexShrink(root_child1, 1); YGNodeStyleSetWidth(root_child1, 500); @@ -181,19 +188,20 @@ TEST(YogaTest, flex_shrink_flex_grow_child_flex_shrink_other_child) { } TEST(YogaTest, flex_basis_flex_grow_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -236,18 +244,19 @@ TEST(YogaTest, flex_basis_flex_grow_row) { } TEST(YogaTest, flex_basis_flex_shrink_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasis(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -290,19 +299,20 @@ TEST(YogaTest, flex_basis_flex_shrink_column) { } TEST(YogaTest, flex_basis_flex_shrink_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasis(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -345,23 +355,24 @@ TEST(YogaTest, flex_basis_flex_shrink_row) { } TEST(YogaTest, flex_shrink_to_zero) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetHeight(root, 75); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 50); YGNodeStyleSetHeight(root_child2, 50); YGNodeInsertChild(root, root_child2, 2); @@ -415,24 +426,25 @@ TEST(YogaTest, flex_shrink_to_zero) { } TEST(YogaTest, flex_basis_overrides_main_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -486,16 +498,17 @@ TEST(YogaTest, flex_basis_overrides_main_size) { } TEST(YogaTest, flex_grow_shrink_at_most) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0_child0, 1); YGNodeStyleSetFlexShrink(root_child0_child0, 1); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -539,23 +552,24 @@ TEST(YogaTest, flex_grow_shrink_at_most) { } TEST(YogaTest, flex_grow_less_than_factor_one) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexGrow(root_child0, 0.2); + 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.2); + 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.4); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 0.4f); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -605,121 +619,3 @@ TEST(YogaTest, flex_grow_less_than_factor_one) { YGConfigFree(config); } - -TEST(YogaTest, flex_shrink_min_width) { - const YGConfigRef config = YGConfigNew(); - YGConfigSetUseWebDefaults(config, true); - - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); - YGNodeStyleSetWidth(root, 500); - YGNodeStyleSetHeight(root, 500); - - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); - YGNodeStyleSetWidth(root_child0, 100); - YGNodeStyleSetMinWidth(root_child0, 301); - YGNodeStyleSetHeight(root_child0, 100); - YGNodeInsertChild(root, root_child0, 0); - - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); - YGNodeStyleSetWidth(root_child1, 100); - YGNodeStyleSetMinWidth(root_child1, 25); - YGNodeStyleSetHeight(root_child1, 100); - YGNodeInsertChild(root, root_child1, 1); - - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child2, YGFlexDirectionRow); - 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(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(301, YGNodeLayoutGetWidth(root_child0)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); - - ASSERT_FLOAT_EQ(301, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); - - ASSERT_FLOAT_EQ(401, YGNodeLayoutGetLeft(root_child2)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); - ASSERT_FLOAT_EQ(99, YGNodeLayoutGetWidth(root_child2)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); - - YGNodeFreeRecursive(root); - - YGConfigFree(config); -} - -TEST(YogaTest, flex_shrink_flex_grow_min_width) { - const YGConfigRef config = YGConfigNew(); - YGConfigSetUseWebDefaults(config, true); - - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); - YGNodeStyleSetWidth(root, 500); - YGNodeStyleSetHeight(root, 500); - - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); - YGNodeStyleSetFlexGrow(root_child0, 0); - YGNodeStyleSetFlexShrink(root_child0, 1); - YGNodeStyleSetWidth(root_child0, 100); - YGNodeStyleSetMinWidth(root_child0, 301); - YGNodeStyleSetHeight(root_child0, 100); - YGNodeInsertChild(root, root_child0, 0); - - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); - YGNodeStyleSetFlexGrow(root_child1, 1); - YGNodeStyleSetFlexShrink(root_child1, 1); - YGNodeStyleSetWidth(root_child1, 100); - YGNodeStyleSetMinWidth(root_child1, 25); - YGNodeStyleSetHeight(root_child1, 100); - YGNodeInsertChild(root, root_child1, 1); - - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child2, YGFlexDirectionRow); - YGNodeStyleSetWidth(root_child2, 100); - YGNodeStyleSetHeight(root_child2, 100); - YGNodeStyleSetFlexShrink(root_child2, 1); - 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(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(301, YGNodeLayoutGetWidth(root_child0)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); - - ASSERT_FLOAT_EQ(301, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); - - ASSERT_FLOAT_EQ(401, YGNodeLayoutGetLeft(root_child2)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); - ASSERT_FLOAT_EQ(99, YGNodeLayoutGetWidth(root_child2)); - ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); - - YGNodeFreeRecursive(root); - - YGConfigFree(config); -} diff --git a/tests/YGFlexWrapTest.cpp b/tests/generated/YGFlexWrapTest.cpp similarity index 80% rename from tests/YGFlexWrapTest.cpp rename to tests/generated/YGFlexWrapTest.cpp index 38a9c51e90..3c08361fa7 100644 --- a/tests/YGFlexWrapTest.cpp +++ b/tests/generated/YGFlexWrapTest.cpp @@ -1,37 +1,42 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<736016d0832b2cf628b204cca95e0141>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGFlexWrapTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGFlexWrapTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, wrap_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 30); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 30); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 30); YGNodeInsertChild(root, root_child3, 3); @@ -95,29 +100,30 @@ TEST(YogaTest, wrap_column) { } TEST(YogaTest, wrap_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 30); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 30); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 30); YGNodeInsertChild(root, root_child3, 3); @@ -181,30 +187,31 @@ TEST(YogaTest, wrap_row) { } TEST(YogaTest, wrap_row_align_items_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 30); YGNodeInsertChild(root, root_child3, 3); @@ -268,30 +275,31 @@ TEST(YogaTest, wrap_row_align_items_flex_end) { } TEST(YogaTest, wrap_row_align_items_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 30); YGNodeInsertChild(root, root_child3, 3); @@ -355,20 +363,21 @@ TEST(YogaTest, wrap_row_align_items_center) { } TEST(YogaTest, flex_wrap_children_with_min_main_overriding_flex_basis) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasis(root_child1, 50); YGNodeStyleSetMinWidth(root_child1, 55); YGNodeStyleSetHeight(root_child1, 50); @@ -413,26 +422,27 @@ TEST(YogaTest, flex_wrap_children_with_min_main_overriding_flex_basis) { } TEST(YogaTest, flex_wrap_wrap_to_child_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 100); YGNodeStyleSetHeight(root_child1, 100); YGNodeInsertChild(root, root_child1, 1); @@ -496,19 +506,20 @@ TEST(YogaTest, flex_wrap_wrap_to_child_height) { } TEST(YogaTest, flex_wrap_align_stretch_fits_one_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 150); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -551,34 +562,35 @@ TEST(YogaTest, flex_wrap_align_stretch_fits_one_row) { } TEST(YogaTest, wrap_reverse_row_align_content_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 40); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child4, 30); YGNodeStyleSetHeight(root_child4, 50); YGNodeInsertChild(root, root_child4, 4); @@ -652,35 +664,36 @@ TEST(YogaTest, wrap_reverse_row_align_content_flex_start) { } TEST(YogaTest, wrap_reverse_row_align_content_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 40); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child4, 30); YGNodeStyleSetHeight(root_child4, 50); YGNodeInsertChild(root, root_child4, 4); @@ -754,34 +767,35 @@ TEST(YogaTest, wrap_reverse_row_align_content_center) { } TEST(YogaTest, wrap_reverse_row_single_line_different_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 300); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 40); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child4, 30); YGNodeStyleSetHeight(root_child4, 50); YGNodeInsertChild(root, root_child4, 4); @@ -855,35 +869,36 @@ TEST(YogaTest, wrap_reverse_row_single_line_different_size) { } TEST(YogaTest, wrap_reverse_row_align_content_stretch) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 40); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child4, 30); YGNodeStyleSetHeight(root_child4, 50); YGNodeInsertChild(root, root_child4, 4); @@ -957,35 +972,36 @@ TEST(YogaTest, wrap_reverse_row_align_content_stretch) { } TEST(YogaTest, wrap_reverse_row_align_content_space_around) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 40); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child4, 30); YGNodeStyleSetHeight(root_child4, 50); YGNodeInsertChild(root, root_child4, 4); @@ -1059,35 +1075,36 @@ TEST(YogaTest, wrap_reverse_row_align_content_space_around) { } TEST(YogaTest, wrap_reverse_column_fixed_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrapReverse); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 30); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 30); YGNodeStyleSetHeight(root_child1, 20); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 30); YGNodeStyleSetHeight(root_child2, 30); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child3, 30); YGNodeStyleSetHeight(root_child3, 40); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child4, 30); YGNodeStyleSetHeight(root_child4, 50); YGNodeInsertChild(root, root_child4, 4); @@ -1161,24 +1178,25 @@ TEST(YogaTest, wrap_reverse_column_fixed_size) { } TEST(YogaTest, wrapped_row_within_align_items_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child1, 80); YGNodeStyleSetHeight(root_child0_child1, 80); YGNodeInsertChild(root_child0, root_child0_child1, 1); @@ -1232,24 +1250,25 @@ TEST(YogaTest, wrapped_row_within_align_items_center) { } TEST(YogaTest, wrapped_row_within_align_items_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child1, 80); YGNodeStyleSetHeight(root_child0_child1, 80); YGNodeInsertChild(root_child0, root_child0_child1, 1); @@ -1303,24 +1322,25 @@ TEST(YogaTest, wrapped_row_within_align_items_flex_start) { } TEST(YogaTest, wrapped_row_within_align_items_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child1, 80); YGNodeStyleSetHeight(root_child0_child1, 80); YGNodeInsertChild(root_child0, root_child0_child1, 1); @@ -1374,23 +1394,24 @@ TEST(YogaTest, wrapped_row_within_align_items_flex_end) { } TEST(YogaTest, wrapped_column_max_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignContent(root, YGAlignCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 700); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child1, YGEdgeLeft, 20); YGNodeStyleSetMargin(root_child1, YGEdgeTop, 20); YGNodeStyleSetMargin(root_child1, YGEdgeRight, 20); @@ -1399,7 +1420,7 @@ TEST(YogaTest, wrapped_column_max_height) { YGNodeStyleSetHeight(root_child1, 200); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 100); YGNodeStyleSetHeight(root_child2, 100); YGNodeInsertChild(root, root_child2, 2); @@ -1453,17 +1474,18 @@ TEST(YogaTest, wrapped_column_max_height) { } TEST(YogaTest, wrapped_column_max_height_flex) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignContent(root, YGAlignCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexWrap(root, YGWrapWrap); YGNodeStyleSetWidth(root, 700); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetFlexBasisPercent(root_child0, 0); @@ -1472,7 +1494,7 @@ TEST(YogaTest, wrapped_column_max_height_flex) { YGNodeStyleSetMaxHeight(root_child0, 200); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetFlexShrink(root_child1, 1); YGNodeStyleSetFlexBasisPercent(root_child1, 0); @@ -1484,7 +1506,7 @@ TEST(YogaTest, wrapped_column_max_height_flex) { YGNodeStyleSetHeight(root_child1, 200); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 100); YGNodeStyleSetHeight(root_child2, 100); YGNodeInsertChild(root, root_child2, 2); @@ -1538,31 +1560,32 @@ TEST(YogaTest, wrapped_column_max_height_flex) { } TEST(YogaTest, wrap_nodes_with_content_sizing_overflowing_margin) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root_child0, root_child0_child0, 0); - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); @@ -1636,31 +1659,32 @@ TEST(YogaTest, wrap_nodes_with_content_sizing_overflowing_margin) { } TEST(YogaTest, wrap_nodes_with_content_sizing_margin_cross) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root_child0, root_child0_child0, 0); - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); @@ -1732,3 +1756,204 @@ TEST(YogaTest, wrap_nodes_with_content_sizing_margin_cross) { YGConfigFree(config); } + +TEST(YogaTest, wrap_with_min_cross_axis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMinHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(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(400, 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(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, wrap_with_max_cross_axis) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, 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(400, 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, nowrap_expands_flexline_box_to_min_cross) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinHeight(root, 400); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + 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(400, 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(400, 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(400, 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(400, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, wrap_does_not_impose_min_cross_onto_single_flexline) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetMinHeight(root, 400); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + 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(400, 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(400, 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); +} diff --git a/tests/generated/YGGapTest.cpp b/tests/generated/YGGapTest.cpp new file mode 100644 index 0000000000..e459a40325 --- /dev/null +++ b/tests/generated/YGGapTest.cpp @@ -0,0 +1,3157 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGGapTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, column_gap_flexible) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 80); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeInsertChild(root, root_child1, 1); + + 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(80, 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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_inflexible) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 80); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(80, 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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_mixed_flexible) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 80); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(80, 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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_child_margins) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 80); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 2); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetMargin(root_child1, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root_child1, YGEdgeRight, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetFlexShrink(root_child2, 1); + YGNodeStyleSetFlexBasisPercent(root_child2, 0); + YGNodeStyleSetMargin(root_child2, YGEdgeLeft, 15); + YGNodeStyleSetMargin(root_child2, YGEdgeRight, 15); + 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(26, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(63, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(2, 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(76, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_row_gap_wrapping) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 80); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeStyleSetHeight(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeStyleSetHeight(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + + YGNodeRef root_child6 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child6, 20); + YGNodeStyleSetHeight(root_child6, 20); + YGNodeInsertChild(root, root_child6, 6); + + YGNodeRef root_child7 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child7, 20); + YGNodeStyleSetHeight(root_child7, 20); + YGNodeInsertChild(root, root_child7, 7); + + YGNodeRef root_child8 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child8, 20); + YGNodeStyleSetHeight(root_child8, 20); + YGNodeInsertChild(root, root_child8, 8); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, 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)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child6)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child6)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child6)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child6)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child7)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child7)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child7)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child7)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child8)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child8)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child8)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child8)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, 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(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child6)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child6)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child6)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child6)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child7)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child7)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child7)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child7)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child8)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child8)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child8)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child8)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_start_index) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 80); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, 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(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_justify_flex_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, 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(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_justify_center) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, 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(70, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_justify_flex_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_justify_space_between) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_justify_space_around) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(3, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(77, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(77, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(3, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_justify_space_evenly) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_wrap_align_flex_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeStyleSetHeight(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeStyleSetHeight(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + 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)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_wrap_align_center) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeStyleSetHeight(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeStyleSetHeight(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + 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(20, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_wrap_align_flex_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeStyleSetHeight(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeStyleSetHeight(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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(40, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + 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(40, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_wrap_align_space_between) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeStyleSetHeight(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeStyleSetHeight(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + 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)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_wrap_align_space_around) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeStyleSetHeight(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeStyleSetHeight(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_wrap_align_stretch) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + YGNodeStyleSetGap(root, YGGutterColumn, 5); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetMinWidth(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetMinWidth(root_child1, 60); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetMinWidth(root_child2, 60); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetMinWidth(root_child3, 60); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child4, 1); + YGNodeStyleSetMinWidth(root_child4, 60); + 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(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(76, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(153, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(229, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(150, 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(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(229, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(153, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(76, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_gap_determines_parent_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 30); + 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(80, 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(20, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(30, 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(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(70, 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(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, 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(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_align_items_stretch) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child5)); + + 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_align_items_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetGap(root, YGGutterColumn, 10); + YGNodeStyleSetGap(root, YGGutterRow, 20); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 20); + YGNodeInsertChild(root, root_child4, 4); + + YGNodeRef root_child5 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child5, 20); + YGNodeInsertChild(root, root_child5, 5); + 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child5)); + + 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child5)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child5)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child5)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_column_child_margins) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetGap(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 2); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 2); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeStyleSetMargin(root_child1, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child1, YGEdgeBottom, 10); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child2, 1); + YGNodeStyleSetFlexShrink(root_child2, 1); + YGNodeStyleSetFlexBasisPercent(root_child2, 0); + YGNodeStyleSetMargin(root_child2, YGEdgeTop, 15); + YGNodeStyleSetMargin(root_child2, YGEdgeBottom, 15); + 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(2, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(42, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(66, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(42, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(143, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(42, 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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(42, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(66, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(42, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(143, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(42, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_row_wrap_child_margins) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetGap(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 2); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 2); + YGNodeStyleSetWidth(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child1, YGEdgeTop, 10); + YGNodeStyleSetMargin(root_child1, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child1, 60); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child2, YGEdgeTop, 15); + YGNodeStyleSetMargin(root_child2, YGEdgeBottom, 15); + YGNodeStyleSetWidth(root_child2, 60); + 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(2, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, 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(40, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(2, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(59, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_determines_parent_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetGap(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetHeight(root_child2, 30); + 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(80, 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(20, 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(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, 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(80, 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(20, 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(50, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 700); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + 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(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_determines_parent_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + 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(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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(200, 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(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_both_content_padding_and_item_padding) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 700); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 10); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 10); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + 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, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child2, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root_child2, YGEdgeTop, 10); + YGNodeStyleSetPadding(root_child2, YGEdgeRight, 10); + YGNodeStyleSetPadding(root_child2, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + 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, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child4, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root_child4, YGEdgeTop, 10); + YGNodeStyleSetPadding(root_child4, YGEdgeRight, 10); + YGNodeStyleSetPadding(root_child4, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + 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(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_both_content_padding) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 10); + YGNodeStyleSetPadding(root, YGEdgeTop, 10); + YGNodeStyleSetPadding(root, YGEdgeRight, 10); + YGNodeStyleSetPadding(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 700); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + 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(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_content_margin) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetMargin(root, YGEdgeLeft, 10); + YGNodeStyleSetMargin(root, YGEdgeTop, 10); + YGNodeStyleSetMargin(root, YGEdgeRight, 10); + YGNodeStyleSetMargin(root, YGEdgeBottom, 10); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 700); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, 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(130, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(340, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(200, 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(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(170, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(340, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_content_margin_and_padding) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + 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); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 700); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + YGNodeInsertChild(root, root_child4, 4); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(138, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(178, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(190, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(346, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_flexible_content) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeInsertChild(root, root_child1, 1); + + 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(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(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child2)); + + 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(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(220, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_mixed_flexible_content) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 10); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child1, 1); + YGNodeStyleSetFlexShrink(root_child1, 1); + YGNodeStyleSetFlexBasisPercent(root_child1, 0); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(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(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(10, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(270, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child2)); + + 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(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(290, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(10, 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(200, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, row_gap_percent_wrapping_with_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetMinWidth(root, 300); + YGNodeStyleSetGapPercent(root, YGGutterColumn, 10); + YGNodeStyleSetGapPercent(root, YGGutterRow, 10); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 100); + YGNodeStyleSetHeight(root_child2, 100); + YGNodeInsertChild(root, root_child2, 2); + + YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 100); + YGNodeStyleSetHeight(root_child3, 100); + YGNodeInsertChild(root, root_child3, 3); + + YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child4, 100); + YGNodeStyleSetHeight(root_child4, 100); + 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(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(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(130, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, 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(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(200, 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(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child3)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child4)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child4)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGIntrinsicSizeTest.cpp b/tests/generated/YGIntrinsicSizeTest.cpp new file mode 100644 index 0000000000..630d251d6b --- /dev/null +++ b/tests/generated/YGIntrinsicSizeTest.cpp @@ -0,0 +1,3046 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<718c2ea7c24bad16412bbcda9182fc9f>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGIntrinsicSizeTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, contains_inner_text_long_word) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"LoremipsumdolorsitametconsecteturadipiscingelitSedeleifasdfettortoracauctorFuscerhoncusipsumtemporerosaliquamconsequatPraesentsoda"); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1300, 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(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(700, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1300, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_no_width_no_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_no_width_no_height_long_word_in_paragraph) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus loremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumloremipsumlorem Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_fixed_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, 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(1290, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1900, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(1290, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_no_width_fixed_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, 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(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_fixed_width_fixed_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, 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(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1950, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_max_width_max_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetMaxWidth(root_child0, 50); + YGNodeStyleSetMaxHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, 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(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1950, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_max_width_max_height_column) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMaxWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(1890, 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(1890, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(1890, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1950, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(1890, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_max_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetMaxWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, 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(1290, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1900, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(1290, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_fixed_width_shorter_text) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum"); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, 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)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1900, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_fixed_height_shorter_text) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetHeight(root_child0, 100); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum"); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(110, 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(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(1890, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(110, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, contains_inner_text_max_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 2000); + YGNodeStyleSetHeight(root, 2000); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetMaxHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + YGNodeSetContext(root_child0, (void*)"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eleifasd et tortor ac auctor. Integer at volutpat libero, sed elementum dui interdum id. Aliquam consectetur massa vel neque aliquet, quis consequat risus fringilla. Fusce rhoncus ipsum tempor eros aliquam, vel tempus metus ullamcorper. Nam at nulla sed tellus vestibulum fringilla vel sit amet ligula. Proin velit lectus, euismod sit amet quam vel ultricies dolor, vitae finibus lorem ipsum. Pellentesque molestie at mi sit amet dictum. Donec vehicula lacinia felis sit amet consectetur. Praesent sodales enim sapien, sed varius ipsum pellentesque vel. Aenean eu mi eu justo tincidunt finibus vel sit amet ipsum. Sed bibasdum purus vel ipsum sagittis, quis fermentum dolor lobortis. Etiam vulputate eleifasd lectus vel varius. Phasellus imperdiet lectus sit amet ipsum egestas, ut bibasdum ipsum malesuada. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed mollis eros sit amet elit porttitor, vel venenatis turpis venenatis. Nulla tempus tortor at eros efficitur, sit amet dapibus ipsum malesuada. Ut at mauris sed nunc malesuada convallis. Duis id sem vel magna varius eleifasd vel at est. Donec eget orci a ipsum tempor lobortis. Sed at consectetur ipsum."); + YGNodeSetMeasureFunc(root_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, 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(2000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(2000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidthMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + 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(175, 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(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, 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(175, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(125, 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(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, 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(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidthFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, 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(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_width) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidthStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + 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(50, 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(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_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + 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(50, 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(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(450, 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(350, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(325, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_height) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetHeightMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, 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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeightFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(90, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(90, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeightStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(500, 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(500, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(500, 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(500, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_flex_basis_column) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetFlexBasisMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, 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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_flex_basis_column) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetFlexBasisFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(90, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(90, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_flex_basis_column) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(500, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(500, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_flex_basis_row) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetFlexBasisMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 500); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(600, 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(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(550, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(600, 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(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(550, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_flex_basis_row) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetFlexBasisFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, 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(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, 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(90, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, 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(-10, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_flex_basis_row) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + 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(50, 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(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_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + 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(50, 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(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(450, 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(350, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(325, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_max_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetMaxWidthMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + 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(175, 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(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, 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(175, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(125, 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(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, 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(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_max_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidth(root_child0, 110); + YGNodeStyleSetMaxWidthFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, 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(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_max_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidth(root_child0, 600); + YGNodeStyleSetMaxWidthStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + 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(50, 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(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_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + 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(50, 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(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(450, 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(350, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(325, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetMinWidthMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 25); + 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(175, 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(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(25, 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(175, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(125, 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(25, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, 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(25, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidth(root_child0, 90); + YGNodeStyleSetMinWidthFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, 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(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, 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(50, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetMinWidthStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 50); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + 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(50, 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(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_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + 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(50, 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(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(450, 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(350, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(325, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_max_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetHeight(root, 200); + YGNodeStyleSetMaxHeightMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, 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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_max_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 110); + YGNodeStyleSetMaxHeightFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(90, 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_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_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)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(90, 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_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_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)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_max_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 600); + YGNodeStyleSetMaxHeightStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(500, 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(500, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(500, 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(500, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, max_content_min_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetHeight(root, 100); + YGNodeStyleSetMinHeightMaxContent(root); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, 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(50, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(175, 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(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, fit_content_min_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 90); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 90); + YGNodeStyleSetMinHeightFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(90, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(90, 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(175, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, stretch_min_height) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetHeight(root, 500); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeStyleSetMinHeightStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child2, 50); + YGNodeStyleSetHeight(root_child0_child2, 25); + YGNodeInsertChild(root_child0, root_child0_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(500, 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(500, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_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(500, 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(500, 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_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, text_max_content_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthMaxContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum sdafhasdfkjlasdhlkajsfhasldkfhasdlkahsdflkjasdhflaksdfasdlkjhasdlfjahsdfljkasdhalsdfhas dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1140, 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(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-940, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, text_stretch_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(20, 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(20, 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, text_fit_content_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum sdafhasdfkjlasdhlkajsfhasldkfhasdlkahsdflkjasdhflaksdfasdlkjhasdlfjahsdfljkasdhalsdfhas dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(30, 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(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-670, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, text_max_content_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetMinWidthMaxContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum sdafhasdfkjlasdhlkajsfhasldkfhasdlkahsdflkjasdhflaksdfasdlkjhasdlfjahsdfljkasdhalsdfhas dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1140, 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(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-940, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, text_stretch_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 100); + YGNodeStyleSetMinWidthStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(20, 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(20, 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, text_fit_content_min_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 300); + YGNodeStyleSetMinWidthFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum sdafhasdfkjlasdhlkajsfhasldkfhasdlkahsdflkjasdhflaksdfasdlkjhasdlfjahsdfljkasdhalsdfhas dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(30, 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(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-670, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, text_max_content_max_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 2000); + YGNodeStyleSetMaxWidthMaxContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum sdafhasdfkjlasdhlkajsfhasldkfhasdlkahsdflkjasdhflaksdfasdlkjhasdlfjahsdfljkasdhalsdfhas dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1140, 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(10, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-940, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(1140, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, text_stretch_max_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 300); + YGNodeStyleSetMaxWidthStretch(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(20, 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(20, 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, text_fit_content_max_width) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 1000); + YGNodeStyleSetMaxWidthFitContent(root_child0); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + YGNodeSetContext(root_child0_child0, (void*)"Lorem ipsum sdafhasdfkjlasdhlkajsfhasldkfhasdlkahsdflkjasdhflaksdfasdlkjhasdlfjahsdfljkasdhalsdfhas dolor sit amet"); + YGNodeSetMeasureFunc(root_child0_child0, &facebook::yoga::test::IntrinsicSizeMeasure); + 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(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(30, 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(30, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-670, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(870, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGJustifyContentTest.cpp b/tests/generated/YGJustifyContentTest.cpp similarity index 51% rename from tests/YGJustifyContentTest.cpp rename to tests/generated/YGJustifyContentTest.cpp index e82263c58e..6f4443227c 100644 --- a/tests/YGJustifyContentTest.cpp +++ b/tests/generated/YGJustifyContentTest.cpp @@ -1,32 +1,36 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<07092062f14f233462a4678c392df76a>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGJustifyContentTest.html */ -// @Generated by gentest/gentest.rb from -// gentest/fixtures/YGJustifyContentTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, justify_content_row_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -79,23 +83,24 @@ TEST(YogaTest, justify_content_row_flex_start) { } TEST(YogaTest, justify_content_row_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -148,23 +153,24 @@ TEST(YogaTest, justify_content_row_flex_end) { } TEST(YogaTest, justify_content_row_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -217,23 +223,24 @@ TEST(YogaTest, justify_content_row_center) { } TEST(YogaTest, justify_content_row_space_between) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -286,23 +293,24 @@ TEST(YogaTest, justify_content_row_space_between) { } TEST(YogaTest, justify_content_row_space_around) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -355,21 +363,22 @@ TEST(YogaTest, justify_content_row_space_around) { } TEST(YogaTest, justify_content_column_flex_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -422,22 +431,23 @@ TEST(YogaTest, justify_content_column_flex_start) { } TEST(YogaTest, justify_content_column_flex_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -490,22 +500,23 @@ TEST(YogaTest, justify_content_column_flex_end) { } TEST(YogaTest, justify_content_column_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -558,22 +569,23 @@ TEST(YogaTest, justify_content_column_center) { } TEST(YogaTest, justify_content_column_space_between) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -626,22 +638,23 @@ TEST(YogaTest, justify_content_column_space_between) { } TEST(YogaTest, justify_content_column_space_around) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -694,15 +707,16 @@ TEST(YogaTest, justify_content_column_space_around) { } TEST(YogaTest, justify_content_row_min_width_and_margin) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeLeft, 100); YGNodeStyleSetMinWidth(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 20); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); @@ -736,16 +750,17 @@ TEST(YogaTest, justify_content_row_min_width_and_margin) { } TEST(YogaTest, justify_content_row_max_width_and_margin) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeLeft, 100); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetMaxWidth(root, 80); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 20); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); @@ -779,14 +794,15 @@ TEST(YogaTest, justify_content_row_max_width_and_margin) { } TEST(YogaTest, justify_content_column_min_height_and_margin) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeTop, 100); YGNodeStyleSetMinHeight(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 20); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); @@ -819,16 +835,17 @@ TEST(YogaTest, justify_content_column_min_height_and_margin) { YGConfigFree(config); } -TEST(YogaTest, justify_content_colunn_max_height_and_margin) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, justify_content_column_max_height_and_margin) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMargin(root, YGEdgeTop, 100); YGNodeStyleSetHeight(root, 100); YGNodeStyleSetMaxHeight(root, 80); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 20); YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); @@ -862,22 +879,23 @@ TEST(YogaTest, justify_content_colunn_max_height_and_margin) { } TEST(YogaTest, justify_content_column_space_evenly) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -930,23 +948,24 @@ TEST(YogaTest, justify_content_column_space_evenly) { } TEST(YogaTest, justify_content_row_space_evenly) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 102); YGNodeStyleSetHeight(root, 102); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -998,22 +1017,21 @@ TEST(YogaTest, justify_content_row_space_evenly) { YGConfigFree(config); } -TEST( - YogaTest, - justify_content_min_width_with_padding_child_width_greater_than_parent) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, justify_content_min_width_with_padding_child_width_greater_than_parent) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 1000); YGNodeStyleSetHeight(root, 1584); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root_child0, YGAlignStretch); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyCenter); YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); @@ -1022,7 +1040,7 @@ TEST( YGNodeStyleSetMinWidth(root_child0_child0, 400); YGNodeInsertChild(root_child0, root_child0_child0, 0); - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0_child0_child0, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root_child0_child0_child0, YGAlignStretch); YGNodeStyleSetWidth(root_child0_child0_child0, 300); @@ -1077,22 +1095,21 @@ TEST( YGConfigFree(config); } -TEST( - YogaTest, - justify_content_min_width_with_padding_child_width_lower_than_parent) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, justify_content_min_width_with_padding_child_width_lower_than_parent) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 1080); YGNodeStyleSetHeight(root, 1584); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root_child0, YGAlignStretch); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyCenter); YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); @@ -1101,7 +1118,7 @@ TEST( YGNodeStyleSetMinWidth(root_child0_child0, 400); YGNodeInsertChild(root_child0, root_child0_child0, 0); - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0_child0_child0, YGFlexDirectionRow); YGNodeStyleSetAlignContent(root_child0_child0_child0, YGAlignStretch); YGNodeStyleSetWidth(root_child0_child0_child0, 199); @@ -1155,3 +1172,847 @@ TEST( YGConfigFree(config); } + +TEST(YogaTest, justify_content_space_between_indefinite_container_dim_with_free_space) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 300); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0, YGJustifySpaceBetween); + YGNodeStyleSetMinWidth(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child1, 50); + YGNodeStyleSetHeight(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(300, 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(200, 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(150, YGNodeLayoutGetLeft(root_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, 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(300, 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(200, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, 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_child0_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_flex_start_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_flex_end_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, 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(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_flex_start) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_flex_end) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(-18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_center) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(-9, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(31, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(71, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(31, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-9, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_between) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_around) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_evenly) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_reverse_space_around) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(-18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_reverse_space_evenly) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(-18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_evenly_auto_margin) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, 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(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, 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(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGMarginTest.cpp b/tests/generated/YGMarginTest.cpp similarity index 84% rename from tests/YGMarginTest.cpp rename to tests/generated/YGMarginTest.cpp index e857da0918..f9b5093795 100644 --- a/tests/YGMarginTest.cpp +++ b/tests/generated/YGMarginTest.cpp @@ -1,23 +1,28 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGMarginTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGMarginTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, margin_start) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -51,13 +56,14 @@ TEST(YogaTest, margin_start) { } TEST(YogaTest, margin_top) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -91,15 +97,16 @@ TEST(YogaTest, margin_top) { } TEST(YogaTest, margin_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -133,14 +140,15 @@ TEST(YogaTest, margin_end) { } TEST(YogaTest, margin_bottom) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -174,14 +182,15 @@ TEST(YogaTest, margin_bottom) { } TEST(YogaTest, margin_and_flex_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); @@ -216,13 +225,14 @@ TEST(YogaTest, margin_and_flex_row) { } TEST(YogaTest, margin_and_flex_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); @@ -257,14 +267,15 @@ TEST(YogaTest, margin_and_flex_column) { } TEST(YogaTest, margin_and_stretch_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 10); YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 10); @@ -299,13 +310,14 @@ TEST(YogaTest, margin_and_stretch_row) { } TEST(YogaTest, margin_and_stretch_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMargin(root_child0, YGEdgeStart, 10); YGNodeStyleSetMargin(root_child0, YGEdgeEnd, 10); @@ -340,19 +352,20 @@ TEST(YogaTest, margin_and_stretch_column) { } TEST(YogaTest, margin_with_sibling_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -395,18 +408,19 @@ TEST(YogaTest, margin_with_sibling_row) { } TEST(YogaTest, margin_with_sibling_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -449,20 +463,21 @@ TEST(YogaTest, margin_with_sibling_column) { } TEST(YogaTest, margin_auto_bottom) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -506,20 +521,21 @@ TEST(YogaTest, margin_auto_bottom) { } TEST(YogaTest, margin_auto_top) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -563,21 +579,22 @@ TEST(YogaTest, margin_auto_top) { } TEST(YogaTest, margin_auto_bottom_and_top) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -621,21 +638,22 @@ TEST(YogaTest, margin_auto_bottom_and_top) { } TEST(YogaTest, margin_auto_bottom_and_top_justify_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -678,27 +696,28 @@ TEST(YogaTest, margin_auto_bottom_and_top_justify_center) { YGConfigFree(config); } -TEST(YogaTest, margin_auto_mutiple_children_column) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, margin_auto_multiple_children_column) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 50); YGNodeStyleSetHeight(root_child2, 50); YGNodeInsertChild(root, root_child2, 2); @@ -751,28 +770,29 @@ TEST(YogaTest, margin_auto_mutiple_children_column) { YGConfigFree(config); } -TEST(YogaTest, margin_auto_mutiple_children_row) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, margin_auto_multiple_children_row) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 50); YGNodeStyleSetHeight(root_child2, 50); YGNodeInsertChild(root, root_child2, 2); @@ -826,22 +846,23 @@ TEST(YogaTest, margin_auto_mutiple_children_row) { } TEST(YogaTest, margin_auto_left_and_right_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -885,20 +906,21 @@ TEST(YogaTest, margin_auto_left_and_right_column) { } TEST(YogaTest, margin_auto_left_and_right) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -942,22 +964,23 @@ TEST(YogaTest, margin_auto_left_and_right) { } TEST(YogaTest, margin_auto_start_and_end_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1001,20 +1024,21 @@ TEST(YogaTest, margin_auto_start_and_end_column) { } TEST(YogaTest, margin_auto_start_and_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1058,21 +1082,22 @@ TEST(YogaTest, margin_auto_start_and_end) { } TEST(YogaTest, margin_auto_left_and_right_column_and_center) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1116,20 +1141,21 @@ TEST(YogaTest, margin_auto_left_and_right_column_and_center) { } TEST(YogaTest, margin_auto_left) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1173,20 +1199,21 @@ TEST(YogaTest, margin_auto_left) { } TEST(YogaTest, margin_auto_right) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1229,22 +1256,23 @@ TEST(YogaTest, margin_auto_right) { YGConfigFree(config); } -TEST(YogaTest, margin_auto_left_and_right_strech) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, margin_auto_left_and_right_stretch) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1287,21 +1315,22 @@ TEST(YogaTest, margin_auto_left_and_right_strech) { YGConfigFree(config); } -TEST(YogaTest, margin_auto_top_and_bottom_strech) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, margin_auto_top_and_bottom_stretch) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1345,13 +1374,14 @@ TEST(YogaTest, margin_auto_top_and_bottom_strech) { } TEST(YogaTest, margin_should_not_be_part_of_max_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 250); YGNodeStyleSetHeight(root, 250); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetHeight(root_child0, 100); @@ -1387,13 +1417,14 @@ TEST(YogaTest, margin_should_not_be_part_of_max_height) { } TEST(YogaTest, margin_should_not_be_part_of_max_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 250); YGNodeStyleSetHeight(root, 250); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 20); YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetMaxWidth(root_child0, 100); @@ -1429,14 +1460,15 @@ TEST(YogaTest, margin_should_not_be_part_of_max_width) { } TEST(YogaTest, margin_auto_left_right_child_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); YGNodeStyleSetWidth(root_child0, 72); @@ -1472,14 +1504,15 @@ TEST(YogaTest, margin_auto_left_right_child_bigger_than_parent) { } TEST(YogaTest, margin_auto_left_child_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); YGNodeStyleSetWidth(root_child0, 72); YGNodeStyleSetHeight(root_child0, 72); @@ -1514,14 +1547,15 @@ TEST(YogaTest, margin_auto_left_child_bigger_than_parent) { } TEST(YogaTest, margin_fix_left_auto_right_child_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 10); YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); YGNodeStyleSetWidth(root_child0, 72); @@ -1557,14 +1591,15 @@ TEST(YogaTest, margin_fix_left_auto_right_child_bigger_than_parent) { } TEST(YogaTest, margin_auto_left_fix_right_child_bigger_than_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 52); YGNodeStyleSetHeight(root, 52); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); YGNodeStyleSetMargin(root_child0, YGEdgeRight, 10); YGNodeStyleSetWidth(root_child0, 72); @@ -1600,21 +1635,22 @@ TEST(YogaTest, margin_auto_left_fix_right_child_bigger_than_parent) { } TEST(YogaTest, margin_auto_top_stretching_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1658,21 +1694,22 @@ TEST(YogaTest, margin_auto_top_stretching_child) { } TEST(YogaTest, margin_auto_left_stretching_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); @@ -1714,3 +1751,61 @@ TEST(YogaTest, margin_auto_left_stretching_child) { YGConfigFree(config); } + +TEST(YogaTest, margin_auto_overflowing_container) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 150); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 150); + 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(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(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(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, 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(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGMinMaxDimensionTest.cpp b/tests/generated/YGMinMaxDimensionTest.cpp similarity index 83% rename from tests/YGMinMaxDimensionTest.cpp rename to tests/generated/YGMinMaxDimensionTest.cpp index ef3fcb6e11..bbb4b40a92 100644 --- a/tests/YGMinMaxDimensionTest.cpp +++ b/tests/generated/YGMinMaxDimensionTest.cpp @@ -1,23 +1,27 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<0054f2d41727e7a0707701c6d7640cb6>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGMinMaxDimensionTest.html */ -// @Generated by gentest/gentest.rb from -// gentest/fixtures/YGMinMaxDimensionTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, max_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMaxWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -51,14 +55,15 @@ TEST(YogaTest, max_width) { } TEST(YogaTest, max_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetMaxHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); @@ -92,18 +97,21 @@ TEST(YogaTest, max_height) { } TEST(YogaTest, min_height) { - const YGConfigRef config = YGConfigNew(); + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMinHeight(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -116,12 +124,12 @@ TEST(YogaTest, min_height) { 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(60, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(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(40, YGNodeLayoutGetHeight(root_child1)); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); @@ -133,12 +141,12 @@ TEST(YogaTest, min_height) { 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(60, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(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(40, YGNodeLayoutGetHeight(root_child1)); YGNodeFreeRecursive(root); @@ -146,19 +154,22 @@ TEST(YogaTest, min_height) { } TEST(YogaTest, min_width) { - const YGConfigRef config = YGConfigNew(); + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMinWidth(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -170,12 +181,12 @@ TEST(YogaTest, min_width) { ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root_child0)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); - ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); @@ -185,14 +196,14 @@ TEST(YogaTest, min_width) { ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); - ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child0)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, 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(40, YGNodeLayoutGetWidth(root_child1)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); YGNodeFreeRecursive(root); @@ -201,15 +212,16 @@ TEST(YogaTest, min_width) { } TEST(YogaTest, justify_content_min_max) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetMinHeight(root, 100); YGNodeStyleSetMaxHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 60); YGNodeStyleSetHeight(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); @@ -243,15 +255,16 @@ TEST(YogaTest, justify_content_min_max) { } TEST(YogaTest, align_items_min_max) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMinWidth(root, 100); YGNodeStyleSetMaxWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 60); YGNodeStyleSetHeight(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); @@ -285,24 +298,25 @@ TEST(YogaTest, align_items_min_max) { } TEST(YogaTest, justify_content_overflow_min_max) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMinHeight(root, 100); YGNodeStyleSetMaxHeight(root, 110); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 50); YGNodeStyleSetHeight(root_child2, 50); YGNodeInsertChild(root, root_child2, 2); @@ -356,19 +370,20 @@ TEST(YogaTest, justify_content_overflow_min_max) { } TEST(YogaTest, flex_grow_to_min) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetMinHeight(root, 100); YGNodeStyleSetMaxHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -411,19 +426,20 @@ TEST(YogaTest, flex_grow_to_min) { } TEST(YogaTest, flex_grow_in_at_most_container) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0_child0, 1); YGNodeStyleSetFlexBasis(root_child0_child0, 0); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -467,12 +483,13 @@ TEST(YogaTest, flex_grow_in_at_most_container) { } TEST(YogaTest, flex_grow_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 0); YGNodeStyleSetHeight(root_child0, 100); @@ -507,17 +524,18 @@ TEST(YogaTest, flex_grow_child) { } TEST(YogaTest, flex_grow_within_constrained_min_max_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMinHeight(root, 100); YGNodeStyleSetMaxHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -560,18 +578,19 @@ TEST(YogaTest, flex_grow_within_constrained_min_max_column) { } TEST(YogaTest, flex_grow_within_max_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0_child0, 1); YGNodeStyleSetHeight(root_child0_child0, 20); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -615,18 +634,19 @@ TEST(YogaTest, flex_grow_within_max_width) { } TEST(YogaTest, flex_grow_within_constrained_max_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0_child0, 1); YGNodeStyleSetHeight(root_child0_child0, 20); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -670,20 +690,21 @@ TEST(YogaTest, flex_grow_within_constrained_max_width) { } TEST(YogaTest, flex_root_ignored) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetFlexGrow(root, 1); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetMinHeight(root, 100); YGNodeStyleSetMaxHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 200); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 100); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -726,25 +747,26 @@ TEST(YogaTest, flex_root_ignored) { } TEST(YogaTest, flex_grow_root_minimized) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetMinHeight(root, 100); YGNodeStyleSetMaxHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0_child1, 100); YGNodeInsertChild(root_child0, root_child0_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -797,24 +819,25 @@ TEST(YogaTest, flex_grow_root_minimized) { } TEST(YogaTest, flex_grow_height_maximized) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0_child1, 100); YGNodeInsertChild(root_child0, root_child0_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -867,18 +890,19 @@ TEST(YogaTest, flex_grow_height_maximized) { } TEST(YogaTest, flex_grow_within_constrained_min_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMinWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -921,16 +945,17 @@ TEST(YogaTest, flex_grow_within_constrained_min_row) { } TEST(YogaTest, flex_grow_within_constrained_min_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetMinHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -973,23 +998,24 @@ TEST(YogaTest, flex_grow_within_constrained_min_column) { } TEST(YogaTest, flex_grow_within_constrained_max_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child1, 50); YGNodeInsertChild(root_child0, root_child0_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1042,18 +1068,19 @@ TEST(YogaTest, flex_grow_within_constrained_max_row) { } TEST(YogaTest, flex_grow_within_constrained_max_column) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetMaxHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child1, 50); YGNodeInsertChild(root, root_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1096,20 +1123,21 @@ TEST(YogaTest, flex_grow_within_constrained_max_column) { } TEST(YogaTest, child_min_max_width_flexing) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 120); YGNodeStyleSetHeight(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetFlexBasisPercent(root_child1, 50); YGNodeStyleSetMaxWidth(root_child1, 20); @@ -1154,9 +1182,10 @@ TEST(YogaTest, child_min_max_width_flexing) { } TEST(YogaTest, min_width_overrides_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 50); YGNodeStyleSetMinWidth(root, 100); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1179,9 +1208,10 @@ TEST(YogaTest, min_width_overrides_width) { } TEST(YogaTest, max_width_overrides_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetMaxWidth(root, 100); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1204,9 +1234,10 @@ TEST(YogaTest, max_width_overrides_width) { } TEST(YogaTest, min_height_overrides_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetHeight(root, 50); YGNodeStyleSetMinHeight(root, 100); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1229,9 +1260,10 @@ TEST(YogaTest, min_height_overrides_height) { } TEST(YogaTest, max_height_overrides_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetHeight(root, 200); YGNodeStyleSetMaxHeight(root, 100); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1254,14 +1286,15 @@ TEST(YogaTest, max_height_overrides_height) { } TEST(YogaTest, min_max_percent_no_width_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMinWidthPercent(root_child0, 10); YGNodeStyleSetMaxWidthPercent(root_child0, 10); YGNodeStyleSetMinHeightPercent(root_child0, 10); @@ -1295,82 +1328,3 @@ TEST(YogaTest, min_max_percent_no_width_height) { YGConfigFree(config); } - -static YGSize _measureCk_test_label_shrink_based_on_height( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - - if (heightMode == YGMeasureModeAtMost) { - return YGSize{ - .width = 290, - .height = 103, - }; - } else { - return YGSize{ - .width = 290, - .height = height, - }; - } -} - -TEST(YogaTest, min_max_percent_margin_percent_no_width_height) { - const YGConfigRef config = YGConfigNew(); - - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetWidth(root, 320); - - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeInsertChild(root, root_child0, 0); - - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetHeight(root_child0_child0, 450); - YGNodeInsertChild(root_child0, root_child0_child0, 0); - - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child0_child0_child0, YGFlexDirectionRow); - YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeTop, 5); - YGNodeStyleSetMaxHeightPercent(root_child0_child0_child0, 10); - YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); - - const YGNodeRef root_child0_child0_child0_child0 = - YGNodeNewWithConfig(config); - YGNodeSetMeasureFunc( - root_child0_child0_child0_child0, - _measureCk_test_label_shrink_based_on_height); - YGNodeInsertChild( - root_child0_child0_child0, root_child0_child0_child0_child0, 0); - - 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(450, YGNodeLayoutGetHeight(root)); - - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); - ASSERT_FLOAT_EQ(320, YGNodeLayoutGetWidth(root_child0)); - ASSERT_FLOAT_EQ(450, YGNodeLayoutGetHeight(root_child0)); - - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); - ASSERT_FLOAT_EQ(320, YGNodeLayoutGetWidth(root_child0_child0)); - ASSERT_FLOAT_EQ(450, YGNodeLayoutGetHeight(root_child0_child0)); - - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); - ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0)); - ASSERT_FLOAT_EQ(320, YGNodeLayoutGetWidth(root_child0_child0_child0)); - ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child0_child0_child0)); - - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); - ASSERT_FLOAT_EQ(290, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); - ASSERT_FLOAT_EQ(45, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); - - YGNodeFreeRecursive(root); - - YGConfigFree(config); -} diff --git a/tests/YGPaddingTest.cpp b/tests/generated/YGPaddingTest.cpp similarity index 73% rename from tests/YGPaddingTest.cpp rename to tests/generated/YGPaddingTest.cpp index bc3847d85d..30365c061a 100644 --- a/tests/YGPaddingTest.cpp +++ b/tests/generated/YGPaddingTest.cpp @@ -1,18 +1,23 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<6b47783e0e0befdd02efbfa83da49403>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGPaddingTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGPaddingTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, padding_no_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPadding(root, YGEdgeLeft, 10); YGNodeStyleSetPadding(root, YGEdgeTop, 10); YGNodeStyleSetPadding(root, YGEdgeRight, 10); @@ -37,15 +42,16 @@ TEST(YogaTest, padding_no_size) { } TEST(YogaTest, padding_container_match_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPadding(root, YGEdgeLeft, 10); YGNodeStyleSetPadding(root, YGEdgeTop, 10); YGNodeStyleSetPadding(root, YGEdgeRight, 10); YGNodeStyleSetPadding(root, YGEdgeBottom, 10); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -79,9 +85,10 @@ TEST(YogaTest, padding_container_match_child) { } TEST(YogaTest, padding_flex_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPadding(root, YGEdgeLeft, 10); YGNodeStyleSetPadding(root, YGEdgeTop, 10); YGNodeStyleSetPadding(root, YGEdgeRight, 10); @@ -89,7 +96,7 @@ TEST(YogaTest, padding_flex_child) { YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -123,9 +130,10 @@ TEST(YogaTest, padding_flex_child) { } TEST(YogaTest, padding_stretch_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPadding(root, YGEdgeLeft, 10); YGNodeStyleSetPadding(root, YGEdgeTop, 10); YGNodeStyleSetPadding(root, YGEdgeRight, 10); @@ -133,7 +141,7 @@ TEST(YogaTest, padding_stretch_child) { YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -166,18 +174,19 @@ TEST(YogaTest, padding_stretch_child) { } TEST(YogaTest, padding_center_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetPadding(root, YGEdgeStart, 10); YGNodeStyleSetPadding(root, YGEdgeEnd, 20); YGNodeStyleSetPadding(root, YGEdgeBottom, 20); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 10); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); @@ -211,15 +220,16 @@ TEST(YogaTest, padding_center_child) { } TEST(YogaTest, child_with_padding_align_end) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 20); YGNodeStyleSetPadding(root_child0, YGEdgeTop, 20); YGNodeStyleSetPadding(root_child0, YGEdgeRight, 20); @@ -255,3 +265,46 @@ TEST(YogaTest, child_with_padding_align_end) { YGConfigFree(config); } + +TEST(YogaTest, physical_and_relative_edge_defined) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPadding(root, YGEdgeLeft, 20); + YGNodeStyleSetPadding(root, YGEdgeEnd, 50); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 100); + YGNodeStyleSetHeight(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(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(130, 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(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(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/YGPercentageTest.cpp b/tests/generated/YGPercentageTest.cpp similarity index 67% rename from tests/YGPercentageTest.cpp rename to tests/generated/YGPercentageTest.cpp index ed794e2655..a8262f4169 100644 --- a/tests/YGPercentageTest.cpp +++ b/tests/generated/YGPercentageTest.cpp @@ -1,23 +1,28 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<6b01edcfd82ee39d61cfcadd0b312a36>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGPercentageTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, percentage_width_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidthPercent(root_child0, 30); YGNodeStyleSetHeightPercent(root_child0, 30); YGNodeInsertChild(root, root_child0, 0); @@ -51,14 +56,15 @@ TEST(YogaTest, percentage_width_height) { } TEST(YogaTest, percentage_position_left_top) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 400); YGNodeStyleSetHeight(root, 400); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 10); YGNodeStyleSetPositionPercent(root_child0, YGEdgeTop, 20); YGNodeStyleSetWidthPercent(root_child0, 45); @@ -94,14 +100,15 @@ TEST(YogaTest, percentage_position_left_top) { } TEST(YogaTest, percentage_position_bottom_right) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 500); YGNodeStyleSetHeight(root, 500); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionPercent(root_child0, YGEdgeRight, 20); YGNodeStyleSetPositionPercent(root_child0, YGEdgeBottom, 10); YGNodeStyleSetWidthPercent(root_child0, 55); @@ -137,19 +144,20 @@ TEST(YogaTest, percentage_position_bottom_right) { } TEST(YogaTest, percentage_flex_basis) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasisPercent(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetFlexBasisPercent(root_child1, 25); YGNodeInsertChild(root, root_child1, 1); @@ -193,18 +201,19 @@ TEST(YogaTest, percentage_flex_basis) { } TEST(YogaTest, percentage_flex_basis_cross) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasisPercent(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetFlexBasisPercent(root_child1, 25); YGNodeInsertChild(root, root_child1, 1); @@ -248,18 +257,21 @@ TEST(YogaTest, percentage_flex_basis_cross) { } TEST(YogaTest, percentage_flex_basis_cross_min_height) { - const YGConfigRef config = YGConfigNew(); + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMinHeightPercent(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 2); YGNodeStyleSetMinHeightPercent(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); @@ -273,12 +285,12 @@ TEST(YogaTest, percentage_flex_basis_cross_min_height) { 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(120, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetTop(root_child1)); ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); - ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child1)); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); @@ -290,12 +302,12 @@ TEST(YogaTest, percentage_flex_basis_cross_min_height) { 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(120, YGNodeLayoutGetHeight(root_child0)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetTop(root_child1)); ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child1)); - ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root_child1)); YGNodeFreeRecursive(root); @@ -303,20 +315,21 @@ TEST(YogaTest, percentage_flex_basis_cross_min_height) { } TEST(YogaTest, percentage_flex_basis_main_max_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 10); YGNodeStyleSetMaxHeightPercent(root_child1, 20); @@ -361,19 +374,20 @@ TEST(YogaTest, percentage_flex_basis_main_max_height) { } TEST(YogaTest, percentage_flex_basis_cross_max_height) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 10); YGNodeStyleSetMaxHeightPercent(root_child1, 20); @@ -418,20 +432,21 @@ TEST(YogaTest, percentage_flex_basis_cross_max_height) { } TEST(YogaTest, percentage_flex_basis_main_max_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 10); YGNodeStyleSetMaxWidthPercent(root_child1, 20); @@ -476,19 +491,20 @@ TEST(YogaTest, percentage_flex_basis_main_max_width) { } TEST(YogaTest, percentage_flex_basis_cross_max_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 15); YGNodeStyleSetMaxWidthPercent(root_child1, 20); @@ -533,20 +549,21 @@ TEST(YogaTest, percentage_flex_basis_cross_max_width) { } TEST(YogaTest, percentage_flex_basis_main_min_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 10); YGNodeStyleSetMinWidthPercent(root_child1, 20); @@ -591,19 +608,20 @@ TEST(YogaTest, percentage_flex_basis_main_min_width) { } TEST(YogaTest, percentage_flex_basis_cross_min_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 15); YGNodeStyleSetMinWidthPercent(root_child1, 20); @@ -647,16 +665,15 @@ TEST(YogaTest, percentage_flex_basis_cross_min_width) { YGConfigFree(config); } -TEST( - YogaTest, - percentage_multiple_nested_with_padding_margin_and_percentage_values) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, percentage_multiple_nested_with_padding_margin_and_percentage_values) { + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetFlexBasisPercent(root_child0, 10); YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 5); @@ -670,7 +687,7 @@ TEST( YGNodeStyleSetMinWidthPercent(root_child0, 60); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 5); YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 5); YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 5); @@ -682,7 +699,7 @@ TEST( YGNodeStyleSetWidthPercent(root_child0_child0, 50); YGNodeInsertChild(root_child0, root_child0_child0, 0); - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + 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); @@ -694,7 +711,7 @@ TEST( YGNodeStyleSetWidthPercent(root_child0_child0_child0, 45); YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 4); YGNodeStyleSetFlexBasisPercent(root_child1, 15); YGNodeStyleSetMinWidthPercent(root_child1, 20); @@ -759,13 +776,14 @@ TEST( } TEST(YogaTest, percentage_margin_should_calculate_based_only_on_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetMarginPercent(root_child0, YGEdgeLeft, 10); YGNodeStyleSetMarginPercent(root_child0, YGEdgeTop, 10); @@ -773,7 +791,7 @@ TEST(YogaTest, percentage_margin_should_calculate_based_only_on_width) { YGNodeStyleSetMarginPercent(root_child0, YGEdgeBottom, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 10); YGNodeStyleSetHeight(root_child0_child0, 10); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -817,13 +835,14 @@ TEST(YogaTest, percentage_margin_should_calculate_based_only_on_width) { } TEST(YogaTest, percentage_padding_should_calculate_based_only_on_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetPaddingPercent(root_child0, YGEdgeLeft, 10); YGNodeStyleSetPaddingPercent(root_child0, YGEdgeTop, 10); @@ -831,7 +850,7 @@ TEST(YogaTest, percentage_padding_should_calculate_based_only_on_width) { YGNodeStyleSetPaddingPercent(root_child0, YGEdgeBottom, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 10); YGNodeStyleSetHeight(root_child0_child0, 10); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -875,13 +894,14 @@ TEST(YogaTest, percentage_padding_should_calculate_based_only_on_width) { } TEST(YogaTest, percentage_absolute_position) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 30); YGNodeStyleSetPositionPercent(root_child0, YGEdgeTop, 10); @@ -918,11 +938,12 @@ TEST(YogaTest, percentage_absolute_position) { } TEST(YogaTest, percentage_width_height_undefined_parent_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidthPercent(root_child0, 50); YGNodeStyleSetHeightPercent(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); @@ -956,26 +977,27 @@ TEST(YogaTest, percentage_width_height_undefined_parent_size) { } TEST(YogaTest, percent_within_flex_grow) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 350); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child1_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidthPercent(root_child1_child0, 100); YGNodeInsertChild(root_child1, root_child1_child0, 0); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child2, 100); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1038,29 +1060,30 @@ TEST(YogaTest, percent_within_flex_grow) { } TEST(YogaTest, percentage_container_in_wrapping_container) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetJustifyContent(root, YGJustifyCenter); YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 200); YGNodeStyleSetHeight(root, 200); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + 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); + 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); + 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); @@ -1124,13 +1147,14 @@ TEST(YogaTest, percentage_container_in_wrapping_container) { } TEST(YogaTest, percent_absolute_position) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 60); YGNodeStyleSetHeight(root, 50); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); YGNodeStyleSetPositionPercent(root_child0, YGEdgeLeft, 50); @@ -1138,11 +1162,11 @@ TEST(YogaTest, percent_absolute_position) { YGNodeStyleSetHeight(root_child0, 50); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetWidthPercent(root_child0_child1, 100); YGNodeInsertChild(root_child0, root_child0_child1, 1); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -1194,78 +1218,419 @@ TEST(YogaTest, percent_absolute_position) { YGConfigFree(config); } -static YGSize _measureCk_test_label_shrink_based_on_height( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode) { - - if (heightMode == YGMeasureModeAtMost) { - return YGSize{ - .width = 290, - .height = 103, - }; - } else { - return YGSize{ - .width = 290, - .height = height, - }; - } +TEST(YogaTest, percent_of_minmax_main) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetMaxWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(60, 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(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); } -TEST(YogaTest, margin_percent_with_measure_func) { - const YGConfigRef config = YGConfigNew(); +TEST(YogaTest, percent_of_min_main) { + GTEST_SKIP(); - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetWidth(root, 320); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetHeight(root_child0_child0, 450); - YGNodeInsertChild(root_child0, root_child0_child0, 0); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root)); - const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexDirection(root_child0_child0_child0, YGFlexDirectionRow); - YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeTop, 5); - YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_of_min_main_multiple) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0_child0_child0 = - YGNodeNewWithConfig(config); - YGNodeSetMeasureFunc( - root_child0_child0_child0_child0, - _measureCk_test_label_shrink_based_on_height); - YGNodeInsertChild( - root_child0_child0_child0, root_child0_child0_child0_child0, 0); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 20); + 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(450, YGNodeLayoutGetHeight(root)); + ASSERT_FLOAT_EQ(60, 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(320, YGNodeLayoutGetWidth(root_child0)); - ASSERT_FLOAT_EQ(450, YGNodeLayoutGetHeight(root_child0)); + ASSERT_FLOAT_EQ(30, 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(320, YGNodeLayoutGetWidth(root_child0_child0)); - ASSERT_FLOAT_EQ(450, YGNodeLayoutGetHeight(root_child0_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(20, YGNodeLayoutGetHeight(root_child1)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); - ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0)); - ASSERT_FLOAT_EQ(320, YGNodeLayoutGetWidth(root_child0_child0_child0)); - ASSERT_FLOAT_EQ(103, YGNodeLayoutGetHeight(root_child0_child0_child0)); - - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); - ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); - ASSERT_FLOAT_EQ(290, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); - ASSERT_FLOAT_EQ(103, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-30, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_of_max_main) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMaxWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(0, 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(0, 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(0, 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(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_of_minmax_cross_stretched) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetMaxWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(60, 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(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_absolute_of_minmax_cross_stretched) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetMaxWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(60, 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(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_of_minmax_cross_unstretched) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetMaxWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(60, 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(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_of_min_cross_unstretched) { + GTEST_SKIP(); + + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(60, 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(30, 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(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(30, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, percent_of_max_cross_unstretched) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMaxWidth(root, 60); + YGNodeStyleSetHeight(root, 50); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0, 50); + 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(0, 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(0, 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(0, 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(0, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0)); YGNodeFreeRecursive(root); diff --git a/tests/YGRoundingTest.cpp b/tests/generated/YGRoundingTest.cpp similarity index 86% rename from tests/YGRoundingTest.cpp rename to tests/generated/YGRoundingTest.cpp index 6e82c11699..1ec813de50 100644 --- a/tests/YGRoundingTest.cpp +++ b/tests/generated/YGRoundingTest.cpp @@ -1,31 +1,36 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGRoundingTest.html */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGRoundingTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, rounding_flex_basis_flex_grow_row_width_of_100) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -78,30 +83,31 @@ TEST(YogaTest, rounding_flex_basis_flex_grow_row_width_of_100) { } TEST(YogaTest, rounding_flex_basis_flex_grow_row_prime_number_width) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 113); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeInsertChild(root, root_child2, 2); - const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeRef root_child3 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child3, 1); YGNodeInsertChild(root, root_child3, 3); - const YGNodeRef root_child4 = YGNodeNewWithConfig(config); + YGNodeRef root_child4 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child4, 1); YGNodeInsertChild(root, root_child4, 4); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -174,23 +180,24 @@ TEST(YogaTest, rounding_flex_basis_flex_grow_row_prime_number_width) { } TEST(YogaTest, rounding_flex_basis_flex_shrink_row) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 101); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexShrink(root_child0, 1); YGNodeStyleSetFlexBasis(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasis(root_child1, 25); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexBasis(root_child2, 25); YGNodeInsertChild(root, root_child2, 2); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -243,24 +250,25 @@ TEST(YogaTest, rounding_flex_basis_flex_shrink_row) { } TEST(YogaTest, rounding_flex_basis_overrides_main_size) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 113); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -314,26 +322,27 @@ TEST(YogaTest, rounding_flex_basis_overrides_main_size) { } TEST(YogaTest, rounding_total_fractial) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetWidth(root, 87.4); - YGNodeStyleSetHeight(root, 113.4); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 87.4f); + YGNodeStyleSetHeight(root, 113.4f); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexGrow(root_child0, 0.7); - YGNodeStyleSetFlexBasis(root_child0, 50.3); - YGNodeStyleSetHeight(root_child0, 20.3); + 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.6); + 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.1); - YGNodeStyleSetHeight(root_child2, 10.7); + 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); @@ -385,40 +394,41 @@ TEST(YogaTest, rounding_total_fractial) { } TEST(YogaTest, rounding_total_fractial_nested) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetWidth(root, 87.4); - YGNodeStyleSetHeight(root, 113.4); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 87.4f); + YGNodeStyleSetHeight(root, 113.4f); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); - YGNodeStyleSetFlexGrow(root_child0, 0.7); - YGNodeStyleSetFlexBasis(root_child0, 50.3); - YGNodeStyleSetHeight(root_child0, 20.3); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0_child0, 1); - YGNodeStyleSetFlexBasis(root_child0_child0, 0.3); - YGNodeStyleSetPosition(root_child0_child0, YGEdgeBottom, 13.3); - YGNodeStyleSetHeight(root_child0_child0, 9.9); + 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); + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0_child1, 4); - YGNodeStyleSetFlexBasis(root_child0_child1, 0.3); - YGNodeStyleSetPosition(root_child0_child1, YGEdgeTop, 13.3); - YGNodeStyleSetHeight(root_child0_child1, 1.1); + 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.6); + 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.1); - YGNodeStyleSetHeight(root_child2, 10.7); + 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); @@ -490,24 +500,25 @@ TEST(YogaTest, rounding_total_fractial_nested) { } TEST(YogaTest, rounding_fractial_input_1) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); - YGNodeStyleSetHeight(root, 113.4); + YGNodeStyleSetHeight(root, 113.4f); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -561,24 +572,25 @@ TEST(YogaTest, rounding_fractial_input_1) { } TEST(YogaTest, rounding_fractial_input_2) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); - YGNodeStyleSetHeight(root, 113.6); + YGNodeStyleSetHeight(root, 113.6f); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -632,25 +644,26 @@ TEST(YogaTest, rounding_fractial_input_2) { } TEST(YogaTest, rounding_fractial_input_3) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetPosition(root, YGEdgeTop, 0.3); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root, YGEdgeTop, 0.3f); YGNodeStyleSetWidth(root, 100); - YGNodeStyleSetHeight(root, 113.4); + YGNodeStyleSetHeight(root, 113.4f); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -704,25 +717,26 @@ TEST(YogaTest, rounding_fractial_input_3) { } TEST(YogaTest, rounding_fractial_input_4) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); - YGNodeStyleSetPosition(root, YGEdgeTop, 0.7); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root, YGEdgeTop, 0.7f); YGNodeStyleSetWidth(root, 100); - YGNodeStyleSetHeight(root, 113.4); + YGNodeStyleSetHeight(root, 113.4f); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child1 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child1, 1); YGNodeStyleSetHeight(root_child1, 10); YGNodeInsertChild(root, root_child1, 1); - const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -776,28 +790,29 @@ TEST(YogaTest, rounding_fractial_input_4) { } TEST(YogaTest, rounding_inner_node_controversy_horizontal) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 320); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -861,27 +876,28 @@ TEST(YogaTest, rounding_inner_node_controversy_horizontal) { } TEST(YogaTest, rounding_inner_node_controversy_vertical) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetHeight(root, 320); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetWidth(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetWidth(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); @@ -945,44 +961,45 @@ TEST(YogaTest, rounding_inner_node_controversy_vertical) { } TEST(YogaTest, rounding_inner_node_controversy_combined) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 640); YGNodeStyleSetHeight(root, 320); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child0, 1); YGNodeStyleSetHeightPercent(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + 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); + 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); + 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); + 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); + 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); + YGNodeRef root_child2 = YGNodeNewWithConfig(config); YGNodeStyleSetFlexGrow(root_child2, 1); YGNodeStyleSetHeightPercent(root_child2, 100); YGNodeInsertChild(root, root_child2, 2); diff --git a/tests/YGSizeOverflowTest.cpp b/tests/generated/YGSizeOverflowTest.cpp similarity index 84% rename from tests/YGSizeOverflowTest.cpp rename to tests/generated/YGSizeOverflowTest.cpp index 4cfa0a68e4..efd3010a89 100644 --- a/tests/YGSizeOverflowTest.cpp +++ b/tests/generated/YGSizeOverflowTest.cpp @@ -1,26 +1,30 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * - * This source code is licensed under the MIT license found in the LICENSE - * file in the root directory of this source tree. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGSizeOverflowTest.html */ -// @Generated by gentest/gentest.rb from -// gentest/fixtures/YGSizeOverflowTest.html #include #include +#include "../util/TestUtil.h" TEST(YogaTest, nested_overflowing_child) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 200); YGNodeStyleSetHeight(root_child0_child0, 200); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -64,18 +68,19 @@ TEST(YogaTest, nested_overflowing_child) { } TEST(YogaTest, nested_overflowing_child_in_constraint_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + 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); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 200); YGNodeStyleSetHeight(root_child0_child0, 200); YGNodeInsertChild(root_child0, root_child0_child0, 0); @@ -119,17 +124,18 @@ TEST(YogaTest, nested_overflowing_child_in_constraint_parent) { } TEST(YogaTest, parent_wrap_child_size_overflowing_parent) { - const YGConfigRef config = YGConfigNew(); + YGConfigRef config = YGConfigNew(); - const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); - const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0, 100); YGNodeInsertChild(root, root_child0, 0); - const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); YGNodeStyleSetWidth(root_child0_child0, 100); YGNodeStyleSetHeight(root_child0_child0, 200); YGNodeInsertChild(root_child0, root_child0_child0, 0); diff --git a/tests/generated/YGStaticPositionTest.cpp b/tests/generated/YGStaticPositionTest.cpp new file mode 100644 index 0000000000..d689f83fd8 --- /dev/null +++ b/tests/generated/YGStaticPositionTest.cpp @@ -0,0 +1,6074 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * clang-format off + * @generated SignedSource<<83ad08d246e0d406b525b1b1d5290b35>> + * generated by gentest/gentest-driver.ts from gentest/fixtures/YGStaticPositionTest.html + */ + +#include +#include +#include "../util/TestUtil.h" + +TEST(YogaTest, static_position_insets_have_no_effect_left_top) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 50); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 50); + 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, static_position_insets_have_no_effect_right_bottom) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeStatic); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, 50); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 50); + 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, static_position_absolute_child_insets_relative_to_positioned_ancestor) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_insets_relative_to_positioned_ancestor_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_reverse_static_position_absolute_child_insets_relative_to_positioned_ancestor_row_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_insets_relative_to_positioned_ancestor_row) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_reverse_static_position_absolute_child_insets_relative_to_positioned_ancestor_row) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_insets_relative_to_positioned_ancestor_column_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, column_reverse_static_position_absolute_child_insets_relative_to_positioned_ancestor_column_reverse) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_insets_relative_to_positioned_ancestor_deep) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0, 100); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 100); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0_child0_child0_child0, YGEdgeLeft, 100); + YGNodeStyleSetWidth(root_child0_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0_child0, 100); + YGNodeInsertChild(root_child0_child0_child0_child0, root_child0_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPosition(root_child0_child0_child0_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0_child0_child0, root_child0_child0_child0_child0_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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(100, 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(100, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-350, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetLeft(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_width_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_width_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_width_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_height_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_height_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_height_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_left_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, 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)); + + 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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_left_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, 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)); + + 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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(100, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_left_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_right_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, 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)); + + 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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_right_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, 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)); + + 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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_right_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_top_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_top_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_top_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_bottom_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_bottom_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_bottom_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_margin_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_margin_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_margin_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetMarginPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_padding_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(-100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_padding_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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)); + + 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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_padding_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeLeft, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeTop, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeRight, 50); + YGNodeStyleSetPaddingPercent(root_child0_child0_child0, YGEdgeBottom, 50); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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)); + + 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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_border_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_border_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + 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); + 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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_border_percentage) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 200); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(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(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(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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(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(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, 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(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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_containing_block_padding_box) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_containing_block_padding_box) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_containing_block_padding_box) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(50, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_containing_block_content_box) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_relative_child_containing_block_content_box) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidthPercent(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_child_containing_block_content_box) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidthPercent(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 50); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_containing_block_padding_and_border) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 8); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 4); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 61); + 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(13, 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(160, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(239, 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(400, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(292, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(13, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-60, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(160, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(239, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 63); + 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(279, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-2, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_no_position_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 63); + 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(279, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-15, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_zero_for_inset_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeLeft, 0); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 63); + 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-1, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(279, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-265, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_start_inset_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeStart, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 63); + 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(11, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(279, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-2, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_end_inset_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeStyleSetWidth(root_child0, 500); + YGNodeStyleSetHeight(root_child0, 500); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child0_child0, 200); + YGNodeStyleSetHeight(root_child0_child0, 200); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeEnd, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 41); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 63); + 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(270, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, 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(513, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(506, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(279, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-261, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(306, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_row_reverse_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRowReverse); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetHeightPercent(root_child0_child0_child0, 12); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-128, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(133, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(133, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(23, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_column_reverse_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionColumnReverse); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(-82, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-15, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(-82, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_justify_flex_start_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(111, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_justify_flex_start_position_set_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 30); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(106, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_no_definite_size_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeLeft, 23); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(133, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(133, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_both_insets_set_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPositionPercent(root_child0_child0_child0, YGEdgeLeft, 23); + YGNodeStyleSetPosition(root_child0_child0_child0, YGEdgeRight, 13); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(9, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(69, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(79, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(56, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(73, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(-3, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_justify_center_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyCenter); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(85, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(111, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(85, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_justify_flex_end_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(111, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_align_flex_start_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0_child0, YGAlignFlexStart); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(111, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_align_center_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0_child0, YGAlignCenter); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(39, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(65, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(39, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_align_flex_end_amalgamation) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 9); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 9); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 11); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 13); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 6); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 7); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 8); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root_child0_child0, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeTop, 6); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeRight, 3); + YGNodeStyleSetMargin(root_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeLeft, 1); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeRight, 9); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeLeft, 8); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeTop, 10); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0_child0, YGEdgeBottom, 1); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 21); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child0_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child0_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child0_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0_child0, root_child0_child0_child0_child0, 0); + + YGNodeRef root_child0_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child1, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child1, 1); + + YGNodeRef root_child0_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child1_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child1_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child1_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child1_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child0_child1, root_child0_child0_child1_child0, 0); + + YGNodeRef root_child0_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2, YGEdgeBottom, 9); + YGNodeStyleSetWidthPercent(root_child0_child0_child2, 10); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child2, 2); + + YGNodeRef root_child0_child0_child2_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeLeft, 9); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeTop, 12); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeRight, 4); + YGNodeStyleSetMargin(root_child0_child0_child2_child0, YGEdgeBottom, 7); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeTop, 3); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeRight, 8); + YGNodeStyleSetPadding(root_child0_child0_child2_child0, YGEdgeBottom, 10); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeLeft, 2); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeTop, 1); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeRight, 5); + YGNodeStyleSetBorder(root_child0_child0_child2_child0, YGEdgeBottom, 9); + YGNodeStyleSetWidth(root_child0_child0_child2_child0, 100); + YGNodeStyleSetHeight(root_child0_child0_child2_child0, 50); + YGNodeInsertChild(root_child0_child0_child2, root_child0_child0_child2_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(111, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(131, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(215, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(301, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(4, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(202, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(295, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(21, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(166, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(244, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(-77, YGNodeLayoutGetLeft(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(29, YGNodeLayoutGetTop(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child1)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child1)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child1_child0)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(140, YGNodeLayoutGetTop(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0_child0_child2)); + ASSERT_FLOAT_EQ(92, YGNodeLayoutGetHeight(root_child0_child0_child2)); + + ASSERT_FLOAT_EQ(-97, YGNodeLayoutGetLeft(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(16, YGNodeLayoutGetTop(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child2_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_static_root) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeStatic); + YGNodeStyleSetPadding(root, YGEdgeLeft, 6); + YGNodeStyleSetPadding(root, YGEdgeTop, 1); + YGNodeStyleSetPadding(root, YGEdgeRight, 11); + YGNodeStyleSetPadding(root, YGEdgeBottom, 4); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 200); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 12); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 11); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 15); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 1); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 3); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 7); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 4); + YGNodeStyleSetBorder(root_child0, YGEdgeLeft, 4); + YGNodeStyleSetBorder(root_child0, YGEdgeTop, 3); + YGNodeStyleSetBorder(root_child0, YGEdgeRight, 2); + YGNodeStyleSetBorder(root_child0, YGEdgeBottom, 1); + 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(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, 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(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(24, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, static_position_absolute_child_multiple) { + YGConfigRef config = YGConfigNew(); + + YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + + YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPadding(root_child0, YGEdgeLeft, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeTop, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeRight, 100); + YGNodeStyleSetPadding(root_child0, YGEdgeBottom, 100); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 400); + YGNodeInsertChild(root, root_child0, 0); + + YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeStyleSetHeight(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child0_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child0_child0, 10); + YGNodeStyleSetHeight(root_child0_child0_child0, 50); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeRef root_child0_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child1, YGPositionTypeStatic); + YGNodeStyleSetWidth(root_child0_child1, 100); + YGNodeStyleSetHeight(root_child0_child1, 100); + YGNodeInsertChild(root_child0, root_child0_child1, 1); + + YGNodeRef root_child0_child1_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child1_child0, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child1_child0, 50); + YGNodeStyleSetHeight(root_child0_child1_child0, 50); + YGNodeInsertChild(root_child0_child1, root_child0_child1_child0, 0); + + YGNodeRef root_child0_child1_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child1_child1, YGPositionTypeAbsolute); + YGNodeStyleSetWidthPercent(root_child0_child1_child1, 50); + YGNodeStyleSetHeight(root_child0_child1_child1, 50); + YGNodeInsertChild(root_child0_child1, root_child0_child1_child1, 1); + + YGNodeRef root_child0_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetPositionType(root_child0_child2, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root_child0_child2, 25); + YGNodeStyleSetHeight(root_child0_child2, 50); + YGNodeInsertChild(root_child0, root_child0_child2, 2); + 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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, 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(40, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(100, 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)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child1_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1_child1)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + 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(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(60, 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(50, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(200, 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)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1_child0)); + + ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root_child0_child1_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child1_child1)); + + ASSERT_FLOAT_EQ(275, YGNodeLayoutGetLeft(root_child0_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child0_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/util/TestUtil.cpp b/tests/util/TestUtil.cpp new file mode 100644 index 0000000000..87166f7f4d --- /dev/null +++ b/tests/util/TestUtil.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "TestUtil.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook::yoga::test { + +int nodeInstanceCount = 0; + +namespace { + +void yogaEventSubscriber( + YGNodeConstRef /*node*/, + Event::Type eventType, + const Event::Data& /*eventData*/) { + switch (eventType) { + case Event::NodeAllocation: + nodeInstanceCount++; + break; + case Event::NodeDeallocation: + nodeInstanceCount--; + break; + default: + break; + } +} +} // namespace + +void TestUtil::startCountingNodes() { + nodeInstanceCount = 0; + Event::subscribe(yogaEventSubscriber); +} + +int TestUtil::nodeCount() { + return nodeInstanceCount; +} + +int TestUtil::stopCountingNodes() { + Event::reset(); + auto prev = nodeInstanceCount; + nodeInstanceCount = 0; + return prev; +} + +ScopedEventSubscription::ScopedEventSubscription( + std::function&& s) { + Event::subscribe(std::move(s)); +} + +ScopedEventSubscription::~ScopedEventSubscription() { + Event::reset(); +} + +YGSize IntrinsicSizeMeasure( + YGNodeConstRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode) { + std::string_view innerText((char*)YGNodeGetContext(node)); + float heightPerChar = 10; + float widthPerChar = 10; + float measuredWidth; + float measuredHeight; + + if (widthMode == YGMeasureModeExactly) { + measuredWidth = width; + } else if (widthMode == YGMeasureModeAtMost) { + measuredWidth = std::min((float)innerText.size() * widthPerChar, width); + } else { + measuredWidth = (float)innerText.size() * widthPerChar; + } + + if (heightMode == YGMeasureModeExactly) { + measuredHeight = height; + } else if (heightMode == YGMeasureModeAtMost) { + measuredHeight = std::min( + calculateHeight( + innerText, + YGNodeStyleGetFlexDirection(node) == YGFlexDirectionColumn + ? measuredWidth + : std::max( + longestWordWidth(innerText, widthPerChar), measuredWidth), + widthPerChar, + heightPerChar), + height); + } else { + measuredHeight = calculateHeight( + innerText, + YGNodeStyleGetFlexDirection(node) == YGFlexDirectionColumn + ? measuredWidth + : std::max( + longestWordWidth(innerText, widthPerChar), measuredWidth), + widthPerChar, + heightPerChar); + } + + return YGSize{measuredWidth, measuredHeight}; +} + +float longestWordWidth(std::string_view text, float widthPerChar) { + int maxLength = 0; + int currentLength = 0; + for (auto c : text) { + if (c == ' ') { + maxLength = std::max(currentLength, maxLength); + currentLength = 0; + } else { + currentLength++; + } + } + return (float)std::max(currentLength, maxLength) * widthPerChar; +} + +float calculateHeight( + std::string_view text, + float measuredWidth, + float widthPerChar, + float heightPerChar) { + if ((float)text.size() * widthPerChar <= measuredWidth) { + return heightPerChar; + } + + std::vector words; + std::istringstream iss((std::string)text); + std::string currentWord; + while (getline(iss, currentWord, ' ')) { + words.push_back(currentWord); + } + + float lines = 1; + float currentLineLength = 0; + for (const std::string& word : words) { + float wordWidth = (float)word.length() * widthPerChar; + if (wordWidth > measuredWidth) { + if (currentLineLength > 0) { + lines++; + } + lines++; + currentLineLength = 0; + } else if (currentLineLength + wordWidth <= measuredWidth) { + currentLineLength += wordWidth + widthPerChar; + } else { + lines++; + currentLineLength = wordWidth + widthPerChar; + } + } + return (currentLineLength == 0 ? lines - 1 : lines) * heightPerChar; +} + +} // namespace facebook::yoga::test diff --git a/tests/util/TestUtil.h b/tests/util/TestUtil.h new file mode 100644 index 0000000000..4326c3bd73 --- /dev/null +++ b/tests/util/TestUtil.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga::test { + +struct TestUtil { + static void startCountingNodes(); + static int nodeCount(); + static int stopCountingNodes(); +}; + +struct ScopedEventSubscription { + explicit ScopedEventSubscription(std::function&&); + ~ScopedEventSubscription(); +}; + +YGSize IntrinsicSizeMeasure( + YGNodeConstRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode); + +float longestWordWidth(std::string_view text, float widthPerChar); + +float calculateHeight( + std::string_view text, + float measuredWidth, + float widthPerChar, + float heightPerChar); + +} // namespace facebook::yoga::test diff --git a/yoga/BitUtils.h b/yoga/BitUtils.h deleted file mode 100644 index 2161effc7b..0000000000 --- a/yoga/BitUtils.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "YGEnums.h" - -namespace facebook { -namespace yoga { - -namespace detail { - -constexpr size_t log2ceilFn(size_t n) { - return n < 1 ? 0 : (1 + log2ceilFn(n / 2)); -} - -constexpr int mask(size_t bitWidth, size_t index) { - return ((1 << bitWidth) - 1) << index; -} - -// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL -template -constexpr size_t bitWidthFn() { - static_assert( - enums::count() > 0, "Enums must have at least one entries"); - return log2ceilFn(enums::count() - 1); -} - -template -constexpr Enum getEnumData(int flags, size_t index) { - return static_cast((flags & mask(bitWidthFn(), index)) >> index); -} - -template -void setEnumData(uint32_t& flags, size_t index, int newValue) { - flags = (flags & ~mask(bitWidthFn(), index)) | - ((newValue << index) & (mask(bitWidthFn(), index))); -} - -template -void setEnumData(uint8_t& flags, size_t index, int newValue) { - flags = (flags & ~static_cast(mask(bitWidthFn(), index))) | - ((newValue << index) & - (static_cast(mask(bitWidthFn(), index)))); -} - -constexpr bool getBooleanData(int flags, size_t index) { - return (flags >> index) & 1; -} - -inline void setBooleanData(uint8_t& flags, size_t index, bool value) { - if (value) { - flags |= 1 << index; - } else { - flags &= ~(1 << index); - } -} - -} // namespace detail -} // namespace yoga -} // namespace facebook diff --git a/yoga/CMakeLists.txt b/yoga/CMakeLists.txt new file mode 100644 index 0000000000..b6eca1ac72 --- /dev/null +++ b/yoga/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + + +cmake_minimum_required(VERSION 3.13...3.26) +project(yogacore) +set(CMAKE_VERBOSE_MAKEFILE on) + +if(TARGET yogacore) + return() +endif() + +include(CheckIPOSupported) + +set(YOGA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/..) +include(${YOGA_ROOT}/cmake/project-defaults.cmake) + + +file(GLOB SOURCES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/**/*.cpp) + +add_library(yogacore STATIC ${SOURCES}) + +# Yoga conditionally uses when building for Android +if (ANDROID) + target_link_libraries(yogacore log) +endif() + +check_ipo_supported(RESULT result) +if(result) + set_target_properties(yogacore PROPERTIES + CMAKE_INTERPROCEDURAL_OPTIMIZATION true) +endif() + +target_include_directories(yogacore + PUBLIC + $ + $) diff --git a/yoga/CompactValue.h b/yoga/CompactValue.h deleted file mode 100644 index def5533a54..0000000000 --- a/yoga/CompactValue.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "YGValue.h" -#include "YGMacros.h" -#include -#include -#include - -static_assert( - std::numeric_limits::is_iec559, - "facebook::yoga::detail::CompactValue only works with IEEE754 floats"); - -#ifdef YOGA_COMPACT_VALUE_TEST -#define VISIBLE_FOR_TESTING public: -#else -#define VISIBLE_FOR_TESTING private: -#endif - -namespace facebook { -namespace yoga { -namespace detail { - -// This class stores YGValue in 64 bits. -// - The value does not matter for Undefined and Auto. NaNs are used for their -// representation. -// - To differentiate between Point and Percent, one exponent bit is used. -// Supported the range [0x40, 0xbf] (0xbf is inclusive for point, but -// exclusive for percent). -// - Value ranges: -// points: 1.08420217e-19f to 36893485948395847680 -// 0x00000000 0x3fffffff -// percent: 1.08420217e-19f to 18446742974197923840 -// 0x40000000 0x7f7fffff -// - Zero is supported, negative zero is not -// - values outside of the representable range are clamped -class YOGA_EXPORT CompactValue { - friend constexpr bool operator==(CompactValue, CompactValue) noexcept; - -public: - static constexpr auto LOWER_BOUND = 1.4916681462400413e-154; - static constexpr auto UPPER_BOUND_POINT = 2.6815615859885191e+154; - static constexpr auto UPPER_BOUND_PERCENT = 1.0474849945267653e+152; - - template - static CompactValue of(double value) noexcept { - if (value == 0.0 || (value < LOWER_BOUND && value > -LOWER_BOUND)) { - constexpr auto zero = - Unit == YGUnitPercent ? ZERO_BITS_PERCENT : ZERO_BITS_POINT; - return {Payload{zero}}; - } - - constexpr auto upperBound = - Unit == YGUnitPercent ? UPPER_BOUND_PERCENT : UPPER_BOUND_POINT; - if (value > upperBound || value < -upperBound) { - value = copysign(upperBound, value); - } - - uint64_t unitBit = Unit == YGUnitPercent ? PERCENT_BIT : 0; - auto data = Payload{value}; - data.repr -= BIAS; - data.repr |= unitBit; - return {data}; - } - - template - static CompactValue ofMaybe(double value) noexcept { - return std::isnan(value) || std::isinf(value) ? ofUndefined() - : of(value); - } - - static constexpr CompactValue ofZero() noexcept { - return CompactValue{Payload{ZERO_BITS_POINT}}; - } - - static constexpr CompactValue ofUndefined() noexcept { - return CompactValue{}; - } - - static constexpr CompactValue ofAuto() noexcept { - return CompactValue{Payload{AUTO_BITS}}; - } - - constexpr CompactValue() noexcept - : payload_(std::numeric_limits::quiet_NaN()) {} - - CompactValue(const YGValue& x) noexcept : payload_(uint64_t{0}) { - switch (x.unit) { - case YGUnitUndefined: - *this = ofUndefined(); - break; - case YGUnitAuto: - *this = ofAuto(); - break; - case YGUnitPoint: - *this = of(x.value); - break; - case YGUnitPercent: - *this = of(x.value); - break; - } - } - - operator YGValue() const noexcept { - switch (payload_.repr) { - case AUTO_BITS: - return YGValueAuto; - case ZERO_BITS_POINT: - return YGValue{0.0, YGUnitPoint}; - case ZERO_BITS_PERCENT: - return YGValue{0.0, YGUnitPercent}; - } - - if (std::isnan(payload_.value)) { - return YGValueUndefined; - } - - auto data = payload_; - data.repr &= ~PERCENT_BIT; - data.repr += BIAS; - - return YGValue{data.value, - payload_.repr & 0x4000000000000000 ? YGUnitPercent : YGUnitPoint}; - } - - bool isUndefined() const noexcept { - return ( - payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT && - payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value)); - } - - bool isAuto() const noexcept { return payload_.repr == AUTO_BITS; } - -private: - union Payload { - double value; - uint64_t repr; - Payload() = delete; - constexpr Payload(uint64_t r) : repr(r) {} - constexpr Payload(double v) : value(v) {} - }; - - static constexpr uint64_t BIAS = 0x2000000000000000; - static constexpr uint64_t PERCENT_BIT = 0x4000000000000000; - - // these are signaling NaNs with specific bit pattern as payload they will be - // silenced whenever going through an FPU operation on ARM + x86 - static constexpr uint64_t AUTO_BITS = 0x7faaaaaaaaaaaaaa; - static constexpr uint64_t ZERO_BITS_POINT = 0x7f8f0f0f0f0f0f0f; - static constexpr uint64_t ZERO_BITS_PERCENT = 0x7f80f0f0f0f0f0f0; - - constexpr CompactValue(Payload data) noexcept : payload_(data) {} - - Payload payload_; - - VISIBLE_FOR_TESTING uint64_t repr() { return payload_.repr; } -}; - -template <> -CompactValue CompactValue::of(double) noexcept = delete; -template <> -CompactValue CompactValue::of(double) noexcept = delete; -template <> -CompactValue CompactValue::ofMaybe(double) noexcept = delete; -template <> -CompactValue CompactValue::ofMaybe(double) noexcept = delete; - -constexpr bool operator==(CompactValue a, CompactValue b) noexcept { - return a.payload_.repr == b.payload_.repr; -} - -constexpr bool operator!=(CompactValue a, CompactValue b) noexcept { - return !(a == b); -} - -} // namespace detail -} // namespace yoga -} // namespace facebook diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp deleted file mode 100644 index fb74d90f2f..0000000000 --- a/yoga/Utils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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" -#include - -using namespace facebook; - -YGFlexDirection YGFlexDirectionCross( - const YGFlexDirection flexDirection, - const YGDirection direction) { - return YGFlexDirectionIsColumn(flexDirection) - ? YGResolveFlexDirection(YGFlexDirectionRow, direction) - : YGFlexDirectionColumn; -} - -double YGFloatMax(const double a, const double b) { - if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fmax(a, b); - } - return yoga::isUndefined(a) ? b : a; -} - -double YGFloatMin(const double a, const double b) { - if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fmin(a, b); - } - - return yoga::isUndefined(a) ? b : a; -} - -bool YGValueEqual(const YGValue& a, const YGValue& b) { - if (a.unit != b.unit) { - return false; - } - - if (a.unit == YGUnitUndefined || - (yoga::isUndefined(a.value) && yoga::isUndefined(b.value))) { - return true; - } - - return fabs(a.value - b.value) < 0.0001; -} - -bool YGFloatsEqual(const double a, const double b) { - if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fabs(a - b) < 0.0001; - } - return yoga::isUndefined(a) && yoga::isUndefined(b); -} - -bool YGDoubleEqual(const double a, const double b) { - if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { - return fabs(a - b) < 0.0001; - } - return yoga::isUndefined(a) && yoga::isUndefined(b); -} - -double YGFloatSanitize(const double val) { - return yoga::isUndefined(val) ? 0 : val; -} - -YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) { - if (op1 >= op2) { - return op1; - } - if (op2 > op1) { - return op2; - } - return op1.isUndefined() ? op2 : op1; -} - -void throwLogicalErrorWithMessage(const char* message) { - throw std::logic_error(message); -} diff --git a/yoga/Utils.h b/yoga/Utils.h deleted file mode 100644 index 0f275ae02a..0000000000 --- a/yoga/Utils.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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" -#include "CompactValue.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 including 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; - double sizeConsumedOnCurrentLine; - double totalFlexGrowFactors; - double totalFlexShrinkScaledFactors; - uint32_t endOfLineIndex; - std::vector relativeChildren; - double 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. - double mainDim; - // The size of the crossDim for the row after considering size, padding, - // margin and border of flex items. Used for calculating containers crossSize. - double crossDim; -}; - -bool YGValueEqual(const YGValue& a, const YGValue& b); -inline bool YGValueEqual( - facebook::yoga::detail::CompactValue a, - facebook::yoga::detail::CompactValue b) { - return YGValueEqual((YGValue) a, (YGValue) b); -} - -// This custom double equality function returns true if either absolute -// difference between two floats is less than 0.0001f or both are undefined. -bool YGFloatsEqual(const double a, const double b); - -bool YGDoubleEqual(const double a, const double b); - -double YGFloatMax(const double a, const double b); - -YGFloatOptional YGFloatOptionalMax( - const YGFloatOptional op1, - const YGFloatOptional op2); - -double YGFloatMin(const double a, const double b); - -// This custom double comparison function compares the array of double with -// YGFloatsEqual, as the default double comparison 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 -double YGFloatSanitize(const double val); - -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 double ownerSize) { - switch (value.unit) { - case YGUnitPoint: - return YGFloatOptional{value.value}; - case YGUnitPercent: - return YGFloatOptional{value.value * ownerSize * 0.01}; - default: - return YGFloatOptional{}; - } -} - -inline YGFloatOptional YGResolveValue( - yoga::detail::CompactValue value, - double ownerSize) { - return YGResolveValue((YGValue) value, ownerSize); -} - -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; -} - -inline YGFloatOptional YGResolveValueMargin( - yoga::detail::CompactValue value, - const double ownerSize) { - return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize); -} - -void throwLogicalErrorWithMessage(const char* message); diff --git a/yoga/YGConfig.cpp b/yoga/YGConfig.cpp index fb72e80cfc..dcc1807f5e 100644 --- a/yoga/YGConfig.cpp +++ b/yoga/YGConfig.cpp @@ -1,44 +1,92 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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" +#include +#include +#include -YGConfig::YGConfig(YGLogger logger) : cloneNodeCallback_{nullptr} { - logger_.noContext = logger; - loggerUsesContext_ = false; +using namespace facebook; +using namespace facebook::yoga; + +YGConfigRef YGConfigNew(void) { + return new yoga::Config(getDefaultLogger()); +} + +void YGConfigFree(const YGConfigRef config) { + delete resolveRef(config); +} + +YGConfigConstRef YGConfigGetDefault() { + return &yoga::Config::getDefault(); +} + +void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled) { + resolveRef(config)->setUseWebDefaults(enabled); +} + +bool YGConfigGetUseWebDefaults(const YGConfigConstRef config) { + return resolveRef(config)->useWebDefaults(); +} + +void YGConfigSetPointScaleFactor( + const YGConfigRef config, + const double pixelsInPoint) { + yoga::assertFatalWithConfig( + resolveRef(config), + pixelsInPoint >= 0.0, + "Scale factor should not be less than zero"); + + resolveRef(config)->setPointScaleFactor(pixelsInPoint); +} + +double YGConfigGetPointScaleFactor(const YGConfigConstRef config) { + return resolveRef(config)->getPointScaleFactor(); } -void YGConfig::log( - YGConfig* config, - YGNode* node, - YGLogLevel logLevel, - void* logContext, - const char* format, - va_list args) { - if (loggerUsesContext_) { - logger_.withContext(config, node, logLevel, logContext, format, args); +void YGConfigSetErrata(YGConfigRef config, YGErrata errata) { + resolveRef(config)->setErrata(scopedEnum(errata)); +} + +YGErrata YGConfigGetErrata(YGConfigConstRef config) { + return unscopedEnum(resolveRef(config)->getErrata()); +} + +void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { + if (logger != nullptr) { + resolveRef(config)->setLogger(logger); } else { - logger_.noContext(config, node, logLevel, format, args); + resolveRef(config)->setLogger(getDefaultLogger()); } } -YGNodeRef YGConfig::cloneNode( - YGNodeRef node, - YGNodeRef owner, - int childIndex, - void* cloneContext) { - YGNodeRef clone = nullptr; - if (cloneNodeCallback_.noContext != nullptr) { - clone = cloneNodeUsesContext_ - ? cloneNodeCallback_.withContext(node, owner, childIndex, cloneContext) - : cloneNodeCallback_.noContext(node, owner, childIndex); - } - if (clone == nullptr) { - clone = YGNodeClone(node); - } - return clone; +void YGConfigSetContext(const YGConfigRef config, void* context) { + resolveRef(config)->setContext(context); +} + +void* YGConfigGetContext(const YGConfigConstRef config) { + return resolveRef(config)->getContext(); +} + +void YGConfigSetExperimentalFeatureEnabled( + const YGConfigRef config, + const YGExperimentalFeature feature, + const bool enabled) { + resolveRef(config)->setExperimentalFeatureEnabled( + scopedEnum(feature), enabled); +} + +bool YGConfigIsExperimentalFeatureEnabled( + const YGConfigConstRef config, + const YGExperimentalFeature feature) { + return resolveRef(config)->isExperimentalFeatureEnabled(scopedEnum(feature)); +} + +void YGConfigSetCloneNodeFunc( + const YGConfigRef config, + const YGCloneNodeFunc callback) { + resolveRef(config)->setCloneNodeCallback(callback); } diff --git a/yoga/YGConfig.h b/yoga/YGConfig.h index 7e1e3f06a8..4c2b33c119 100644 --- a/yoga/YGConfig.h +++ b/yoga/YGConfig.h @@ -1,76 +1,158 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 YOGA_EXPORT YGConfig { - using LogWithContextFn = int (*)( - YGConfigRef config, - YGNodeRef node, - YGLogLevel level, - void* context, - const char* format, - va_list args); - using CloneWithContextFn = YGNodeRef (*)( - YGNodeRef node, - YGNodeRef owner, - int childIndex, - void* cloneContext); - -private: - union { - CloneWithContextFn withContext; - YGCloneNodeFunc noContext; - } cloneNodeCallback_; - union { - LogWithContextFn withContext; - YGLogger noContext; - } logger_; - bool cloneNodeUsesContext_; - bool loggerUsesContext_; - -public: - bool useWebDefaults = false; - bool useLegacyStretchBehaviour = false; - bool shouldDiffLayoutWithoutLegacyStretchBehaviour = false; - bool printTree = false; - double pointScaleFactor = 1.0; - std::array()> - experimentalFeatures = {}; - void* context = nullptr; - - YGConfig(YGLogger logger); - void log(YGConfig*, YGNode*, YGLogLevel, void*, const char*, va_list); - void setLogger(YGLogger logger) { - logger_.noContext = logger; - loggerUsesContext_ = false; - } - void setLogger(LogWithContextFn logger) { - logger_.withContext = logger; - loggerUsesContext_ = true; - } - void setLogger(std::nullptr_t) { setLogger(YGLogger{nullptr}); } - - YGNodeRef cloneNode( - YGNodeRef node, - YGNodeRef owner, - int childIndex, - void* cloneContext); - void setCloneNodeCallback(YGCloneNodeFunc cloneNode) { - cloneNodeCallback_.noContext = cloneNode; - cloneNodeUsesContext_ = false; - } - void setCloneNodeCallback(CloneWithContextFn cloneNode) { - cloneNodeCallback_.withContext = cloneNode; - cloneNodeUsesContext_ = true; - } - void setCloneNodeCallback(std::nullptr_t) { - setCloneNodeCallback(YGCloneNodeFunc{nullptr}); - } -}; + +#include +#include +#include + +#include +#include + +YG_EXTERN_C_BEGIN + +typedef struct YGNode* YGNodeRef; +typedef const struct YGNode* YGNodeConstRef; + +/** + * Handle to a mutable Yoga configuration. + */ +typedef struct YGConfig* YGConfigRef; + +/** + * Handle to an immutable Yoga configuration. + */ +typedef const struct YGConfig* YGConfigConstRef; + +/** + * Allocates a set of configuration options. The configuration may be applied to + * multiple nodes (i.e. a single global config), or can be applied more + * granularly per-node. + */ +YG_EXPORT YGConfigRef YGConfigNew(void); + +/** + * Frees the associated Yoga configuration. + */ +YG_EXPORT void YGConfigFree(YGConfigRef config); + +/** + * Returns the default config values set by Yoga. + */ +YG_EXPORT YGConfigConstRef YGConfigGetDefault(void); + +/** + * Yoga by default creates new nodes with style defaults different from flexbox + * on web (e.g. `YGFlexDirectionColumn` and `YGPositionRelative`). + * `UseWebDefaults` instructs Yoga to instead use a default style consistent + * with the web. + */ +YG_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled); + +/** + * Whether the configuration is set to use web defaults. + */ +YG_EXPORT bool YGConfigGetUseWebDefaults(YGConfigConstRef config); + +/** + * Yoga will by default round final layout positions and dimensions to the + * nearst point. `pointScaleFactor` controls the density of the grid used for + * layout rounding (e.g. to round to the closest display pixel). + * + * May be set to 0.0 to avoid rounding the layout results. + */ +YG_EXPORT void YGConfigSetPointScaleFactor( + YGConfigRef config, + double pixelsInPoint); + +/** + * Get the currently set point scale factor. + */ +YG_EXPORT double YGConfigGetPointScaleFactor(YGConfigConstRef config); + +/** + * Configures how Yoga balances W3C conformance vs compatibility with layouts + * created against earlier versions of Yoga. + * + * By default Yoga will prioritize W3C conformance. `Errata` may be set to ask + * Yoga to produce specific incorrect behaviors. E.g. `YGConfigSetErrata(config, + * YGErrataStretchFlexBasis)`. + * + * YGErrata is a bitmask, and multiple errata may be set at once. Predefined + * constants exist for convenience: + * 1. YGErrataNone: No errata + * 2. YGErrataClassic: Match layout behaviors of Yoga 1.x + * 3. YGErrataAll: Match layout behaviors of Yoga 1.x, including + * `UseLegacyStretchBehaviour` + */ +YG_EXPORT void YGConfigSetErrata(YGConfigRef config, YGErrata errata); + +/** + * Get the currently set errata. + */ +YG_EXPORT YGErrata YGConfigGetErrata(YGConfigConstRef config); + +/** + * Function pointer type for YGConfigSetLogger. + */ +typedef int (*YGLogger)( + YGConfigConstRef config, + YGNodeConstRef node, + YGLogLevel level, + const char* format, + va_list args); + +/** + * Set a custom log function for to use when logging diagnostics or fatal. + * errors. + */ +YG_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger); + +/** + * Sets an arbitrary context pointer on the config which may be read from during + * callbacks. + */ +YG_EXPORT void YGConfigSetContext(YGConfigRef config, void* context); + +/** + * Gets the currently set context. + */ +YG_EXPORT void* YGConfigGetContext(YGConfigConstRef config); + +/** + * Function pointer type for YGConfigSetCloneNodeFunc. + */ +typedef YGNodeRef (*YGCloneNodeFunc)( + YGNodeConstRef oldNode, + YGNodeConstRef owner, + size_t childIndex); + +/** + * Enable an experimental/unsupported feature in Yoga. + */ +YG_EXPORT void YGConfigSetExperimentalFeatureEnabled( + YGConfigRef config, + YGExperimentalFeature feature, + bool enabled); + +/** + * Whether an experimental feature is set. + */ +YG_EXPORT bool YGConfigIsExperimentalFeatureEnabled( + YGConfigConstRef config, + YGExperimentalFeature feature); + +/** + * Sets a callback, called during layout, to create a new mutable Yoga node if + * Yoga must write to it and its owner is not its parent observed during layout. + */ +YG_EXPORT void YGConfigSetCloneNodeFunc( + YGConfigRef config, + YGCloneNodeFunc callback); + +YG_EXTERN_C_END diff --git a/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index c01d3d94b3..4bdace6b7a 100644 --- a/yoga/YGEnums.cpp +++ b/yoga/YGEnums.cpp @@ -1,11 +1,13 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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" +// @generated by enums.py +// clang-format off +#include const char* YGAlignToString(const YGAlign value) { switch (value) { @@ -25,6 +27,18 @@ const char* YGAlignToString(const YGAlign value) { return "space-between"; case YGAlignSpaceAround: return "space-around"; + case YGAlignSpaceEvenly: + return "space-evenly"; + } + return "unknown"; +} + +const char* YGBoxSizingToString(const YGBoxSizing value) { + switch (value) { + case YGBoxSizingBorderBox: + return "border-box"; + case YGBoxSizingContentBox: + return "content-box"; } return "unknown"; } @@ -57,6 +71,8 @@ const char* YGDisplayToString(const YGDisplay value) { return "flex"; case YGDisplayNone: return "none"; + case YGDisplayContents: + return "contents"; } return "unknown"; } @@ -85,6 +101,24 @@ const char* YGEdgeToString(const YGEdge value) { return "unknown"; } +const char* YGErrataToString(const YGErrata value) { + switch (value) { + case YGErrataNone: + return "none"; + case YGErrataStretchFlexBasis: + return "stretch-flex-basis"; + case YGErrataAbsolutePositionWithoutInsetsExcludesPadding: + return "absolute-position-without-insets-excludes-padding"; + case YGErrataAbsolutePercentAgainstInnerSize: + return "absolute-percent-against-inner-size"; + case YGErrataAll: + return "all"; + case YGErrataClassic: + return "classic"; + } + return "unknown"; +} + const char* YGExperimentalFeatureToString(const YGExperimentalFeature value) { switch (value) { case YGExperimentalFeatureWebFlexBasis: @@ -107,6 +141,18 @@ const char* YGFlexDirectionToString(const YGFlexDirection value) { return "unknown"; } +const char* YGGutterToString(const YGGutter value) { + switch (value) { + case YGGutterColumn: + return "column"; + case YGGutterRow: + return "row"; + case YGGutterAll: + return "all"; + } + return "unknown"; +} + const char* YGJustifyToString(const YGJustify value) { switch (value) { case YGJustifyFlexStart: @@ -189,18 +235,6 @@ const char* YGPositionTypeToString(const YGPositionType value) { 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: @@ -211,6 +245,12 @@ const char* YGUnitToString(const YGUnit value) { return "percent"; case YGUnitAuto: return "auto"; + case YGUnitMaxContent: + return "max-content"; + case YGUnitFitContent: + return "fit-content"; + case YGUnitStretch: + return "stretch"; } return "unknown"; } diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index d308634b7a..bb83bcfac9 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -1,64 +1,18 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ +// @generated by enums.py +// clang-format off #pragma once - -#include "YGMacros.h" - -#ifdef __cplusplus -YG_EXTERN_CXX_BEGIN -namespace facebook { -namespace yoga { -namespace enums { - -template -constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9 - -namespace detail { -template -constexpr int n() { - return sizeof...(xs); -} -} // namespace detail - -} // namespace enums -} // namespace yoga -} // namespace facebook -YG_EXTERN_CXX_END -#endif - -#define YG_ENUM_DECL(NAME, ...) \ - typedef YG_ENUM_BEGIN(NAME){__VA_ARGS__} YG_ENUM_END(NAME); \ - WIN_EXPORT const char* NAME##ToString(NAME); - -#ifdef __cplusplus -#define YG_ENUM_SEQ_DECL(NAME, ...) \ - YG_ENUM_DECL(NAME, __VA_ARGS__) \ - YG_EXTERN_C_END \ - YG_EXTERN_CXX_BEGIN \ - namespace facebook { \ - namespace yoga { \ - namespace enums { \ - template <> \ - constexpr int count() { \ - return detail::n<__VA_ARGS__>(); \ - } \ - } \ - } \ - } \ - YG_EXTERN_CXX_END \ - YG_EXTERN_C_BEGIN -#else -#define YG_ENUM_SEQ_DECL YG_ENUM_DECL -#endif +#include YG_EXTERN_C_BEGIN -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGAlign, YGAlignAuto, YGAlignFlexStart, @@ -67,19 +21,32 @@ YG_ENUM_SEQ_DECL( YGAlignStretch, YGAlignBaseline, YGAlignSpaceBetween, - YGAlignSpaceAround); + YGAlignSpaceAround, + YGAlignSpaceEvenly) + +YG_ENUM_DECL( + YGBoxSizing, + YGBoxSizingBorderBox, + YGBoxSizingContentBox) -YG_ENUM_SEQ_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight) +YG_ENUM_DECL( + YGDimension, + YGDimensionWidth, + YGDimensionHeight) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGDirection, YGDirectionInherit, YGDirectionLTR, YGDirectionRTL) -YG_ENUM_SEQ_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone) +YG_ENUM_DECL( + YGDisplay, + YGDisplayFlex, + YGDisplayNone, + YGDisplayContents) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGEdge, YGEdgeLeft, YGEdgeTop, @@ -91,16 +58,34 @@ YG_ENUM_SEQ_DECL( YGEdgeVertical, YGEdgeAll) -YG_ENUM_SEQ_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis) +YG_ENUM_DECL( + YGErrata, + YGErrataNone = 0, + YGErrataStretchFlexBasis = 1, + YGErrataAbsolutePositionWithoutInsetsExcludesPadding = 2, + YGErrataAbsolutePercentAgainstInnerSize = 4, + YGErrataAll = 2147483647, + YGErrataClassic = 2147483646) +YG_DEFINE_ENUM_FLAG_OPERATORS(YGErrata) + +YG_ENUM_DECL( + YGExperimentalFeature, + YGExperimentalFeatureWebFlexBasis) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGFlexDirection, YGFlexDirectionColumn, YGFlexDirectionColumnReverse, YGFlexDirectionRow, YGFlexDirectionRowReverse) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( + YGGutter, + YGGutterColumn, + YGGutterRow, + YGGutterAll) + +YG_ENUM_DECL( YGJustify, YGJustifyFlexStart, YGJustifyCenter, @@ -109,7 +94,7 @@ YG_ENUM_SEQ_DECL( YGJustifySpaceAround, YGJustifySpaceEvenly) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGLogLevel, YGLogLevelError, YGLogLevelWarn, @@ -118,42 +103,43 @@ YG_ENUM_SEQ_DECL( YGLogLevelVerbose, YGLogLevelFatal) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGMeasureMode, YGMeasureModeUndefined, YGMeasureModeExactly, YGMeasureModeAtMost) -YG_ENUM_SEQ_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText) +YG_ENUM_DECL( + YGNodeType, + YGNodeTypeDefault, + YGNodeTypeText) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGOverflow, YGOverflowVisible, YGOverflowHidden, YGOverflowScroll) -YG_ENUM_SEQ_DECL( +YG_ENUM_DECL( YGPositionType, YGPositionTypeStatic, YGPositionTypeRelative, YGPositionTypeAbsolute) YG_ENUM_DECL( - YGPrintOptions, - YGPrintOptionsLayout = 1, - YGPrintOptionsStyle = 2, - YGPrintOptionsChildren = 4) - -YG_ENUM_SEQ_DECL( YGUnit, YGUnitUndefined, YGUnitPoint, YGUnitPercent, - YGUnitAuto) + YGUnitAuto, + YGUnitMaxContent, + YGUnitFitContent, + YGUnitStretch) -YG_ENUM_SEQ_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse) +YG_ENUM_DECL( + YGWrap, + YGWrapNoWrap, + YGWrapWrap, + YGWrapWrapReverse) YG_EXTERN_C_END - -#undef YG_ENUM_DECL -#undef YG_ENUM_SEQ_DECL diff --git a/yoga/YGFloatOptional.h b/yoga/YGFloatOptional.h deleted file mode 100644 index dbb3b1658c..0000000000 --- a/yoga/YGFloatOptional.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "Yoga-internal.h" - -struct YGFloatOptional { -private: - double value_ = std::numeric_limits::quiet_NaN(); - -public: - explicit constexpr YGFloatOptional(double value) : value_(value) {} - constexpr YGFloatOptional() = default; - - // returns the wrapped value, or a value x with YGIsUndefined(x) == true - constexpr double unwrap() const { return value_; } - - bool isUndefined() const { return std::isnan(value_); } -}; - -// operators take YGFloatOptional by value, as it is a 32bit value - -inline bool operator==(YGFloatOptional lhs, YGFloatOptional rhs) { - return lhs.unwrap() == rhs.unwrap() || - (lhs.isUndefined() && rhs.isUndefined()); -} -inline bool operator!=(YGFloatOptional lhs, YGFloatOptional rhs) { - return !(lhs == rhs); -} - -inline bool operator==(YGFloatOptional lhs, double rhs) { - return lhs == YGFloatOptional{rhs}; -} -inline bool operator!=(YGFloatOptional lhs, double rhs) { - return !(lhs == rhs); -} - -inline bool operator==(double lhs, YGFloatOptional rhs) { - return rhs == lhs; -} -inline bool operator!=(double lhs, YGFloatOptional rhs) { - return !(lhs == rhs); -} - -inline YGFloatOptional operator+(YGFloatOptional lhs, YGFloatOptional rhs) { - return YGFloatOptional{lhs.unwrap() + rhs.unwrap()}; -} - -inline bool operator>(YGFloatOptional lhs, YGFloatOptional rhs) { - return lhs.unwrap() > rhs.unwrap(); -} - -inline bool operator<(YGFloatOptional lhs, YGFloatOptional rhs) { - return lhs.unwrap() < rhs.unwrap(); -} - -inline bool operator>=(YGFloatOptional lhs, YGFloatOptional rhs) { - return lhs > rhs || lhs == rhs; -} - -inline bool operator<=(YGFloatOptional lhs, YGFloatOptional rhs) { - return lhs < rhs || lhs == rhs; -} diff --git a/yoga/YGLayout.cpp b/yoga/YGLayout.cpp deleted file mode 100644 index e43213cdc6..0000000000 --- a/yoga/YGLayout.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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" - -using namespace facebook; - -bool YGLayout::operator==(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 (!yoga::isUndefined(measuredDimensions[0]) || - !yoga::isUndefined(layout.measuredDimensions[0])) { - isEqual = - isEqual && (measuredDimensions[0] == layout.measuredDimensions[0]); - } - if (!yoga::isUndefined(measuredDimensions[1]) || - !yoga::isUndefined(layout.measuredDimensions[1])) { - isEqual = - isEqual && (measuredDimensions[1] == layout.measuredDimensions[1]); - } - - return isEqual; -} diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h deleted file mode 100644 index 0153ba649d..0000000000 --- a/yoga/YGLayout.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "BitUtils.h" -#include "YGFloatOptional.h" -#include "Yoga-internal.h" - -using namespace facebook::yoga; - -struct YGLayout { - std::array position = {}; - std::array dimensions = {{YGUndefined, YGUndefined}}; - std::array margin = {}; - std::array border = {}; - std::array padding = {}; - -private: - static constexpr size_t directionOffset = 0; - static constexpr size_t didUseLegacyFlagOffset = - directionOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset = - didUseLegacyFlagOffset + 1; - static constexpr size_t hadOverflowOffset = - doesLegacyStretchFlagAffectsLayoutOffset + 1; - uint8_t flags = 0; - -public: - uint32_t computedFlexBasisGeneration = 0; - YGFloatOptional computedFlexBasis = {}; - - // Instead of recomputing the entire layout every single time, we cache some - // information to break early when nothing changed - uint32_t generationCount = 0; - YGDirection lastOwnerDirection = YGDirectionInherit; - - uint32_t nextCachedMeasurementsIndex = 0; - std::array - cachedMeasurements = {}; - std::array measuredDimensions = {{YGUndefined, YGUndefined}}; - - YGCachedMeasurement cachedLayout = YGCachedMeasurement(); - - YGDirection direction() const { - return facebook::yoga::detail::getEnumData( - flags, directionOffset); - } - - void setDirection(YGDirection direction) { - facebook::yoga::detail::setEnumData( - flags, directionOffset, direction); - } - - bool didUseLegacyFlag() const { - return facebook::yoga::detail::getBooleanData( - flags, didUseLegacyFlagOffset); - } - - void setDidUseLegacyFlag(bool val) { - facebook::yoga::detail::setBooleanData(flags, didUseLegacyFlagOffset, val); - } - - bool doesLegacyStretchFlagAffectsLayout() const { - return facebook::yoga::detail::getBooleanData( - flags, doesLegacyStretchFlagAffectsLayoutOffset); - } - - void setDoesLegacyStretchFlagAffectsLayout(bool val) { - facebook::yoga::detail::setBooleanData( - flags, doesLegacyStretchFlagAffectsLayoutOffset, val); - } - - bool hadOverflow() const { - return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset); - } - void setHadOverflow(bool hadOverflow) { - facebook::yoga::detail::setBooleanData( - flags, hadOverflowOffset, hadOverflow); - } - - bool operator==(YGLayout layout) const; - bool operator!=(YGLayout layout) const { return !(*this == layout); } -}; diff --git a/yoga/YGMacros.h b/yoga/YGMacros.h index 86cb619f06..a2b6d60efc 100644 --- a/yoga/YGMacros.h +++ b/yoga/YGMacros.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -8,35 +8,43 @@ #pragma once #ifdef __cplusplus -#define YG_EXTERN_CXX_BEGIN extern "C++" { -#define YG_EXTERN_CXX_END } +#include +#endif + +#ifdef __cplusplus #define YG_EXTERN_C_BEGIN extern "C" { #define YG_EXTERN_C_END } #else -#define YG_EXTERN_CXX_BEGIN -#define YG_EXTERN_CXX_END #define YG_EXTERN_C_BEGIN #define YG_EXTERN_C_END #endif -#ifdef _WINDLL -#define WIN_EXPORT __declspec(dllexport) +#if defined(__cplusplus) +#define YG_DEPRECATED(message) [[deprecated(message)]] +#elif defined(_MSC_VER) +#define YG_DEPRECATED(message) __declspec(deprecated(message)) #else -#define WIN_EXPORT +#define YG_DEPRECATED(message) __attribute__((deprecated(message))) #endif -#ifndef YOGA_EXPORT -#ifdef _MSC_VER -#define YOGA_EXPORT +#ifdef _WINDLL +#define YG_EXPORT __declspec(dllexport) +#elif !defined(_MSC_VER) +#define YG_EXPORT __attribute__((visibility("default"))) #else -#define YOGA_EXPORT __attribute__((visibility("default"))) +#define YG_EXPORT +#endif + +#ifdef __OBJC__ +#if __has_include() +#import #endif #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. +// the header is a mismatch for the Yoga ABI. #define YG_ENUM_BEGIN(name) NS_ENUM(int, name) #define YG_ENUM_END(name) #else @@ -44,14 +52,48 @@ #define YG_ENUM_END(name) name #endif -#ifdef __GNUC__ -#define YG_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define YG_DEPRECATED __declspec(deprecated) -#elif __cplusplus >= 201402L -#if defined(__has_cpp_attribute) -#if __has_cpp_attribute(deprecated) -#define YG_DEPRECATED [[deprecated]] -#endif -#endif +#ifdef __cplusplus +#define YG_DEFINE_ENUM_FLAG_OPERATORS(name) \ + extern "C++" { \ + constexpr name operator~(name a) { \ + return static_cast( \ + ~static_cast::type>(a)); \ + } \ + constexpr name operator|(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) | \ + static_cast::type>(b)); \ + } \ + constexpr name operator&(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) & \ + static_cast::type>(b)); \ + } \ + constexpr name operator^(name a, name b) { \ + return static_cast( \ + static_cast::type>(a) ^ \ + static_cast::type>(b)); \ + } \ + inline name& operator|=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) |= \ + static_cast::type>(b)); \ + } \ + inline name& operator&=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) &= \ + static_cast::type>(b)); \ + } \ + inline name& operator^=(name& a, name b) { \ + return reinterpret_cast( \ + reinterpret_cast::type&>(a) ^= \ + static_cast::type>(b)); \ + } \ + } +#else +#define YG_DEFINE_ENUM_FLAG_OPERATORS(name) #endif + +#define YG_ENUM_DECL(NAME, ...) \ + typedef YG_ENUM_BEGIN(NAME){__VA_ARGS__} YG_ENUM_END(NAME); \ + YG_EXPORT const char* NAME##ToString(NAME); diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 5b2cd50c36..dfc1410924 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -1,591 +1,366 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 -#include "CompactValue.h" -#include "Utils.h" +#include + +#include +#include +#include +#include +#include +#include using namespace facebook; -using facebook::yoga::detail::CompactValue; - -YGNode::YGNode(YGNode&& node) { - context_ = node.context_; - flags = node.flags; - measure_ = node.measure_; - baseline_ = node.baseline_; - print_ = node.print_; - dirtied_ = node.dirtied_; - style_ = node.style_; - layout_ = node.layout_; - lineIndex_ = node.lineIndex_; - owner_ = node.owner_; - children_ = std::move(node.children_); - config_ = node.config_; - resolvedDimensions_ = node.resolvedDimensions_; - for (auto c : children_) { - c->setOwner(this); - } +using namespace facebook::yoga; + +YGNodeRef YGNodeNew(void) { + return YGNodeNewWithConfig(YGConfigGetDefault()); } -YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} { - config_ = config; - if (config->useWebDefaults) { - useWebDefaults(); - } +YGNodeRef YGNodeNewWithConfig(const YGConfigConstRef config) { + auto* node = new yoga::Node{resolveRef(config)}; + yoga::assertFatal( + config != nullptr, "Tried to construct YGNode with null config"); + Event::publish(node, {config}); + + return node; } -void YGNode::print(void* printContext) { - if (print_.noContext != nullptr) { - if (facebook::yoga::detail::getBooleanData(flags, printUsesContext_)) { - print_.withContext(this, printContext); - } else { - print_.noContext(this); - } - } +YGNodeRef YGNodeClone(YGNodeConstRef oldNodeRef) { + auto oldNode = resolveRef(oldNodeRef); + const auto node = new yoga::Node(*oldNode); + Event::publish(node, {node->getConfig()}); + node->setOwner(nullptr); + return node; } -CompactValue YGNode::computeEdgeValueForRow( - const YGStyle::Edges& edges, - YGEdge rowEdge, - YGEdge edge, - CompactValue defaultValue) { - if (!edges[rowEdge].isUndefined()) { - return edges[rowEdge]; - } else if (!edges[edge].isUndefined()) { - return edges[edge]; - } else if (!edges[YGEdgeHorizontal].isUndefined()) { - return edges[YGEdgeHorizontal]; - } else if (!edges[YGEdgeAll].isUndefined()) { - return edges[YGEdgeAll]; - } else { - return defaultValue; +void YGNodeFree(const YGNodeRef nodeRef) { + const auto node = resolveRef(nodeRef); + + if (auto owner = node->getOwner()) { + owner->removeChild(node); + node->setOwner(nullptr); } -} -CompactValue YGNode::computeEdgeValueForColumn( - const YGStyle::Edges& edges, - YGEdge edge, - CompactValue defaultValue) { - if (!edges[edge].isUndefined()) { - return edges[edge]; - } else if (!edges[YGEdgeVertical].isUndefined()) { - return edges[YGEdgeVertical]; - } else if (!edges[YGEdgeAll].isUndefined()) { - return edges[YGEdgeAll]; - } else { - return defaultValue; + const size_t childCount = node->getChildCount(); + for (size_t i = 0; i < childCount; i++) { + auto child = node->getChild(i); + child->setOwner(nullptr); } -} -YGFloatOptional YGNode::getLeadingPosition( - const YGFlexDirection axis, - const double axisSize) const { - auto leadingPosition = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.position(), - YGEdgeStart, - leading[axis], - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.position(), leading[axis], CompactValue::ofZero()); - return YGResolveValue(leadingPosition, axisSize); -} - -YGFloatOptional YGNode::getTrailingPosition( - const YGFlexDirection axis, - const double axisSize) const { - auto trailingPosition = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.position(), - YGEdgeEnd, - trailing[axis], - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.position(), trailing[axis], CompactValue::ofZero()); - return YGResolveValue(trailingPosition, axisSize); -} - -bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const { - auto leadingPosition = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.position(), - YGEdgeStart, - leading[axis], - CompactValue::ofUndefined()) - : computeEdgeValueForColumn( - style_.position(), leading[axis], CompactValue::ofUndefined()); - return !leadingPosition.isUndefined(); -} - -bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const { - auto trailingPosition = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.position(), - YGEdgeEnd, - trailing[axis], - CompactValue::ofUndefined()) - : computeEdgeValueForColumn( - style_.position(), trailing[axis], CompactValue::ofUndefined()); - return !trailingPosition.isUndefined(); -} - -YGFloatOptional YGNode::getLeadingMargin( - const YGFlexDirection axis, - const double widthSize) const { - auto leadingMargin = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.margin(), leading[axis], CompactValue::ofZero()); - return YGResolveValueMargin(leadingMargin, widthSize); -} - -YGFloatOptional YGNode::getTrailingMargin( - const YGFlexDirection axis, - const double widthSize) const { - auto trailingMargin = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.margin(), trailing[axis], CompactValue::ofZero()); - return YGResolveValueMargin(trailingMargin, widthSize); -} - -YGFloatOptional YGNode::getMarginForAxis( - const YGFlexDirection axis, - const double widthSize) const { - return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); -} - -YGSize YGNode::measure( - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode, - void* layoutContext) { - return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_) - ? measure_.withContext( - this, width, widthMode, height, heightMode, layoutContext) - : measure_.noContext(this, width, widthMode, height, heightMode); -} + node->clearChildren(); -double YGNode::baseline(double width, double height, void* layoutContext) { - return facebook::yoga::detail::getBooleanData(flags, baselineUsesContext_) - ? baseline_.withContext(this, width, height, layoutContext) - : baseline_.noContext(this, width, height); + Event::publish(node, {YGNodeGetConfig(node)}); + delete resolveRef(node); } -// Setters +void YGNodeFreeRecursive(YGNodeRef rootRef) { + const auto root = resolveRef(rootRef); -void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) { - if (measureFunc.noContext == nullptr) { - // TODO: t18095186 Move nodeType to opt-in function and mark appropriate - // places in Litho - setNodeType(YGNodeTypeDefault); - } else { - YGAssertWithNode( - this, - children_.size() == 0, - "Cannot set measure function: Nodes with measure functions cannot have " - "children."); - // TODO: t18095186 Move nodeType to opt-in function and mark appropriate - // places in Litho - setNodeType(YGNodeTypeText); + size_t skipped = 0; + while (root->getChildCount() > skipped) { + const auto child = root->getChild(skipped); + if (child->getOwner() != root) { + // Don't free shared nodes that we don't own. + skipped += 1; + } else { + YGNodeRemoveChild(root, child); + YGNodeFreeRecursive(child); + } } - - measure_ = measureFunc; + YGNodeFree(root); } -void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) { - facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, false); - decltype(YGNode::measure_) m; - m.noContext = measureFunc; - setMeasureFunc(m); +void YGNodeFinalize(const YGNodeRef node) { + Event::publish(node, {YGNodeGetConfig(node)}); + delete resolveRef(node); } -YOGA_EXPORT void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) { - facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, true); - decltype(YGNode::measure_) m; - m.withContext = measureFunc; - setMeasureFunc(m); +void YGNodeReset(YGNodeRef node) { + resolveRef(node)->reset(); } -void YGNode::replaceChild(YGNodeRef child, uint32_t index) { - children_[index] = child; +void YGNodeCalculateLayout( + const YGNodeRef node, + const double ownerWidth, + const double ownerHeight, + const YGDirection ownerDirection) { + yoga::calculateLayout( + resolveRef(node), ownerWidth, ownerHeight, scopedEnum(ownerDirection)); } -void YGNode::replaceChild(YGNodeRef oldChild, YGNodeRef newChild) { - std::replace(children_.begin(), children_.end(), oldChild, newChild); +bool YGNodeGetHasNewLayout(YGNodeConstRef node) { + return resolveRef(node)->getHasNewLayout(); } -void YGNode::insertChild(YGNodeRef child, uint32_t index) { - children_.insert(children_.begin() + index, child); +void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) { + resolveRef(node)->setHasNewLayout(hasNewLayout); } -void YGNode::setDirty(bool isDirty) { - if (isDirty == facebook::yoga::detail::getBooleanData(flags, isDirty_)) { - return; - } - facebook::yoga::detail::setBooleanData(flags, isDirty_, isDirty); - if (isDirty && dirtied_) { - dirtied_(this); - } +bool YGNodeIsDirty(YGNodeConstRef node) { + return resolveRef(node)->isDirty(); } -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 YGNodeMarkDirty(const YGNodeRef nodeRef) { + const auto node = resolveRef(nodeRef); -void YGNode::removeChild(uint32_t index) { - children_.erase(children_.begin() + index); -} + yoga::assertFatalWithNode( + node, + node->hasMeasureFunc(), + "Only leaf nodes with custom measure functions " + "should manually mark themselves as dirty"); -void YGNode::setLayoutDirection(YGDirection direction) { - layout_.setDirection(direction); + node->markDirtyAndPropagate(); } -void YGNode::setLayoutMargin(double margin, int index) { - layout_.margin[index] = margin; +void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc) { + resolveRef(node)->setDirtiedFunc(dirtiedFunc); } -void YGNode::setLayoutBorder(double border, int index) { - layout_.border[index] = border; +YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeConstRef node) { + return resolveRef(node)->getDirtiedFunc(); } -void YGNode::setLayoutPadding(double padding, int index) { - layout_.padding[index] = padding; -} +void YGNodeInsertChild( + const YGNodeRef ownerRef, + const YGNodeRef childRef, + const size_t index) { + auto owner = resolveRef(ownerRef); + auto child = resolveRef(childRef); -void YGNode::setLayoutLastOwnerDirection(YGDirection direction) { - layout_.lastOwnerDirection = direction; -} + yoga::assertFatalWithNode( + owner, + child->getOwner() == nullptr, + "Child already has a owner, it must be removed first."); -void YGNode::setLayoutComputedFlexBasis( - const YGFloatOptional computedFlexBasis) { - layout_.computedFlexBasis = computedFlexBasis; -} + yoga::assertFatalWithNode( + owner, + !owner->hasMeasureFunc(), + "Cannot add child: Nodes with measure functions cannot have children."); -void YGNode::setLayoutPosition(double position, int index) { - layout_.position[index] = position; + owner->insertChild(child, index); + child->setOwner(owner); + owner->markDirtyAndPropagate(); } -void YGNode::setLayoutComputedFlexBasisGeneration( - uint32_t computedFlexBasisGeneration) { - layout_.computedFlexBasisGeneration = computedFlexBasisGeneration; -} +void YGNodeSwapChild( + const YGNodeRef ownerRef, + const YGNodeRef childRef, + const size_t index) { + auto owner = resolveRef(ownerRef); + auto child = resolveRef(childRef); -void YGNode::setLayoutMeasuredDimension(double measuredDimension, int index) { - layout_.measuredDimensions[index] = measuredDimension; + owner->replaceChild(child, index); + child->setOwner(owner); } -void YGNode::setLayoutHadOverflow(bool hadOverflow) { - layout_.setHadOverflow(hadOverflow); -} +void YGNodeRemoveChild( + const YGNodeRef ownerRef, + const YGNodeRef excludedChildRef) { + auto owner = resolveRef(ownerRef); + auto excludedChild = resolveRef(excludedChildRef); -void YGNode::setLayoutDimension(double dimension, int index) { - layout_.dimensions[index] = dimension; -} + if (owner->getChildCount() == 0) { + // This is an empty set. Nothing to remove. + return; + } -// 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 double axisSize) const { - if (isLeadingPositionDefined(axis)) { - return getLeadingPosition(axis, axisSize); + // Children may be shared between parents, which is indicated by not having an + // owner. We only want to reset the child completely if it is owned + // exclusively by one node. + auto childOwner = excludedChild->getOwner(); + if (owner->removeChild(excludedChild)) { + if (owner == childOwner) { + excludedChild->setLayout({}); // layout is no longer valid + excludedChild->setOwner(nullptr); + } + owner->markDirtyAndPropagate(); } +} - YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize); - if (!trailingPosition.isUndefined()) { - trailingPosition = YGFloatOptional{-1 * trailingPosition.unwrap()}; +void YGNodeRemoveAllChildren(const YGNodeRef ownerRef) { + auto owner = resolveRef(ownerRef); + + const size_t childCount = owner->getChildCount(); + if (childCount == 0) { + // This is an empty set already. Nothing to do. + return; } - return trailingPosition; -} - -void YGNode::setPosition( - const YGDirection direction, - const double mainSize, - const double crossSize, - const double 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); - - // Here we should check for `YGPositionTypeStatic` and in this case zero inset - // properties (left, right, top, bottom, begin, end). - // https://www.w3.org/TR/css-position-3/#valdef-position-static - const YGFloatOptional relativePositionMain = - relativePosition(mainAxis, mainSize); - const YGFloatOptional relativePositionCross = - relativePosition(crossAxis, crossSize); - - setLayoutPosition( - (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), - leading[mainAxis]); - setLayoutPosition( - (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), - trailing[mainAxis]); - setLayoutPosition( - (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross) - .unwrap(), - leading[crossAxis]); - setLayoutPosition( - (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross) - .unwrap(), - trailing[crossAxis]); -} - -YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const { - if (YGFlexDirectionIsRow(axis) && - !style_.margin()[YGEdgeStart].isUndefined()) { - return style_.margin()[YGEdgeStart]; - } else { - return style_.margin()[leading[axis]]; + auto* firstChild = owner->getChild(0); + if (firstChild->getOwner() == owner) { + // If the first child has this node as its owner, we assume that this child + // set is unique. + for (size_t i = 0; i < childCount; i++) { + yoga::Node* oldChild = owner->getChild(i); + oldChild->setLayout({}); // layout is no longer valid + oldChild->setOwner(nullptr); + } + owner->clearChildren(); + owner->markDirtyAndPropagate(); + return; } + // Otherwise, we are not the owner of the child set. We don't have to do + // anything to clear it. + owner->setChildren({}); + owner->markDirtyAndPropagate(); } -YGValue YGNode::marginTrailingValue(const YGFlexDirection axis) const { - if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) { - return style_.margin()[YGEdgeEnd]; +void YGNodeSetChildren( + const YGNodeRef ownerRef, + const YGNodeRef* childrenRefs, + const size_t count) { + auto owner = resolveRef(ownerRef); + auto children = reinterpret_cast(childrenRefs); + + if (owner == nullptr) { + return; + } + + const std::vector childrenVector = {children, children + count}; + if (childrenVector.empty()) { + if (owner->getChildCount() > 0) { + for (auto* child : owner->getChildren()) { + child->setLayout({}); + child->setOwner(nullptr); + } + owner->setChildren({}); + owner->markDirtyAndPropagate(); + } } else { - return style_.margin()[trailing[axis]]; + if (owner->getChildCount() > 0) { + for (auto* 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(childrenVector.begin(), childrenVector.end(), oldChild) == + childrenVector.end()) { + oldChild->setLayout({}); + oldChild->setOwner(nullptr); + } + } + } + owner->setChildren(childrenVector); + for (yoga::Node* child : childrenVector) { + child->setOwner(owner); + } + owner->markDirtyAndPropagate(); } } -YGValue YGNode::resolveFlexBasisPtr() const { - YGValue flexBasis = style_.flexBasis(); - if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { - return flexBasis; - } - if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0) { - return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) - ? YGValueAuto - : YGValueZero; +YGNodeRef YGNodeGetChild(const YGNodeRef nodeRef, const size_t index) { + const auto node = resolveRef(nodeRef); + + if (index < node->getChildren().size()) { + return node->getChild(index); } - return YGValueAuto; + return nullptr; } -void YGNode::resolveDimension() { - using namespace yoga; - const YGStyle& style = getStyle(); - for (auto dim : {YGDimensionWidth, YGDimensionHeight}) { - if (!style.maxDimensions()[dim].isUndefined() && - YGValueEqual(style.maxDimensions()[dim], style.minDimensions()[dim])) { - resolvedDimensions_[dim] = style.maxDimensions()[dim]; - } else { - resolvedDimensions_[dim] = style.dimensions()[dim]; - } - } +size_t YGNodeGetChildCount(const YGNodeConstRef node) { + return resolveRef(node)->getChildren().size(); } -YGDirection YGNode::resolveDirection(const YGDirection ownerDirection) { - if (style_.direction() == YGDirectionInherit) { - return ownerDirection > YGDirectionInherit ? ownerDirection - : YGDirectionLTR; - } else { - return style_.direction(); - } +YGNodeRef YGNodeGetOwner(const YGNodeRef node) { + return resolveRef(node)->getOwner(); } -YOGA_EXPORT void YGNode::clearChildren() { - children_.clear(); - children_.shrink_to_fit(); +YGNodeRef YGNodeGetParent(const YGNodeRef node) { + return resolveRef(node)->getOwner(); } -// Other Methods +void YGNodeSetConfig(YGNodeRef node, YGConfigRef config) { + resolveRef(node)->setConfig(resolveRef(config)); +} -void YGNode::cloneChildrenIfNeeded(void* cloneContext) { - iterChildrenAfterCloningIfNeeded([](YGNodeRef, void*) {}, cloneContext); +YGConfigConstRef YGNodeGetConfig(YGNodeRef node) { + return resolveRef(node)->getConfig(); } -void YGNode::markDirtyAndPropogate() { - if (!facebook::yoga::detail::getBooleanData(flags, isDirty_)) { - setDirty(true); - setLayoutComputedFlexBasis(YGFloatOptional()); - if (owner_) { - owner_->markDirtyAndPropogate(); - } - } +void YGNodeSetContext(YGNodeRef node, void* context) { + return resolveRef(node)->setContext(context); } -void YGNode::markDirtyAndPropogateDownwards() { - facebook::yoga::detail::setBooleanData(flags, isDirty_, true); - for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) { - childNode->markDirtyAndPropogateDownwards(); - }); +void* YGNodeGetContext(YGNodeConstRef node) { + return resolveRef(node)->getContext(); } -double YGNode::resolveFlexGrow() const { - // Root nodes flexGrow should always be 0 - if (owner_ == nullptr) { - return 0.0; - } - if (!style_.flexGrow().isUndefined()) { - return style_.flexGrow().unwrap(); - } - if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0) { - return style_.flex().unwrap(); - } - return kDefaultFlexGrow; +void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc) { + resolveRef(node)->setMeasureFunc(measureFunc); } -double YGNode::resolveFlexShrink() const { - if (owner_ == nullptr) { - return 0.0; - } - if (!style_.flexShrink().isUndefined()) { - return style_.flexShrink().unwrap(); - } - if (!facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) && - !style_.flex().isUndefined() && style_.flex().unwrap() < 0.0) { - return -style_.flex().unwrap(); - } - return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) - ? kWebDefaultFlexShrink - : kDefaultFlexShrink; -} - -bool YGNode::isNodeFlexible() { - return ( - (style_.positionType() != YGPositionTypeAbsolute) && - (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); -} - -double YGNode::getLeadingBorder(const YGFlexDirection axis) const { - YGValue leadingBorder = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.border(), leading[axis], CompactValue::ofZero()); - return fmax(leadingBorder.value, 0.0); -} - -double YGNode::getTrailingBorder(const YGFlexDirection axis) const { - YGValue trailingBorder = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.border(), trailing[axis], CompactValue::ofZero()); - return fmax(trailingBorder.value, 0.0); -} - -YGFloatOptional YGNode::getLeadingPadding( - const YGFlexDirection axis, - const double widthSize) const { - auto leadingPadding = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.padding(), - YGEdgeStart, - leading[axis], - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.padding(), leading[axis], CompactValue::ofZero()); - return YGResolveValue(leadingPadding, widthSize); -} - -YGFloatOptional YGNode::getTrailingPadding( - const YGFlexDirection axis, - const double widthSize) const { - auto trailingPadding = YGFlexDirectionIsRow(axis) - ? computeEdgeValueForRow( - style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.padding(), trailing[axis], CompactValue::ofZero()); - return YGResolveValue(trailingPadding, widthSize); -} - -YGFloatOptional YGNode::getLeadingPaddingAndBorder( - const YGFlexDirection axis, - const double widthSize) const { - return getLeadingPadding(axis, widthSize) + - YGFloatOptional(getLeadingBorder(axis)); -} - -YGFloatOptional YGNode::getTrailingPaddingAndBorder( - const YGFlexDirection axis, - const double 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; +bool YGNodeHasMeasureFunc(YGNodeConstRef node) { + return resolveRef(node)->hasMeasureFunc(); } -void YGNode::setLayoutDoesLegacyFlagAffectsLayout( - bool doesLegacyFlagAffectsLayout) { - layout_.setDoesLegacyStretchFlagAffectsLayout(doesLegacyFlagAffectsLayout); +void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc) { + resolveRef(node)->setBaselineFunc(baselineFunc); } -void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) { - layout_.setDidUseLegacyFlag(didUseLegacyFlag); +bool YGNodeHasBaselineFunc(YGNodeConstRef node) { + return resolveRef(node)->hasBaselineFunc(); } -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; +void YGNodeSetIsReferenceBaseline(YGNodeRef nodeRef, bool isReferenceBaseline) { + const auto node = resolveRef(nodeRef); + if (node->isReferenceBaseline() != isReferenceBaseline) { + node->setIsReferenceBaseline(isReferenceBaseline); + node->markDirtyAndPropagate(); } +} - 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; +bool YGNodeIsReferenceBaseline(YGNodeConstRef node) { + return resolveRef(node)->isReferenceBaseline(); } -void YGNode::reset() { - YGAssertWithNode( - this, - children_.size() == 0, - "Cannot reset a node which still has children attached"); - YGAssertWithNode( - this, owner_ == nullptr, "Cannot reset a node still attached to a owner"); +void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) { + return resolveRef(node)->setNodeType(scopedEnum(nodeType)); +} - clearChildren(); +YGNodeType YGNodeGetNodeType(YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->getNodeType()); +} - auto webDefaults = - facebook::yoga::detail::getBooleanData(flags, useWebDefaults_); - *this = YGNode{getConfig()}; - if (webDefaults) { - useWebDefaults(); - } +void YGNodeSetAlwaysFormsContainingBlock( + YGNodeRef node, + bool alwaysFormsContainingBlock) { + resolveRef(node)->setAlwaysFormsContainingBlock(alwaysFormsContainingBlock); +} + +bool YGNodeGetAlwaysFormsContainingBlock(YGNodeConstRef node) { + return resolveRef(node)->alwaysFormsContainingBlock(); +} + +// TODO: This leaks internal details to the public API. Remove after removing +// ComponentKit usage of it. +bool YGNodeCanUseCachedMeasurement( + YGMeasureMode widthMode, + double availableWidth, + YGMeasureMode heightMode, + double availableHeight, + YGMeasureMode lastWidthMode, + double lastAvailableWidth, + YGMeasureMode lastHeightMode, + double lastAvailableHeight, + double lastComputedWidth, + double lastComputedHeight, + double marginRow, + double marginColumn, + YGConfigRef config) { + return yoga::canUseCachedMeasurement( + sizingMode(scopedEnum(widthMode)), + availableWidth, + sizingMode(scopedEnum(heightMode)), + availableHeight, + sizingMode(scopedEnum(lastWidthMode)), + lastAvailableWidth, + sizingMode(scopedEnum(lastHeightMode)), + lastAvailableHeight, + lastComputedWidth, + lastComputedHeight, + marginRow, + marginColumn, + resolveRef(config)); } diff --git a/yoga/YGNode.h b/yoga/YGNode.h index 5b4195429b..196db54bc7 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -7,342 +7,298 @@ #pragma once -#ifdef __cplusplus - -#include -#include -#include "BitUtils.h" -#include "CompactValue.h" -#include "YGConfig.h" -#include "YGLayout.h" -#include "YGStyle.h" -#include "YGMacros.h" -#include "Yoga-internal.h" - -YGConfigRef YGConfigGetDefault(); - -struct YOGA_EXPORT YGNode { - using MeasureWithContextFn = - YGSize (*)(YGNode*, double, YGMeasureMode, double, YGMeasureMode, void*); - using BaselineWithContextFn = double (*)(YGNode*, double, double, void*); - using PrintWithContextFn = void (*)(YGNode*, void*); - -private: - static constexpr size_t hasNewLayout_ = 0; - static constexpr size_t isReferenceBaseline_ = 1; - static constexpr size_t isDirty_ = 2; - static constexpr size_t nodeType_ = 3; - static constexpr size_t measureUsesContext_ = 4; - static constexpr size_t baselineUsesContext_ = 5; - static constexpr size_t printUsesContext_ = 6; - static constexpr size_t useWebDefaults_ = 7; - - const void* context_ = nullptr; - uint8_t flags = 1; - uint8_t reserved_ = 0; - union { - YGMeasureFunc noContext; - MeasureWithContextFn withContext; - } measure_ = {nullptr}; - union { - YGBaselineFunc noContext; - BaselineWithContextFn withContext; - } baseline_ = {nullptr}; - union { - YGPrintFunc noContext; - PrintWithContextFn withContext; - } print_ = {nullptr}; - YGDirtiedFunc dirtied_ = nullptr; - YGStyle style_ = {}; - YGLayout layout_ = {}; - uint32_t lineIndex_ = 0; - YGNodeRef owner_ = nullptr; - YGVector children_ = {}; - YGConfigRef config_; - std::array resolvedDimensions_ = { - {YGValueUndefined, YGValueUndefined}}; - - YGFloatOptional relativePosition( - const YGFlexDirection axis, - const double axisSize) const; - - void setMeasureFunc(decltype(measure_)); - void setBaselineFunc(decltype(baseline_)); - - void useWebDefaults() { - facebook::yoga::detail::setBooleanData(flags, useWebDefaults_, true); - style_.flexDirection() = YGFlexDirectionRow; - style_.alignContent() = YGAlignStretch; - } - - // DANGER DANGER DANGER! - // If the node assigned to has children, we'd either have to deallocate - // them (potentially incorrect) or ignore them (danger of leaks). Only ever - // use this after checking that there are no children. - // DO NOT CHANGE THE VISIBILITY OF THIS METHOD! - YGNode& operator=(YGNode&&) = default; - - using CompactValue = facebook::yoga::detail::CompactValue; - -public: - YGNode() : YGNode{YGConfigGetDefault()} {} - explicit YGNode(const YGConfigRef config) : config_{config} { - if (config->useWebDefaults) { - useWebDefaults(); - } - }; - ~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree - - YGNode(YGNode&&); - - // Does not expose true value semantics, as children are not cloned eagerly. - // Should we remove this? - YGNode(const YGNode& node) = default; - - // for RB fabric - YGNode(const YGNode& node, YGConfigRef config); - - // assignment means potential leaks of existing children, or alternatively - // freeing unowned memory, double free, or freeing stack memory. - YGNode& operator=(const YGNode&) = delete; - - // Getters - const void* getContext() const { return context_; } - - uint8_t& reserved() { return reserved_; } - uint8_t reserved() const { return reserved_; } - - void print(void*); - - bool getHasNewLayout() const { - return facebook::yoga::detail::getBooleanData(flags, hasNewLayout_); - } - - YGNodeType getNodeType() const { - return facebook::yoga::detail::getEnumData(flags, nodeType_); - } - - bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; } - - YGSize measure(double, YGMeasureMode, double, YGMeasureMode, void*); - - bool hasBaselineFunc() const noexcept { - return baseline_.noContext != nullptr; - } - - double baseline(double width, double height, void* layoutContext); - - YGDirtiedFunc getDirtied() const { return dirtied_; } - - // For Performance reasons passing as reference. - YGStyle& getStyle() { return style_; } - - const YGStyle& getStyle() const { return style_; } - - // For Performance reasons passing as reference. - YGLayout& getLayout() { return layout_; } - - const YGLayout& getLayout() const { return layout_; } - - uint32_t getLineIndex() const { return lineIndex_; } - - bool isReferenceBaseline() { - return facebook::yoga::detail::getBooleanData(flags, isReferenceBaseline_); - } - - // 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 { return owner_; } - - // Deprecated, use getOwner() instead. - YGNodeRef getParent() const { return getOwner(); } - - const YGVector& getChildren() const { return children_; } - - // Applies a callback to all children, after cloning them if they are not - // owned. - template - void iterChildrenAfterCloningIfNeeded(T callback, void* cloneContext) { - int i = 0; - for (YGNodeRef& child : children_) { - if (child->getOwner() != this) { - child = config_->cloneNode(child, this, i, cloneContext); - child->setOwner(this); - } - i += 1; - - callback(child, cloneContext); - } - } - - YGNodeRef getChild(uint32_t index) const { return children_.at(index); } - - YGConfigRef getConfig() const { return config_; } - - bool isDirty() const { - return facebook::yoga::detail::getBooleanData(flags, isDirty_); - } - - std::array getResolvedDimensions() const { - return resolvedDimensions_; - } - - YGValue getResolvedDimension(int index) const { - return resolvedDimensions_[index]; - } - - static CompactValue computeEdgeValueForColumn( - const YGStyle::Edges& edges, - YGEdge edge, - CompactValue defaultValue); - - static CompactValue computeEdgeValueForRow( - const YGStyle::Edges& edges, - YGEdge rowEdge, - YGEdge edge, - CompactValue defaultValue); - - // Methods related to positions, margin, padding and border - YGFloatOptional getLeadingPosition( - const YGFlexDirection axis, - const double axisSize) const; - bool isLeadingPositionDefined(const YGFlexDirection axis) const; - bool isTrailingPosDefined(const YGFlexDirection axis) const; - YGFloatOptional getTrailingPosition( - const YGFlexDirection axis, - const double axisSize) const; - YGFloatOptional getLeadingMargin( - const YGFlexDirection axis, - const double widthSize) const; - YGFloatOptional getTrailingMargin( - const YGFlexDirection axis, - const double widthSize) const; - double getLeadingBorder(const YGFlexDirection flexDirection) const; - double getTrailingBorder(const YGFlexDirection flexDirection) const; - YGFloatOptional getLeadingPadding( - const YGFlexDirection axis, - const double widthSize) const; - YGFloatOptional getTrailingPadding( - const YGFlexDirection axis, - const double widthSize) const; - YGFloatOptional getLeadingPaddingAndBorder( - const YGFlexDirection axis, - const double widthSize) const; - YGFloatOptional getTrailingPaddingAndBorder( - const YGFlexDirection axis, - const double widthSize) const; - YGFloatOptional getMarginForAxis( - const YGFlexDirection axis, - const double widthSize) const; - // Setters - - void setContext(const void* context) { context_ = context; } - - void setPrintFunc(YGPrintFunc printFunc) { - print_.noContext = printFunc; - facebook::yoga::detail::setBooleanData(flags, printUsesContext_, false); - } - void setPrintFunc(PrintWithContextFn printFunc) { - print_.withContext = printFunc; - facebook::yoga::detail::setBooleanData(flags, printUsesContext_, true); - } - void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); } - - void setHasNewLayout(bool hasNewLayout) { - facebook::yoga::detail::setBooleanData(flags, hasNewLayout_, hasNewLayout); - } - - void setNodeType(YGNodeType nodeType) { - return facebook::yoga::detail::setEnumData( - flags, nodeType_, nodeType); - } - - void setMeasureFunc(YGMeasureFunc measureFunc); - void setMeasureFunc(MeasureWithContextFn); - void setMeasureFunc(std::nullptr_t) { - return setMeasureFunc(YGMeasureFunc{nullptr}); - } - - void setBaselineFunc(YGBaselineFunc baseLineFunc) { - facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, false); - baseline_.noContext = baseLineFunc; - } - void setBaselineFunc(BaselineWithContextFn baseLineFunc) { - facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, true); - baseline_.withContext = baseLineFunc; - } - void setBaselineFunc(std::nullptr_t) { - return setBaselineFunc(YGBaselineFunc{nullptr}); - } - - void setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { dirtied_ = dirtiedFunc; } - - void setStyle(const YGStyle& style) { style_ = style; } - - void setLayout(const YGLayout& layout) { layout_ = layout; } - - void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; } - - void setIsReferenceBaseline(bool isReferenceBaseline) { - facebook::yoga::detail::setBooleanData( - flags, isReferenceBaseline_, isReferenceBaseline); - } - - void setOwner(YGNodeRef owner) { owner_ = owner; } - - void setChildren(const YGVector& children) { children_ = children; } - - // TODO: rvalue override for setChildren - - YG_DEPRECATED void setConfig(YGConfigRef config) { config_ = config; } - - void setDirty(bool isDirty); - void setLayoutLastOwnerDirection(YGDirection direction); - void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis); - void setLayoutComputedFlexBasisGeneration( - uint32_t computedFlexBasisGeneration); - void setLayoutMeasuredDimension(double measuredDimension, int index); - void setLayoutHadOverflow(bool hadOverflow); - void setLayoutDimension(double dimension, int index); - void setLayoutDirection(YGDirection direction); - void setLayoutMargin(double margin, int index); - void setLayoutBorder(double border, int index); - void setLayoutPadding(double padding, int index); - void setLayoutPosition(double position, int index); - void setPosition( - const YGDirection direction, - const double mainSize, - const double crossSize, - const double ownerWidth); - 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*); - void markDirtyAndPropogate(); - double resolveFlexGrow() const; - double resolveFlexShrink() const; - bool isNodeFlexible(); - bool didUseLegacyFlag(); - bool isLayoutTreeEqualToNode(const YGNode& node) const; - void reset(); -}; - -#endif +#include +#include + +#include +#include +#include + +YG_EXTERN_C_BEGIN + +/** + * Handle to a mutable Yoga Node. + */ +typedef struct YGNode* YGNodeRef; + +/** + * Handle to an immutable Yoga Node. + */ +typedef const struct YGNode* YGNodeConstRef; + +/** + * Heap allocates and returns a new Yoga node using Yoga settings. + */ +YG_EXPORT YGNodeRef YGNodeNew(void); + +/** + * Heap allocates and returns a new Yoga node, with customized settings. + */ +YG_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigConstRef config); + +/** + * Returns a mutable copy of an existing node, with the same context and + * children, but no owner set. Does not call the function set by + * YGConfigSetCloneNodeFunc(). + */ +YG_EXPORT YGNodeRef YGNodeClone(YGNodeConstRef node); + +/** + * Frees the Yoga node, disconnecting it from its owner and children. + */ +YG_EXPORT void YGNodeFree(YGNodeRef node); + +/** + * Frees the subtree of Yoga nodes rooted at the given node. + */ +YG_EXPORT void YGNodeFreeRecursive(YGNodeRef node); + +/** + * Frees the Yoga node without disconnecting it from its owner or children. + * Allows garbage collecting Yoga nodes in parallel when the entire tree is + * unreachable. + */ +YG_EXPORT void YGNodeFinalize(YGNodeRef node); + +/** + * Resets the node to its default state. + */ +YG_EXPORT void YGNodeReset(YGNodeRef node); + +/** + * Calculates the layout of the tree rooted at the given node. + * + * Layout results may be read after calling YGNodeCalculateLayout() using + * functions like YGNodeLayoutGetLeft(), YGNodeLayoutGetTop(), etc. + * + * YGNodeGetHasNewLayout() may be read to know if the layout of the node or its + * subtrees may have changed since the last time YGNodeCalculate() was called. + */ +YG_EXPORT void YGNodeCalculateLayout( + YGNodeRef node, + double availableWidth, + double availableHeight, + YGDirection ownerDirection); + +/** + * Whether the given node may have new layout results. Must be reset by calling + * YGNodeSetHasNewLayout(). + */ +YG_EXPORT bool YGNodeGetHasNewLayout(YGNodeConstRef node); + +/** + * Sets whether a nodes layout is considered new. + */ +YG_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout); + +/** + * Whether the node's layout results are dirty due to it or its children + * changing. + */ +YG_EXPORT bool YGNodeIsDirty(YGNodeConstRef node); + +/** + * Marks a node with custom measure function as dirty. + */ +YG_EXPORT void YGNodeMarkDirty(YGNodeRef node); + +typedef void (*YGDirtiedFunc)(YGNodeConstRef node); + +/** + * Called when a change is made to the Yoga tree which dirties this node. + */ +YG_EXPORT void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc); + +/** + * Returns a dirtied func if set. + */ +YG_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeConstRef node); + +/** + * Inserts a child node at the given index. + */ +YG_EXPORT void YGNodeInsertChild(YGNodeRef node, YGNodeRef child, size_t index); + +/** + * Replaces the child node at a given index with a new one. + */ +YG_EXPORT void YGNodeSwapChild(YGNodeRef node, YGNodeRef child, size_t index); + +/** + * Removes the given child node. + */ +YG_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); + +/** + * Removes all children nodes. + */ +YG_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node); + +/** + * Sets children according to the given list of nodes. + */ +YG_EXPORT void +YGNodeSetChildren(YGNodeRef owner, const YGNodeRef* children, size_t count); + +/** + * Get the child node at a given index. + */ +YG_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, size_t index); + +/** + * The number of child nodes. + */ +YG_EXPORT size_t YGNodeGetChildCount(YGNodeConstRef node); + +/** + * Get the parent/owner currently set for a node. + */ +YG_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node); + +/** + * Get the parent/owner currently set for a node. + */ +YG_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node); + +/** + * Set a new config for the node after creation. + */ +YG_EXPORT void YGNodeSetConfig(YGNodeRef node, YGConfigRef config); + +/** + * Get the config currently set on the node. + */ +YG_EXPORT YGConfigConstRef YGNodeGetConfig(YGNodeRef node); + +/** + * Sets extra data on the Yoga node which may be read from during callbacks. + */ +YG_EXPORT void YGNodeSetContext(YGNodeRef node, void* context); + +/** + * Returns the context or NULL if no context has been set. + */ +YG_EXPORT void* YGNodeGetContext(YGNodeConstRef node); + +typedef struct YGSize { + double width; + double height; +} YGSize; + +/** + * Returns the computed dimensions of the node, following the constraints of + * `widthMode` and `heightMode`: + * + * YGMeasureModeUndefined: The parent has not imposed any constraint on the + * child. It can be whatever size it wants. + * + * YGMeasureModeAtMost: The child can be as large as it wants up to the + * specified size. + * + * YGMeasureModeExactly: The parent has determined an exact size for the + * child. The child is going to be given those bounds regardless of how big it + * wants to be. + * + * @returns the size of the leaf node, measured under the given constraints. + */ +typedef YGSize (*YGMeasureFunc)( + YGNodeConstRef node, + double width, + YGMeasureMode widthMode, + double height, + YGMeasureMode heightMode); + +/** + * Allows providing custom measurements for a Yoga leaf node (usually for + * measuring text). YGNodeMarkDirty() must be set if content effecting the + * measurements of the node changes. + */ +YG_EXPORT void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc); + +/** + * Whether a measure function is set. + */ +YG_EXPORT bool YGNodeHasMeasureFunc(YGNodeConstRef node); + +/** + * @returns a defined offset to baseline (ascent). + */ +typedef double (*YGBaselineFunc)(YGNodeConstRef node, double width, double height); + +/** + * Set a custom function for determining the text baseline for use in baseline + * alignment. + */ +YG_EXPORT void YGNodeSetBaselineFunc( + YGNodeRef node, + YGBaselineFunc baselineFunc); + +/** + * Whether a baseline function is set. + */ +YG_EXPORT bool YGNodeHasBaselineFunc(YGNodeConstRef node); + +/** + * Sets this node should be considered the reference baseline among siblings. + */ +YG_EXPORT void YGNodeSetIsReferenceBaseline( + YGNodeRef node, + bool isReferenceBaseline); + +/** + * Whether this node is set as the reference baseline. + */ +YG_EXPORT bool YGNodeIsReferenceBaseline(YGNodeConstRef node); + +/** + * Sets whether a leaf node's layout results may be truncated during layout + * rounding. + */ +YG_EXPORT void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType); + +/** + * Wwhether a leaf node's layout results may be truncated during layout + * rounding. + */ +YG_EXPORT YGNodeType YGNodeGetNodeType(YGNodeConstRef node); + +/** + * Make it so that this node will always form a containing block for any + * descendant nodes. This is useful for when a node has a property outside of + * of Yoga that will form a containing block. For example, transforms or some of + * the others listed in + * https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block + */ +YG_EXPORT void YGNodeSetAlwaysFormsContainingBlock( + YGNodeRef node, + bool alwaysFormsContainingBlock); + +/** + * Whether the node will always form a containing block for any descendant. This + * can happen in situation where the client implements something like a + * transform that can affect containing blocks but is not handled by Yoga + * directly. + */ +YG_EXPORT bool YGNodeGetAlwaysFormsContainingBlock(YGNodeConstRef node); + +/** + * @deprecated + */ +YG_DEPRECATED( + "YGNodeCanUseCachedMeasurement may be removed in a future version of Yoga") +YG_EXPORT bool YGNodeCanUseCachedMeasurement( + YGMeasureMode widthMode, + double availableWidth, + YGMeasureMode heightMode, + double availableHeight, + YGMeasureMode lastWidthMode, + double lastAvailableWidth, + YGMeasureMode lastHeightMode, + double lastAvailableHeight, + double lastComputedWidth, + double lastComputedHeight, + double marginRow, + double marginColumn, + YGConfigRef config); + +YG_EXTERN_C_END diff --git a/yoga/YGNodeLayout.cpp b/yoga/YGNodeLayout.cpp new file mode 100644 index 0000000000..359feedc87 --- /dev/null +++ b/yoga/YGNodeLayout.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include + +using namespace facebook; +using namespace facebook::yoga; + +namespace { + +template +double getResolvedLayoutProperty(const YGNodeConstRef nodeRef, const Edge edge) { + const auto node = resolveRef(nodeRef); + yoga::assertFatalWithNode( + node, + edge <= Edge::End, + "Cannot get layout properties of multi-edge shorthands"); + + if (edge == Edge::Start) { + if (node->getLayout().direction() == Direction::RTL) { + return (node->getLayout().*LayoutMember)(PhysicalEdge::Right); + } else { + return (node->getLayout().*LayoutMember)(PhysicalEdge::Left); + } + } + + if (edge == Edge::End) { + if (node->getLayout().direction() == Direction::RTL) { + return (node->getLayout().*LayoutMember)(PhysicalEdge::Left); + } else { + return (node->getLayout().*LayoutMember)(PhysicalEdge::Right); + } + } + + return (node->getLayout().*LayoutMember)(static_cast(edge)); +} + +} // namespace + +double YGNodeLayoutGetLeft(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().position(PhysicalEdge::Left); +} + +double YGNodeLayoutGetTop(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().position(PhysicalEdge::Top); +} + +double YGNodeLayoutGetRight(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().position(PhysicalEdge::Right); +} + +double YGNodeLayoutGetBottom(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().position(PhysicalEdge::Bottom); +} + +double YGNodeLayoutGetWidth(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().dimension(Dimension::Width); +} + +double YGNodeLayoutGetHeight(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().dimension(Dimension::Height); +} + +YGDirection YGNodeLayoutGetDirection(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->getLayout().direction()); +} + +bool YGNodeLayoutGetHadOverflow(const YGNodeConstRef node) { + return resolveRef(node)->getLayout().hadOverflow(); +} + +double YGNodeLayoutGetMargin(YGNodeConstRef node, YGEdge edge) { + return getResolvedLayoutProperty<&LayoutResults::margin>( + node, scopedEnum(edge)); +} + +double YGNodeLayoutGetBorder(YGNodeConstRef node, YGEdge edge) { + return getResolvedLayoutProperty<&LayoutResults::border>( + node, scopedEnum(edge)); +} + +double YGNodeLayoutGetPadding(YGNodeConstRef node, YGEdge edge) { + return getResolvedLayoutProperty<&LayoutResults::padding>( + node, scopedEnum(edge)); +} diff --git a/yoga/YGNodeLayout.h b/yoga/YGNodeLayout.h new file mode 100644 index 0000000000..4cd92566f3 --- /dev/null +++ b/yoga/YGNodeLayout.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +YG_EXTERN_C_BEGIN + +YG_EXPORT double YGNodeLayoutGetLeft(YGNodeConstRef node); +YG_EXPORT double YGNodeLayoutGetTop(YGNodeConstRef node); +YG_EXPORT double YGNodeLayoutGetRight(YGNodeConstRef node); +YG_EXPORT double YGNodeLayoutGetBottom(YGNodeConstRef node); +YG_EXPORT double YGNodeLayoutGetWidth(YGNodeConstRef node); +YG_EXPORT double YGNodeLayoutGetHeight(YGNodeConstRef node); +YG_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeConstRef node); +YG_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeConstRef 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_EXPORT double YGNodeLayoutGetMargin(YGNodeConstRef node, YGEdge edge); +YG_EXPORT double YGNodeLayoutGetBorder(YGNodeConstRef node, YGEdge edge); +YG_EXPORT double YGNodeLayoutGetPadding(YGNodeConstRef node, YGEdge edge); + +YG_EXTERN_C_END diff --git a/yoga/YGNodePrint.cpp b/yoga/YGNodePrint.cpp deleted file mode 100644 index 72d147dbb7..0000000000 --- a/yoga/YGNodePrint.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#ifdef DEBUG -#include "YGNodePrint.h" -#include -#include "YGEnums.h" -#include "YGNode.h" -#include "Yoga-internal.h" -#include "Utils.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 YGStyle::Edges& 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.unwrap()); - } -} - -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 YGStyle::Edges& 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 YGStyle::Edges& edges, - const YGEdge edge) { - // TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account - auto value = (edge == YGEdgeLeft || edge == YGEdgeRight) - ? YGNode::computeEdgeValueForRow( - edges, edge, edge, detail::CompactValue::ofUndefined()) - : YGNode::computeEdgeValueForColumn( - edges, edge, detail::CompactValue::ofUndefined()); - appendNumberIfNotUndefined(base, str, value); -} - -void YGNodeToString( - std::string& str, - YGNodeRef node, - YGPrintOptions options, - uint32_t level) { - indent(str, level); - appendFormatedString(str, "
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=\""); - const auto& style = node->getStyle(); - if (style.flexDirection() != YGNode().getStyle().flexDirection()) { - appendFormatedString( - str, - "flex-direction: %s; ", - YGFlexDirectionToString(style.flexDirection())); - } - if (style.justifyContent() != YGNode().getStyle().justifyContent()) { - appendFormatedString( - str, - "justify-content: %s; ", - YGJustifyToString(style.justifyContent())); - } - if (style.alignItems() != YGNode().getStyle().alignItems()) { - appendFormatedString( - str, "align-items: %s; ", YGAlignToString(style.alignItems())); - } - if (style.alignContent() != YGNode().getStyle().alignContent()) { - appendFormatedString( - str, "align-content: %s; ", YGAlignToString(style.alignContent())); - } - if (style.alignSelf() != YGNode().getStyle().alignSelf()) { - appendFormatedString( - str, "align-self: %s; ", YGAlignToString(style.alignSelf())); - } - appendFloatOptionalIfDefined(str, "flex-grow", style.flexGrow()); - appendFloatOptionalIfDefined(str, "flex-shrink", style.flexShrink()); - appendNumberIfNotAuto(str, "flex-basis", style.flexBasis()); - appendFloatOptionalIfDefined(str, "flex", style.flex()); - - if (style.flexWrap() != YGNode().getStyle().flexWrap()) { - appendFormatedString( - str, "flex-wrap: %s; ", YGWrapToString(style.flexWrap())); - } - - if (style.overflow() != YGNode().getStyle().overflow()) { - appendFormatedString( - str, "overflow: %s; ", YGOverflowToString(style.overflow())); - } - - if (style.display() != YGNode().getStyle().display()) { - appendFormatedString( - str, "display: %s; ", YGDisplayToString(style.display())); - } - appendEdges(str, "margin", style.margin()); - appendEdges(str, "padding", style.padding()); - appendEdges(str, "border", style.border()); - - appendNumberIfNotAuto(str, "width", style.dimensions()[YGDimensionWidth]); - appendNumberIfNotAuto(str, "height", style.dimensions()[YGDimensionHeight]); - appendNumberIfNotAuto( - str, "max-width", style.maxDimensions()[YGDimensionWidth]); - appendNumberIfNotAuto( - str, "max-height", style.maxDimensions()[YGDimensionHeight]); - appendNumberIfNotAuto( - str, "min-width", style.minDimensions()[YGDimensionWidth]); - appendNumberIfNotAuto( - str, "min-height", style.minDimensions()[YGDimensionHeight]); - - if (style.positionType() != YGNode().getStyle().positionType()) { - appendFormatedString( - str, "position: %s; ", YGPositionTypeToString(style.positionType())); - } - - appendEdgeIfNotUndefined(str, "left", style.position(), YGEdgeLeft); - appendEdgeIfNotUndefined(str, "right", style.position(), YGEdgeRight); - appendEdgeIfNotUndefined(str, "top", style.position(), YGEdgeTop); - appendEdgeIfNotUndefined(str, "bottom", style.position(), YGEdgeBottom); - appendFormatedString(str, "\" "); - - if (node->hasMeasureFunc()) { - 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 -#endif diff --git a/yoga/YGNodePrint.h b/yoga/YGNodePrint.h deleted file mode 100644 index 3db504b460..0000000000 --- a/yoga/YGNodePrint.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#ifdef DEBUG -#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 -#endif diff --git a/yoga/YGNodeStyle.cpp b/yoga/YGNodeStyle.cpp new file mode 100644 index 0000000000..0aeb08fa4e --- /dev/null +++ b/yoga/YGNodeStyle.cpp @@ -0,0 +1,505 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +using namespace facebook; +using namespace facebook::yoga; + +namespace { + +template +void updateStyle(YGNodeRef node, ValueT value) { + auto& style = resolveRef(node)->style(); + if ((style.*GetterT)() != value) { + (style.*SetterT)(value); + resolveRef(node)->markDirtyAndPropagate(); + } +} + +template +void updateStyle(YGNodeRef node, IdxT idx, ValueT value) { + auto& style = resolveRef(node)->style(); + if ((style.*GetterT)(idx) != value) { + (style.*SetterT)(idx, value); + resolveRef(node)->markDirtyAndPropagate(); + } +} + +} // namespace + +void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeConstRef srcNode) { + auto dst = resolveRef(dstNode); + auto src = resolveRef(srcNode); + + if (dst->style() != src->style()) { + dst->setStyle(src->style()); + dst->markDirtyAndPropagate(); + } +} + +void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) { + updateStyle<&Style::direction, &Style::setDirection>(node, scopedEnum(value)); +} + +YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().direction()); +} + +void YGNodeStyleSetFlexDirection( + const YGNodeRef node, + const YGFlexDirection flexDirection) { + updateStyle<&Style::flexDirection, &Style::setFlexDirection>( + node, scopedEnum(flexDirection)); +} + +YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().flexDirection()); +} + +void YGNodeStyleSetJustifyContent( + const YGNodeRef node, + const YGJustify justifyContent) { + updateStyle<&Style::justifyContent, &Style::setJustifyContent>( + node, scopedEnum(justifyContent)); +} + +YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().justifyContent()); +} + +void YGNodeStyleSetAlignContent( + const YGNodeRef node, + const YGAlign alignContent) { + updateStyle<&Style::alignContent, &Style::setAlignContent>( + node, scopedEnum(alignContent)); +} + +YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().alignContent()); +} + +void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) { + updateStyle<&Style::alignItems, &Style::setAlignItems>( + node, scopedEnum(alignItems)); +} + +YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().alignItems()); +} + +void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) { + updateStyle<&Style::alignSelf, &Style::setAlignSelf>( + node, scopedEnum(alignSelf)); +} + +YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().alignSelf()); +} + +void YGNodeStyleSetPositionType( + const YGNodeRef node, + const YGPositionType positionType) { + updateStyle<&Style::positionType, &Style::setPositionType>( + node, scopedEnum(positionType)); +} + +YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().positionType()); +} + +void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) { + updateStyle<&Style::flexWrap, &Style::setFlexWrap>( + node, scopedEnum(flexWrap)); +} + +YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().flexWrap()); +} + +void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) { + updateStyle<&Style::overflow, &Style::setOverflow>( + node, scopedEnum(overflow)); +} + +YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().overflow()); +} + +void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) { + updateStyle<&Style::display, &Style::setDisplay>(node, scopedEnum(display)); +} + +YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().display()); +} + +void YGNodeStyleSetFlex(const YGNodeRef node, const double flex) { + updateStyle<&Style::flex, &Style::setFlex>(node, FloatOptional{flex}); +} + +double YGNodeStyleGetFlex(const YGNodeConstRef nodeRef) { + const auto node = resolveRef(nodeRef); + return node->style().flex().isUndefined() ? YGUndefined + : node->style().flex().unwrap(); +} + +void YGNodeStyleSetFlexGrow(const YGNodeRef node, const double flexGrow) { + updateStyle<&Style::flexGrow, &Style::setFlexGrow>( + node, FloatOptional{flexGrow}); +} + +double YGNodeStyleGetFlexGrow(const YGNodeConstRef nodeRef) { + const auto node = resolveRef(nodeRef); + return node->style().flexGrow().isUndefined() + ? Style::DefaultFlexGrow + : node->style().flexGrow().unwrap(); +} + +void YGNodeStyleSetFlexShrink(const YGNodeRef node, const double flexShrink) { + updateStyle<&Style::flexShrink, &Style::setFlexShrink>( + node, FloatOptional{flexShrink}); +} + +double YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) { + const auto node = resolveRef(nodeRef); + return node->style().flexShrink().isUndefined() + ? (node->getConfig()->useWebDefaults() ? Style::WebDefaultFlexShrink + : Style::DefaultFlexShrink) + : node->style().flexShrink().unwrap(); +} + +void YGNodeStyleSetFlexBasis(const YGNodeRef node, const double flexBasis) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::points(flexBasis)); +} + +void YGNodeStyleSetFlexBasisPercent( + const YGNodeRef node, + const double flexBasisPercent) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::percent(flexBasisPercent)); +} + +void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofAuto()); +} + +void YGNodeStyleSetFlexBasisMaxContent(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetFlexBasisFitContent(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetFlexBasisStretch(const YGNodeRef node) { + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().flexBasis(); +} + +void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, double points) { + updateStyle<&Style::position, &Style::setPosition>( + node, scopedEnum(edge), StyleLength::points(points)); +} + +void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, double percent) { + updateStyle<&Style::position, &Style::setPosition>( + node, scopedEnum(edge), StyleLength::percent(percent)); +} + +void YGNodeStyleSetPositionAuto(YGNodeRef node, YGEdge edge) { + updateStyle<&Style::position, &Style::setPosition>( + node, scopedEnum(edge), StyleLength::ofAuto()); +} + +YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { + return (YGValue)resolveRef(node)->style().position(scopedEnum(edge)); +} + +void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, double points) { + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), StyleLength::points(points)); +} + +void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, double percent) { + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), StyleLength::percent(percent)); +} + +void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), StyleLength::ofAuto()); +} + +YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { + return (YGValue)resolveRef(node)->style().margin(scopedEnum(edge)); +} + +void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, double points) { + updateStyle<&Style::padding, &Style::setPadding>( + node, scopedEnum(edge), StyleLength::points(points)); +} + +void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, double percent) { + updateStyle<&Style::padding, &Style::setPadding>( + node, scopedEnum(edge), StyleLength::percent(percent)); +} + +YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { + return (YGValue)resolveRef(node)->style().padding(scopedEnum(edge)); +} + +void YGNodeStyleSetBorder( + const YGNodeRef node, + const YGEdge edge, + const double border) { + updateStyle<&Style::border, &Style::setBorder>( + node, scopedEnum(edge), StyleLength::points(border)); +} + +double YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) { + auto border = resolveRef(node)->style().border(scopedEnum(edge)); + if (border.isUndefined() || border.isAuto()) { + return YGUndefined; + } + + return static_cast(border).value; +} + +void YGNodeStyleSetGap( + const YGNodeRef node, + const YGGutter gutter, + const double gapLength) { + updateStyle<&Style::gap, &Style::setGap>( + node, scopedEnum(gutter), StyleLength::points(gapLength)); +} + +void YGNodeStyleSetGapPercent(YGNodeRef node, YGGutter gutter, double percent) { + updateStyle<&Style::gap, &Style::setGap>( + node, scopedEnum(gutter), StyleLength::percent(percent)); +} + +YGValue YGNodeStyleGetGap(const YGNodeConstRef node, const YGGutter gutter) { + return (YGValue)resolveRef(node)->style().gap(scopedEnum(gutter)); +} + +void YGNodeStyleSetAspectRatio(const YGNodeRef node, const double aspectRatio) { + updateStyle<&Style::aspectRatio, &Style::setAspectRatio>( + node, FloatOptional{aspectRatio}); +} + +double YGNodeStyleGetAspectRatio(const YGNodeConstRef node) { + const FloatOptional op = resolveRef(node)->style().aspectRatio(); + return op.isUndefined() ? YGUndefined : op.unwrap(); +} + +void YGNodeStyleSetBoxSizing(YGNodeRef node, YGBoxSizing boxSizing) { + updateStyle<&Style::boxSizing, &Style::setBoxSizing>( + node, scopedEnum(boxSizing)); +} + +YGBoxSizing YGNodeStyleGetBoxSizing(const YGNodeConstRef node) { + return unscopedEnum(resolveRef(node)->style().boxSizing()); +} + +void YGNodeStyleSetWidth(YGNodeRef node, double points) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::points(points)); +} + +void YGNodeStyleSetWidthPercent(YGNodeRef node, double percent) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::percent(percent)); +} + +void YGNodeStyleSetWidthAuto(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofAuto()); +} + +void YGNodeStyleSetWidthMaxContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetWidthFitContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetWidthStretch(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().dimension(Dimension::Width); +} + +void YGNodeStyleSetHeight(YGNodeRef node, double points) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::points(points)); +} + +void YGNodeStyleSetHeightPercent(YGNodeRef node, double percent) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::percent(percent)); +} + +void YGNodeStyleSetHeightAuto(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofAuto()); +} + +void YGNodeStyleSetHeightMaxContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetHeightFitContent(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetHeightStretch(YGNodeRef node) { + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().dimension(Dimension::Height); +} + +void YGNodeStyleSetMinWidth(const YGNodeRef node, const double minWidth) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::points(minWidth)); +} + +void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const double minWidth) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::percent(minWidth)); +} + +void YGNodeStyleSetMinWidthMaxContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMinWidthFitContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMinWidthStretch(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().minDimension(Dimension::Width); +} + +void YGNodeStyleSetMinHeight(const YGNodeRef node, const double minHeight) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::points(minHeight)); +} + +void YGNodeStyleSetMinHeightPercent( + const YGNodeRef node, + const double minHeight) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::percent(minHeight)); +} + +void YGNodeStyleSetMinHeightMaxContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMinHeightFitContent(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMinHeightStretch(const YGNodeRef node) { + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().minDimension(Dimension::Height); +} + +void YGNodeStyleSetMaxWidth(const YGNodeRef node, const double maxWidth) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::points(maxWidth)); +} + +void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const double maxWidth) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::percent(maxWidth)); +} + +void YGNodeStyleSetMaxWidthMaxContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMaxWidthFitContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMaxWidthStretch(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Width); +} + +void YGNodeStyleSetMaxHeight(const YGNodeRef node, const double maxHeight) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::points(maxHeight)); +} + +void YGNodeStyleSetMaxHeightPercent( + const YGNodeRef node, + const double maxHeight) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::percent(maxHeight)); +} + +void YGNodeStyleSetMaxHeightMaxContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::ofMaxContent()); +} + +void YGNodeStyleSetMaxHeightFitContent(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::ofFitContent()); +} + +void YGNodeStyleSetMaxHeightStretch(const YGNodeRef node) { + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, StyleSizeLength::ofStretch()); +} + +YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { + return (YGValue)resolveRef(node)->style().maxDimension(Dimension::Height); +} diff --git a/yoga/YGNodeStyle.h b/yoga/YGNodeStyle.h new file mode 100644 index 0000000000..579e713df2 --- /dev/null +++ b/yoga/YGNodeStyle.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +YG_EXTERN_C_BEGIN + +YG_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeConstRef srcNode); + +YG_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction); +YG_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetFlexDirection( + YGNodeRef node, + YGFlexDirection flexDirection); +YG_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetJustifyContent( + YGNodeRef node, + YGJustify justifyContent); +YG_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetAlignContent(YGNodeRef node, YGAlign alignContent); +YG_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems); +YG_EXPORT YGAlign YGNodeStyleGetAlignItems(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf); +YG_EXPORT YGAlign YGNodeStyleGetAlignSelf(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetPositionType( + YGNodeRef node, + YGPositionType positionType); +YG_EXPORT YGPositionType YGNodeStyleGetPositionType(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap); +YG_EXPORT YGWrap YGNodeStyleGetFlexWrap(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetOverflow(YGNodeRef node, YGOverflow overflow); +YG_EXPORT YGOverflow YGNodeStyleGetOverflow(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetDisplay(YGNodeRef node, YGDisplay display); +YG_EXPORT YGDisplay YGNodeStyleGetDisplay(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetFlex(YGNodeRef node, double flex); +YG_EXPORT double YGNodeStyleGetFlex(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetFlexGrow(YGNodeRef node, double flexGrow); +YG_EXPORT double YGNodeStyleGetFlexGrow(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetFlexShrink(YGNodeRef node, double flexShrink); +YG_EXPORT double YGNodeStyleGetFlexShrink(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetFlexBasis(YGNodeRef node, double flexBasis); +YG_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, double flexBasis); +YG_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetFlexBasisStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node); + +YG_EXPORT void +YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, double position); +YG_EXPORT void +YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, double position); +YG_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge); +YG_EXPORT void YGNodeStyleSetPositionAuto(YGNodeRef node, YGEdge edge); + +YG_EXPORT +void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, double margin); +YG_EXPORT void +YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, double margin); +YG_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge); +YG_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge); + +YG_EXPORT void +YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, double padding); +YG_EXPORT void +YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, double padding); +YG_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge); + +YG_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, double border); +YG_EXPORT double YGNodeStyleGetBorder(YGNodeConstRef node, YGEdge edge); + +YG_EXPORT void +YGNodeStyleSetGap(YGNodeRef node, YGGutter gutter, double gapLength); +YG_EXPORT void +YGNodeStyleSetGapPercent(YGNodeRef node, YGGutter gutter, double gapLength); +YG_EXPORT YGValue YGNodeStyleGetGap(YGNodeConstRef node, YGGutter gutter); + +YG_EXPORT void YGNodeStyleSetBoxSizing(YGNodeRef node, YGBoxSizing boxSizing); +YG_EXPORT YGBoxSizing YGNodeStyleGetBoxSizing(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, double width); +YG_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, double width); +YG_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetWidthStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, double height); +YG_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, double height); +YG_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetHeightStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetMinWidth(YGNodeRef node, double minWidth); +YG_EXPORT void YGNodeStyleSetMinWidthPercent(YGNodeRef node, double minWidth); +YG_EXPORT void YGNodeStyleSetMinWidthMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinWidthFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinWidthStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetMinWidth(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetMinHeight(YGNodeRef node, double minHeight); +YG_EXPORT void YGNodeStyleSetMinHeightPercent(YGNodeRef node, double minHeight); +YG_EXPORT void YGNodeStyleSetMinHeightMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinHeightFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMinHeightStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetMinHeight(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetMaxWidth(YGNodeRef node, double maxWidth); +YG_EXPORT void YGNodeStyleSetMaxWidthPercent(YGNodeRef node, double maxWidth); +YG_EXPORT void YGNodeStyleSetMaxWidthMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxWidthFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxWidthStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetMaxWidth(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetMaxHeight(YGNodeRef node, double maxHeight); +YG_EXPORT void YGNodeStyleSetMaxHeightPercent(YGNodeRef node, double maxHeight); +YG_EXPORT void YGNodeStyleSetMaxHeightMaxContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxHeightFitContent(YGNodeRef node); +YG_EXPORT void YGNodeStyleSetMaxHeightStretch(YGNodeRef node); +YG_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node); + +YG_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, double aspectRatio); +YG_EXPORT double YGNodeStyleGetAspectRatio(YGNodeConstRef node); + +YG_EXTERN_C_END diff --git a/yoga/YGPixelGrid.cpp b/yoga/YGPixelGrid.cpp new file mode 100644 index 0000000000..f38a224588 --- /dev/null +++ b/yoga/YGPixelGrid.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include + +using namespace facebook; +using namespace facebook::yoga; + +double YGRoundValueToPixelGrid( + const double value, + const double pointScaleFactor, + const bool forceCeil, + const bool forceFloor) { + return yoga::roundValueToPixelGrid( + value, pointScaleFactor, forceCeil, forceFloor); +} diff --git a/yoga/YGPixelGrid.h b/yoga/YGPixelGrid.h new file mode 100644 index 0000000000..dd2ddb6f1f --- /dev/null +++ b/yoga/YGPixelGrid.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +YG_EXTERN_C_BEGIN + +/** + * Rounds a point value to the nearest whole pixel, given a pointScaleFactor + * describing pixel density. + * @returns the rounded value in points + */ +YG_EXPORT double YGRoundValueToPixelGrid( + double value, + double pointScaleFactor, + bool forceCeil, + bool forceFloor); + +YG_EXTERN_C_END diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp deleted file mode 100644 index e8033bdf4c..0000000000 --- a/yoga/YGStyle.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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" -#include "Utils.h" - -// Yoga specific properties, not compatible with flexbox specification -bool operator==(const YGStyle& lhs, const YGStyle& rhs) { - bool areNonFloatValuesEqual = lhs.direction() == rhs.direction() && - lhs.flexDirection() == rhs.flexDirection() && - lhs.justifyContent() == rhs.justifyContent() && - lhs.alignContent() == rhs.alignContent() && - lhs.alignItems() == rhs.alignItems() && - lhs.alignSelf() == rhs.alignSelf() && - lhs.positionType() == rhs.positionType() && - lhs.flexWrap() == rhs.flexWrap() && lhs.overflow() == rhs.overflow() && - lhs.display() == rhs.display() && - YGValueEqual(lhs.flexBasis(), rhs.flexBasis()) && - lhs.margin() == rhs.margin() && lhs.position() == rhs.position() && - lhs.padding() == rhs.padding() && lhs.border() == rhs.border() && - lhs.dimensions() == rhs.dimensions() && - lhs.minDimensions() == rhs.minDimensions() && - lhs.maxDimensions() == rhs.maxDimensions(); - - areNonFloatValuesEqual = areNonFloatValuesEqual && - lhs.flex().isUndefined() == rhs.flex().isUndefined(); - if (areNonFloatValuesEqual && !lhs.flex().isUndefined() && - !rhs.flex().isUndefined()) { - areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flex() == rhs.flex(); - } - - areNonFloatValuesEqual = areNonFloatValuesEqual && - lhs.flexGrow().isUndefined() == rhs.flexGrow().isUndefined(); - if (areNonFloatValuesEqual && !lhs.flexGrow().isUndefined()) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && lhs.flexGrow() == rhs.flexGrow(); - } - - areNonFloatValuesEqual = areNonFloatValuesEqual && - lhs.flexShrink().isUndefined() == rhs.flexShrink().isUndefined(); - if (areNonFloatValuesEqual && !rhs.flexShrink().isUndefined()) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && lhs.flexShrink() == rhs.flexShrink(); - } - - if (!(lhs.aspectRatio().isUndefined() && rhs.aspectRatio().isUndefined())) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && lhs.aspectRatio() == rhs.aspectRatio(); - } - - return areNonFloatValuesEqual; -} diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h deleted file mode 100644 index aab7599ccd..0000000000 --- a/yoga/YGStyle.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 - -#include -#include -#include -#include -#include "CompactValue.h" -#include "YGEnums.h" -#include "YGFloatOptional.h" -#include "Yoga-internal.h" -#include "Yoga.h" -#include "BitUtils.h" - -class YOGA_EXPORT YGStyle { - template - using Values = - facebook::yoga::detail::Values()>; - using CompactValue = facebook::yoga::detail::CompactValue; - -public: - using Dimensions = Values; - using Edges = Values; - - template - struct BitfieldRef { - YGStyle& style; - size_t offset; - operator T() const { - return facebook::yoga::detail::getEnumData(style.flags, offset); - } - BitfieldRef& operator=(T x) { - facebook::yoga::detail::setEnumData(style.flags, offset, x); - return *this; - } - }; - - template - struct Ref { - YGStyle& style; - operator T() const { return style.*Prop; } - Ref& operator=(T value) { - style.*Prop = value; - return *this; - } - }; - - template YGStyle::*Prop> - struct IdxRef { - struct Ref { - YGStyle& style; - Idx idx; - operator CompactValue() const { return (style.*Prop)[idx]; } - operator YGValue() const { return (style.*Prop)[idx]; } - Ref& operator=(CompactValue value) { - (style.*Prop)[idx] = value; - return *this; - } - }; - - YGStyle& style; - IdxRef& operator=(const Values& values) { - style.*Prop = values; - return *this; - } - operator const Values&() const { return style.*Prop; } - Ref operator[](Idx idx) { return {style, idx}; } - CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; } - }; - - YGStyle() { - alignContent() = YGAlignFlexStart; - alignItems() = YGAlignStretch; - } - ~YGStyle() = default; - -private: - static constexpr size_t directionOffset = 0; - static constexpr size_t flexdirectionOffset = - directionOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t justifyContentOffset = flexdirectionOffset + - facebook::yoga::detail::bitWidthFn(); - static constexpr size_t alignContentOffset = - justifyContentOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t alignItemsOffset = - alignContentOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t alignSelfOffset = - alignItemsOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t positionTypeOffset = - alignSelfOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t flexWrapOffset = - positionTypeOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t overflowOffset = - flexWrapOffset + facebook::yoga::detail::bitWidthFn(); - static constexpr size_t displayOffset = - overflowOffset + facebook::yoga::detail::bitWidthFn(); - - uint32_t flags = 0; - - YGFloatOptional flex_ = {}; - YGFloatOptional flexGrow_ = {}; - YGFloatOptional flexShrink_ = {}; - CompactValue flexBasis_ = CompactValue::ofAuto(); - Edges margin_ = {}; - Edges position_ = {}; - Edges padding_ = {}; - Edges border_ = {}; - Dimensions dimensions_{CompactValue::ofAuto()}; - Dimensions minDimensions_ = {}; - Dimensions maxDimensions_ = {}; - // Yoga specific properties, not compatible with flexbox specification - YGFloatOptional aspectRatio_ = {}; - -public: - // for library users needing a type - using ValueRepr = std::remove_reference::type; - - YGDirection direction() const { - return facebook::yoga::detail::getEnumData( - flags, directionOffset); - } - BitfieldRef direction() { return {*this, directionOffset}; } - - YGFlexDirection flexDirection() const { - return facebook::yoga::detail::getEnumData( - flags, flexdirectionOffset); - } - BitfieldRef flexDirection() { - return {*this, flexdirectionOffset}; - } - - YGJustify justifyContent() const { - return facebook::yoga::detail::getEnumData( - flags, justifyContentOffset); - } - BitfieldRef justifyContent() { - return {*this, justifyContentOffset}; - } - - YGAlign alignContent() const { - return facebook::yoga::detail::getEnumData( - flags, alignContentOffset); - } - BitfieldRef alignContent() { return {*this, alignContentOffset}; } - - YGAlign alignItems() const { - return facebook::yoga::detail::getEnumData( - flags, alignItemsOffset); - } - BitfieldRef alignItems() { return {*this, alignItemsOffset}; } - - YGAlign alignSelf() const { - return facebook::yoga::detail::getEnumData(flags, alignSelfOffset); - } - BitfieldRef alignSelf() { return {*this, alignSelfOffset}; } - - YGPositionType positionType() const { - return facebook::yoga::detail::getEnumData( - flags, positionTypeOffset); - } - BitfieldRef positionType() { - return {*this, positionTypeOffset}; - } - - YGWrap flexWrap() const { - return facebook::yoga::detail::getEnumData(flags, flexWrapOffset); - } - BitfieldRef flexWrap() { return {*this, flexWrapOffset}; } - - YGOverflow overflow() const { - return facebook::yoga::detail::getEnumData( - flags, overflowOffset); - } - BitfieldRef overflow() { return {*this, overflowOffset}; } - - YGDisplay display() const { - return facebook::yoga::detail::getEnumData(flags, displayOffset); - } - BitfieldRef display() { return {*this, displayOffset}; } - - YGFloatOptional flex() const { return flex_; } - Ref flex() { return {*this}; } - - YGFloatOptional flexGrow() const { return flexGrow_; } - Ref flexGrow() { return {*this}; } - - YGFloatOptional flexShrink() const { return flexShrink_; } - Ref flexShrink() { return {*this}; } - - CompactValue flexBasis() const { return flexBasis_; } - Ref flexBasis() { return {*this}; } - - const Edges& margin() const { return margin_; } - IdxRef margin() { return {*this}; } - - const Edges& position() const { return position_; } - IdxRef position() { return {*this}; } - - const Edges& padding() const { return padding_; } - IdxRef padding() { return {*this}; } - - const Edges& border() const { return border_; } - IdxRef border() { return {*this}; } - - const Dimensions& dimensions() const { return dimensions_; } - IdxRef dimensions() { return {*this}; } - - const Dimensions& minDimensions() const { return minDimensions_; } - IdxRef minDimensions() { - return {*this}; - } - - const Dimensions& maxDimensions() const { return maxDimensions_; } - IdxRef maxDimensions() { - return {*this}; - } - - // Yoga specific properties, not compatible with flexbox specification - YGFloatOptional aspectRatio() const { return aspectRatio_; } - Ref aspectRatio() { return {*this}; } -}; - -YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs); -YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) { - return !(lhs == rhs); -} - -#endif diff --git a/yoga/YGValue.cpp b/yoga/YGValue.cpp index aef8d55064..963fc35400 100644 --- a/yoga/YGValue.cpp +++ b/yoga/YGValue.cpp @@ -1,12 +1,20 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -#include "YGValue.h" +#include +#include -const YGValue YGValueZero = { 0, YGUnitPoint }; -const YGValue YGValueUndefined = { YGUndefined, YGUnitUndefined }; -const YGValue YGValueAuto = { YGUndefined, YGUnitAuto }; +using namespace facebook; +using namespace facebook::yoga; + +const YGValue YGValueZero = {0, YGUnitPoint}; +const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; +const YGValue YGValueAuto = {YGUndefined, YGUnitAuto}; + +bool YGFloatIsUndefined(const double value) { + return yoga::isUndefined(value); +} diff --git a/yoga/YGValue.h b/yoga/YGValue.h index 032c2fc71d..be2084fdc5 100644 --- a/yoga/YGValue.h +++ b/yoga/YGValue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -7,45 +7,56 @@ #pragma once -#include -#include "YGEnums.h" -#include "YGMacros.h" +#include -#if defined(_MSC_VER) && defined(__clang__) -#define COMPILING_WITH_CLANG_ON_WINDOWS -#endif -#if defined(COMPILING_WITH_CLANG_ON_WINDOWS) +#include +#include + +/** + * Float value to represent "undefined" in style values. + */ +#ifdef __cplusplus #include constexpr double YGUndefined = std::numeric_limits::quiet_NaN(); #else -YG_EXTERN_C_BEGIN - -// Not defined in MSVC++ -#ifndef NAN -static const uint64_t __nan = 0x7ff8000000000000; -#define NAN (*(const double*) __nan) -#endif - +#include #define YGUndefined NAN #endif +YG_EXTERN_C_BEGIN + +/** + * Structure used to represent a dimension in a style. + */ typedef struct YGValue { double value; YGUnit unit; } YGValue; -YOGA_EXPORT extern const YGValue YGValueAuto; -YOGA_EXPORT extern const YGValue YGValueUndefined; -YOGA_EXPORT extern const YGValue YGValueZero; +/** + * Constant for a dimension of "auto". + */ +YG_EXPORT extern const YGValue YGValueAuto; + +/** + * Constant for a dimension which is not defined. + */ +YG_EXPORT extern const YGValue YGValueUndefined; + +/** + * Constant for a dimension that is zero-length. + */ +YG_EXPORT extern const YGValue YGValueZero; + +/** + * Whether a dimension represented as a double is defined. + */ +YG_EXPORT bool YGFloatIsUndefined(double value); -#if !defined(COMPILING_WITH_CLANG_ON_WINDOWS) YG_EXTERN_C_END -#endif -#undef COMPILING_WITH_CLANG_ON_WINDOWS +// Equality operators for comparison of YGValue in C++ #ifdef __cplusplus -YG_EXTERN_CXX_BEGIN - inline bool operator==(const YGValue& lhs, const YGValue& rhs) { if (lhs.unit != rhs.unit) { return false; @@ -54,6 +65,9 @@ inline bool operator==(const YGValue& lhs, const YGValue& rhs) { switch (lhs.unit) { case YGUnitUndefined: case YGUnitAuto: + case YGUnitFitContent: + case YGUnitMaxContent: + case YGUnitStretch: return true; case YGUnitPoint: case YGUnitPercent: @@ -70,28 +84,4 @@ inline bool operator!=(const YGValue& lhs, const YGValue& rhs) { inline YGValue operator-(const YGValue& value) { return {-value.value, value.unit}; } - -namespace facebook { -namespace yoga { -namespace literals { - -inline YGValue operator"" _pt(long double value) { - return YGValue{static_cast(value), YGUnitPoint}; -} -inline YGValue operator"" _pt(unsigned long long value) { - return operator"" _pt(static_cast(value)); -} - -inline YGValue operator"" _percent(long double value) { - return YGValue{static_cast(value), YGUnitPercent}; -} -inline YGValue operator"" _percent(unsigned long long value) { - return operator"" _percent(static_cast(value)); -} - -} // namespace literals -} // namespace yoga -} // namespace facebook - -YG_EXTERN_CXX_END #endif diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h deleted file mode 100644 index e2d66c932b..0000000000 --- a/yoga/Yoga-internal.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "CompactValue.h" -#include "Yoga.h" - -using YGVector = std::vector; - -YG_EXTERN_C_BEGIN - -void YGNodeCalculateLayoutWithContext( - YGNodeRef node, - double availableWidth, - double availableHeight, - YGDirection ownerDirection, - void* layoutContext); - -YG_EXTERN_C_END - -namespace facebook { -namespace yoga { - -inline bool isUndefined(double value) { - return std::isnan(value); -} - -} // namespace yoga -} // namespace facebook - -using namespace facebook; - -extern const std::array trailing; -extern const std::array leading; -extern const YGValue YGValueUndefined; -extern const YGValue YGValueAuto; -extern const YGValue YGValueZero; - -struct YGCachedMeasurement { - double availableWidth; - double availableHeight; - YGMeasureMode widthMeasureMode; - YGMeasureMode heightMeasureMode; - - double computedWidth; - double computedHeight; - - YGCachedMeasurement() - : availableWidth(-1), - availableHeight(-1), - widthMeasureMode(YGMeasureModeUndefined), - heightMeasureMode(YGMeasureModeUndefined), - computedWidth(-1), - computedHeight(-1) {} - - bool operator==(YGCachedMeasurement measurement) const { - bool isEqual = widthMeasureMode == measurement.widthMeasureMode && - heightMeasureMode == measurement.heightMeasureMode; - - if (!yoga::isUndefined(availableWidth) || - !yoga::isUndefined(measurement.availableWidth)) { - isEqual = isEqual && availableWidth == measurement.availableWidth; - } - if (!yoga::isUndefined(availableHeight) || - !yoga::isUndefined(measurement.availableHeight)) { - isEqual = isEqual && availableHeight == measurement.availableHeight; - } - if (!yoga::isUndefined(computedWidth) || - !yoga::isUndefined(measurement.computedWidth)) { - isEqual = isEqual && computedWidth == measurement.computedWidth; - } - if (!yoga::isUndefined(computedHeight) || - !yoga::isUndefined(measurement.computedHeight)) { - isEqual = isEqual && computedHeight == measurement.computedHeight; - } - - return isEqual; - } -}; - -// This value was chosen based on empirical data: -// 98% of analyzed layouts require less than 8 entries. -#define YG_MAX_CACHED_RESULT_COUNT 8 - -namespace facebook { -namespace yoga { -namespace detail { - -template -class Values { -private: - std::array values_; - -public: - Values() = default; - explicit Values(const YGValue& defaultValue) noexcept { - values_.fill(defaultValue); - } - - const CompactValue& operator[](size_t i) const noexcept { return values_[i]; } - CompactValue& operator[](size_t i) noexcept { return values_[i]; } - - template - YGValue get() const noexcept { - return std::get(values_); - } - - template - void set(YGValue& value) noexcept { - std::get(values_) = value; - } - - template - void set(YGValue&& value) noexcept { - set(value); - } - - bool operator==(const Values& other) const noexcept { - for (size_t i = 0; i < Size; ++i) { - if (values_[i] != other.values_[i]) { - return false; - } - } - return true; - } - - Values& operator=(const Values& other) = default; -}; - -} // namespace detail -} // namespace yoga -} // namespace facebook - -static const double kDefaultFlexGrow = 0.0; -static const double kDefaultFlexShrink = 0.0; -static const double kWebDefaultFlexShrink = 1.0; - -extern bool YGFloatsEqual(const double a, const double b); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp deleted file mode 100644 index cfdcdb42de..0000000000 --- a/yoga/Yoga.cpp +++ /dev/null @@ -1,4380 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "log.h" -#include -#include -#include -#include -#include -#include -#include "Utils.h" -#include "YGNode.h" -#include "YGNodePrint.h" -#include "Yoga-internal.h" -#include "event/event.h" -#ifdef _MSC_VER - -/* define fmax if < VC12 */ -#if _MSC_VER < 1800 -__forceinline const double fmax(const double a, const double b) { - return (a > b) ? a : b; -} -#endif -#endif - -using namespace facebook::yoga; -using detail::Log; - -#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 - -#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 - -static inline bool YGDoubleIsUndefined(const double value) { - return facebook::yoga::isUndefined(value); -} - -YOGA_EXPORT bool YGFloatIsUndefined(const double value) { - return facebook::yoga::isUndefined(value); -} - -YOGA_EXPORT const void* YGNodeGetContext(YGNodeRef node) { - return node->getContext(); -} - -YOGA_EXPORT void YGNodeSetContext(YGNodeRef node, const void* context) { - return node->setContext(context); -} - -YOGA_EXPORT bool YGNodeHasMeasureFunc(YGNodeRef node) { - return node->hasMeasureFunc(); -} - -YOGA_EXPORT void YGNodeSetMeasureFunc( - YGNodeRef node, - YGMeasureFunc measureFunc) { - node->setMeasureFunc(measureFunc); -} - -YOGA_EXPORT bool YGNodeHasBaselineFunc(YGNodeRef node) { - return node->hasBaselineFunc(); -} - -YOGA_EXPORT void YGNodeSetBaselineFunc( - YGNodeRef node, - YGBaselineFunc baselineFunc) { - node->setBaselineFunc(baselineFunc); -} - -YOGA_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node) { - return node->getDirtied(); -} - -YOGA_EXPORT void YGNodeSetDirtiedFunc( - YGNodeRef node, - YGDirtiedFunc dirtiedFunc) { - node->setDirtiedFunc(dirtiedFunc); -} - -YOGA_EXPORT void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc) { - node->setPrintFunc(printFunc); -} - -YOGA_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node) { - return node->getHasNewLayout(); -} - -YOGA_EXPORT void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled) { - config->printTree = enabled; -} - -YOGA_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) { - node->setHasNewLayout(hasNewLayout); -} - -YOGA_EXPORT YGNodeType YGNodeGetNodeType(YGNodeRef node) { - return node->getNodeType(); -} - -YOGA_EXPORT void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) { - return node->setNodeType(nodeType); -} - -YOGA_EXPORT bool YGNodeIsDirty(YGNodeRef node) { - return node->isDirty(); -} - -YOGA_EXPORT bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node) { - return node->didUseLegacyFlag(); -} - -YOGA_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants( - const YGNodeRef node) { - return node->markDirtyAndPropogateDownwards(); -} - -int32_t gConfigInstanceCount = 0; - -YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { - const YGNodeRef node = new YGNode{config}; - YGAssertWithConfig( - config, node != nullptr, "Could not allocate memory for node"); - Event::publish(node, {config}); - - return node; -} - -YOGA_EXPORT YGConfigRef YGConfigGetDefault() { - static YGConfigRef defaultConfig = YGConfigNew(); - return defaultConfig; -} - -YOGA_EXPORT YGNodeRef YGNodeNew(void) { - return YGNodeNewWithConfig(YGConfigGetDefault()); -} - -YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) { - YGNodeRef node = new YGNode(*oldNode); - YGAssertWithConfig( - oldNode->getConfig(), - node != nullptr, - "Could not allocate memory for node"); - Event::publish(node, {node->getConfig()}); - 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"); - gConfigInstanceCount++; - return config; -} - -static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) { - auto config = YGConfigClone(*oldNode->getConfig()); - auto node = new YGNode{*oldNode, config}; - node->setOwner(nullptr); - Event::publish(node, {node->getConfig()}); - - 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); - - return node; -} - -YOGA_EXPORT 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(); - Event::publish(node, {node->getConfig()}); - delete node; -} - -static void YGConfigFreeRecursive(const YGNodeRef root) { - if (root->getConfig() != nullptr) { - gConfigInstanceCount--; - delete root->getConfig(); - } - // Delete configs recursively for childrens - for (auto* child : root->getChildren()) { - YGConfigFreeRecursive(child); - } -} - -YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( - const YGNodeRef root, - YGNodeCleanupFunc cleanup) { - uint32_t skipped = 0; - while (YGNodeGetChildCount(root) > skipped) { - const YGNodeRef child = YGNodeGetChild(root, skipped); - if (child->getOwner() != root) { - // Don't free shared nodes that we don't own. - skipped += 1; - } else { - YGNodeRemoveChild(root, child); - YGNodeFreeRecursive(child); - } - } - if (cleanup != nullptr) { - cleanup(root); - } - YGNodeFree(root); -} - -YOGA_EXPORT void YGNodeFreeRecursive(const YGNodeRef root) { - return YGNodeFreeRecursiveWithCleanupFunc(root, nullptr); -} - -YOGA_EXPORT void YGNodeReset(YGNodeRef node) { - node->reset(); -} - -int32_t YGConfigGetInstanceCount(void) { - return gConfigInstanceCount; -} - -YOGA_EXPORT YGConfigRef YGConfigNew(void) { -#ifdef ANDROID - const YGConfigRef config = new YGConfig(YGAndroidLog); -#else - const YGConfigRef config = new YGConfig(YGDefaultLog); -#endif - gConfigInstanceCount++; - return config; -} - -YOGA_EXPORT void YGConfigFree(const YGConfigRef config) { - delete config; - gConfigInstanceCount--; -} - -void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) { - memcpy(dest, src, sizeof(YGConfig)); -} - -YOGA_EXPORT void YGNodeSetIsReferenceBaseline( - YGNodeRef node, - bool isReferenceBaseline) { - if (node->isReferenceBaseline() != isReferenceBaseline) { - node->setIsReferenceBaseline(isReferenceBaseline); - node->markDirtyAndPropogate(); - } -} - -YOGA_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node) { - return node->isReferenceBaseline(); -} - -YOGA_EXPORT void YGNodeInsertChild( - const YGNodeRef owner, - const YGNodeRef child, - const uint32_t index) { - YGAssertWithNode( - owner, - child->getOwner() == nullptr, - "Child already has a owner, it must be removed first."); - - YGAssertWithNode( - owner, - !owner->hasMeasureFunc(), - "Cannot add child: Nodes with measure functions cannot have children."); - - owner->insertChild(child, index); - child->setOwner(owner); - owner->markDirtyAndPropogate(); -} - -YOGA_EXPORT void YGNodeSwapChild( - const YGNodeRef owner, - const YGNodeRef child, - const uint32_t index) { - owner->replaceChild(child, index); - child->setOwner(owner); -} - -YOGA_EXPORT void YGNodeRemoveChild( - const YGNodeRef owner, - const YGNodeRef excludedChild) { - if (YGNodeGetChildCount(owner) == 0) { - // This is an empty set. Nothing to remove. - return; - } - - // Children may be shared between parents, which is indicated by not having an - // owner. We only want to reset the child completely if it is owned - // exclusively by one node. - auto childOwner = excludedChild->getOwner(); - if (owner->removeChild(excludedChild)) { - if (owner == childOwner) { - excludedChild->setLayout({}); // layout is no longer valid - excludedChild->setOwner(nullptr); - } - owner->markDirtyAndPropogate(); - } -} - -YOGA_EXPORT 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(); - } -} - -YOGA_EXPORT void YGNodeSetChildren( - const YGNodeRef owner, - const YGNodeRef c[], - const uint32_t count) { - const YGVector children = {c, c + count}; - YGNodeSetChildrenInternal(owner, children); -} - -YOGA_EXPORT void YGNodeSetChildren( - YGNodeRef const owner, - const std::vector& children) { - YGNodeSetChildrenInternal(owner, children); -} - -YOGA_EXPORT YGNodeRef -YGNodeGetChild(const YGNodeRef node, const uint32_t index) { - if (index < node->getChildren().size()) { - return node->getChild(index); - } - return nullptr; -} - -YOGA_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node) { - return static_cast(node->getChildren().size()); -} - -YOGA_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node) { - return node->getOwner(); -} - -YOGA_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node) { - return node->getOwner(); -} - -YOGA_EXPORT void YGNodeMarkDirty(const YGNodeRef node) { - YGAssertWithNode( - node, - node->hasMeasureFunc(), - "Only leaf nodes with custom measure functions" - "should manually mark themselves as dirty"); - - node->markDirtyAndPropogate(); -} - -YOGA_EXPORT void YGNodeCopyStyle( - const YGNodeRef dstNode, - const YGNodeRef srcNode) { - if (!(dstNode->getStyle() == srcNode->getStyle())) { - dstNode->setStyle(srcNode->getStyle()); - dstNode->markDirtyAndPropogate(); - } -} - -YOGA_EXPORT double YGNodeStyleGetFlexGrow(const YGNodeConstRef node) { - return node->getStyle().flexGrow().isUndefined() - ? kDefaultFlexGrow - : node->getStyle().flexGrow().unwrap(); -} - -YOGA_EXPORT double YGNodeStyleGetFlexShrink(const YGNodeConstRef node) { - return node->getStyle().flexShrink().isUndefined() - ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink - : kDefaultFlexShrink) - : node->getStyle().flexShrink().unwrap(); -} - -namespace { - -template -void updateStyle( - YGNode* node, - T value, - NeedsUpdate&& needsUpdate, - Update&& update) { - if (needsUpdate(node->getStyle(), value)) { - update(node->getStyle(), value); - node->markDirtyAndPropogate(); - } -} - -template -void updateStyle(YGNode* node, Ref (YGStyle::*prop)(), T value) { - updateStyle( - node, - value, - [prop](YGStyle& s, T x) { return (s.*prop)() != x; }, - [prop](YGStyle& s, T x) { (s.*prop)() = x; }); -} - -template -void updateIndexedStyleProp( - YGNode* node, - Ref (YGStyle::*prop)(), - Idx idx, - detail::CompactValue value) { - using detail::CompactValue; - updateStyle( - node, - value, - [idx, prop](YGStyle& s, CompactValue x) { return (s.*prop)()[idx] != x; }, - [idx, prop](YGStyle& s, CompactValue x) { (s.*prop)()[idx] = x; }); -} - -} // namespace - -// MSVC has trouble inferring the return type of pointer to member functions -// with const and non-const overloads, instead of preferring the non-const -// overload like clang and GCC. For the purposes of updateStyle(), we can help -// MSVC by specifying that return type explicitely. In combination with -// decltype, MSVC will prefer the non-const version. -#define MSVC_HINT(PROP) decltype(YGStyle{}.PROP()) - -YOGA_EXPORT void YGNodeStyleSetDirection( - const YGNodeRef node, - const YGDirection value) { - updateStyle(node, &YGStyle::direction, value); -} -YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { - return node->getStyle().direction(); -} - -YOGA_EXPORT void YGNodeStyleSetFlexDirection( - const YGNodeRef node, - const YGFlexDirection flexDirection) { - updateStyle( - node, &YGStyle::flexDirection, flexDirection); -} -YOGA_EXPORT YGFlexDirection -YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { - return node->getStyle().flexDirection(); -} - -YOGA_EXPORT void YGNodeStyleSetJustifyContent( - const YGNodeRef node, - const YGJustify justifyContent) { - updateStyle( - node, &YGStyle::justifyContent, justifyContent); -} -YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { - return node->getStyle().justifyContent(); -} - -YOGA_EXPORT void YGNodeStyleSetAlignContent( - const YGNodeRef node, - const YGAlign alignContent) { - updateStyle( - node, &YGStyle::alignContent, alignContent); -} -YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { - return node->getStyle().alignContent(); -} - -YOGA_EXPORT void YGNodeStyleSetAlignItems( - const YGNodeRef node, - const YGAlign alignItems) { - updateStyle(node, &YGStyle::alignItems, alignItems); -} -YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { - return node->getStyle().alignItems(); -} - -YOGA_EXPORT void YGNodeStyleSetAlignSelf( - const YGNodeRef node, - const YGAlign alignSelf) { - updateStyle(node, &YGStyle::alignSelf, alignSelf); -} -YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { - return node->getStyle().alignSelf(); -} - -YOGA_EXPORT void YGNodeStyleSetPositionType( - const YGNodeRef node, - const YGPositionType positionType) { - updateStyle( - node, &YGStyle::positionType, positionType); -} -YOGA_EXPORT YGPositionType -YGNodeStyleGetPositionType(const YGNodeConstRef node) { - return node->getStyle().positionType(); -} - -YOGA_EXPORT void YGNodeStyleSetFlexWrap( - const YGNodeRef node, - const YGWrap flexWrap) { - updateStyle(node, &YGStyle::flexWrap, flexWrap); -} -YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { - return node->getStyle().flexWrap(); -} - -YOGA_EXPORT void YGNodeStyleSetOverflow( - const YGNodeRef node, - const YGOverflow overflow) { - updateStyle(node, &YGStyle::overflow, overflow); -} -YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { - return node->getStyle().overflow(); -} - -YOGA_EXPORT void YGNodeStyleSetDisplay( - const YGNodeRef node, - const YGDisplay display) { - updateStyle(node, &YGStyle::display, display); -} -YOGA_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { - return node->getStyle().display(); -} - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const double flex) { - updateStyle(node, &YGStyle::flex, YGFloatOptional{flex}); -} - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT double YGNodeStyleGetFlex(const YGNodeConstRef node) { - return node->getStyle().flex().isUndefined() - ? YGUndefined - : node->getStyle().flex().unwrap(); -} - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetFlexGrow( - const YGNodeRef node, - const double flexGrow) { - updateStyle( - node, &YGStyle::flexGrow, YGFloatOptional{flexGrow}); -} - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetFlexShrink( - const YGNodeRef node, - const double flexShrink) { - updateStyle( - node, &YGStyle::flexShrink, YGFloatOptional{flexShrink}); -} - -YOGA_EXPORT YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef 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; -} - -YOGA_EXPORT void YGNodeStyleSetFlexBasis( - const YGNodeRef node, - const double flexBasis) { - auto value = detail::CompactValue::ofMaybe(flexBasis); - updateStyle(node, &YGStyle::flexBasis, value); -} - -YOGA_EXPORT void YGNodeStyleSetFlexBasisPercent( - const YGNodeRef node, - const double flexBasisPercent) { - auto value = detail::CompactValue::ofMaybe(flexBasisPercent); - updateStyle(node, &YGStyle::flexBasis, value); -} - -YOGA_EXPORT void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { - updateStyle( - node, &YGStyle::flexBasis, detail::CompactValue::ofAuto()); -} - -YOGA_EXPORT void YGNodeStyleSetPosition( - YGNodeRef node, - YGEdge edge, - double points) { - auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &YGStyle::position, edge, value); -} -YOGA_EXPORT void YGNodeStyleSetPositionPercent( - YGNodeRef node, - YGEdge edge, - double percent) { - auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &YGStyle::position, edge, value); -} -YOGA_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { - return node->getStyle().position()[edge]; -} - -YOGA_EXPORT void YGNodeStyleSetMargin( - YGNodeRef node, - YGEdge edge, - double points) { - auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &YGStyle::margin, edge, value); -} -YOGA_EXPORT void YGNodeStyleSetMarginPercent( - YGNodeRef node, - YGEdge edge, - double percent) { - auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &YGStyle::margin, edge, value); -} -YOGA_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { - updateIndexedStyleProp( - node, &YGStyle::margin, edge, detail::CompactValue::ofAuto()); -} -YOGA_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { - return node->getStyle().margin()[edge]; -} - -YOGA_EXPORT void YGNodeStyleSetPadding( - YGNodeRef node, - YGEdge edge, - double points) { - auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &YGStyle::padding, edge, value); -} -YOGA_EXPORT void YGNodeStyleSetPaddingPercent( - YGNodeRef node, - YGEdge edge, - double percent) { - auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &YGStyle::padding, edge, value); -} -YOGA_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { - return node->getStyle().padding()[edge]; -} - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetBorder( - const YGNodeRef node, - const YGEdge edge, - const double border) { - auto value = detail::CompactValue::ofMaybe(border); - updateIndexedStyleProp( - node, &YGStyle::border, edge, value); -} - -YOGA_EXPORT double YGNodeStyleGetBorder( - const YGNodeConstRef node, - const YGEdge edge) { - auto border = node->getStyle().border()[edge]; - if (border.isUndefined() || border.isAuto()) { - // TODO(T26792433): Rather than returning YGUndefined, change the api to - // return YGFloatOptional. - return YGUndefined; - } - - return static_cast(border).value; -} - -// Yoga specific properties, not compatible with flexbox specification - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT double YGNodeStyleGetAspectRatio(const YGNodeConstRef node) { - const YGFloatOptional op = node->getStyle().aspectRatio(); - return op.isUndefined() ? YGUndefined : op.unwrap(); -} - -// TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetAspectRatio( - const YGNodeRef node, - const double aspectRatio) { - updateStyle( - node, &YGStyle::aspectRatio, YGFloatOptional{aspectRatio}); -} - -YOGA_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, double points) { - auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &YGStyle::dimensions, YGDimensionWidth, value); -} -YOGA_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, double percent) { - auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &YGStyle::dimensions, YGDimensionWidth, value); -} -YOGA_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node) { - updateIndexedStyleProp( - node, - &YGStyle::dimensions, - YGDimensionWidth, - detail::CompactValue::ofAuto()); -} -YOGA_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { - return node->getStyle().dimensions()[YGDimensionWidth]; -} - -YOGA_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, double points) { - auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &YGStyle::dimensions, YGDimensionHeight, value); -} -YOGA_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, double percent) { - auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &YGStyle::dimensions, YGDimensionHeight, value); -} -YOGA_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node) { - updateIndexedStyleProp( - node, - &YGStyle::dimensions, - YGDimensionHeight, - detail::CompactValue::ofAuto()); -} -YOGA_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { - return node->getStyle().dimensions()[YGDimensionHeight]; -} - -YOGA_EXPORT void YGNodeStyleSetMinWidth( - const YGNodeRef node, - const double minWidth) { - auto value = detail::CompactValue::ofMaybe(minWidth); - updateIndexedStyleProp( - node, &YGStyle::minDimensions, YGDimensionWidth, value); -} -YOGA_EXPORT void YGNodeStyleSetMinWidthPercent( - const YGNodeRef node, - const double minWidth) { - auto value = detail::CompactValue::ofMaybe(minWidth); - updateIndexedStyleProp( - node, &YGStyle::minDimensions, YGDimensionWidth, value); -} -YOGA_EXPORT YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { - return node->getStyle().minDimensions()[YGDimensionWidth]; -}; - -YOGA_EXPORT void YGNodeStyleSetMinHeight( - const YGNodeRef node, - const double minHeight) { - auto value = detail::CompactValue::ofMaybe(minHeight); - updateIndexedStyleProp( - node, &YGStyle::minDimensions, YGDimensionHeight, value); -} -YOGA_EXPORT void YGNodeStyleSetMinHeightPercent( - const YGNodeRef node, - const double minHeight) { - auto value = detail::CompactValue::ofMaybe(minHeight); - updateIndexedStyleProp( - node, &YGStyle::minDimensions, YGDimensionHeight, value); -} -YOGA_EXPORT YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { - return node->getStyle().minDimensions()[YGDimensionHeight]; -}; - -YOGA_EXPORT void YGNodeStyleSetMaxWidth( - const YGNodeRef node, - const double maxWidth) { - auto value = detail::CompactValue::ofMaybe(maxWidth); - updateIndexedStyleProp( - node, &YGStyle::maxDimensions, YGDimensionWidth, value); -} -YOGA_EXPORT void YGNodeStyleSetMaxWidthPercent( - const YGNodeRef node, - const double maxWidth) { - auto value = detail::CompactValue::ofMaybe(maxWidth); - updateIndexedStyleProp( - node, &YGStyle::maxDimensions, YGDimensionWidth, value); -} -YOGA_EXPORT YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { - return node->getStyle().maxDimensions()[YGDimensionWidth]; -}; - -YOGA_EXPORT void YGNodeStyleSetMaxHeight( - const YGNodeRef node, - const double maxHeight) { - auto value = detail::CompactValue::ofMaybe(maxHeight); - updateIndexedStyleProp( - node, &YGStyle::maxDimensions, YGDimensionHeight, value); -} -YOGA_EXPORT void YGNodeStyleSetMaxHeightPercent( - const YGNodeRef node, - const double maxHeight) { - auto value = detail::CompactValue::ofMaybe(maxHeight); - updateIndexedStyleProp( - node, &YGStyle::maxDimensions, YGDimensionHeight, value); -} -YOGA_EXPORT YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { - return node->getStyle().maxDimensions()[YGDimensionHeight]; -}; - -#define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ - YOGA_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node) { \ - return node->getLayout().instanceName; \ - } - -#define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \ - YOGA_EXPORT type YGNodeLayoutGet##name( \ - const YGNodeRef node, const YGEdge edge) { \ - YGAssertWithNode( \ - node, \ - edge <= YGEdgeEnd, \ - "Cannot get layout properties of multi-edge shorthands"); \ - \ - if (edge == YGEdgeStart) { \ - if (node->getLayout().direction() == YGDirectionRTL) { \ - return node->getLayout().instanceName[YGEdgeRight]; \ - } else { \ - return node->getLayout().instanceName[YGEdgeLeft]; \ - } \ - } \ - \ - if (edge == YGEdgeEnd) { \ - if (node->getLayout().direction() == YGDirectionRTL) { \ - return node->getLayout().instanceName[YGEdgeLeft]; \ - } else { \ - return node->getLayout().instanceName[YGEdgeRight]; \ - } \ - } \ - \ - return node->getLayout().instanceName[edge]; \ - } - -YG_NODE_LAYOUT_PROPERTY_IMPL(double, Left, position[YGEdgeLeft]); -YG_NODE_LAYOUT_PROPERTY_IMPL(double, Top, position[YGEdgeTop]); -YG_NODE_LAYOUT_PROPERTY_IMPL(double, Right, position[YGEdgeRight]); -YG_NODE_LAYOUT_PROPERTY_IMPL(double, Bottom, position[YGEdgeBottom]); -YG_NODE_LAYOUT_PROPERTY_IMPL(double, Width, dimensions[YGDimensionWidth]); -YG_NODE_LAYOUT_PROPERTY_IMPL(double, 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(double, Margin, margin); -YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(double, Border, border); -YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(double, Padding, padding); - -YOGA_EXPORT bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout( - const YGNodeRef node) { - return node->getLayout().doesLegacyStretchFlagAffectsLayout(); -} - -std::atomic gCurrentGenerationCount(0); - -bool YGLayoutNodeInternal( - const YGNodeRef node, - const double availableWidth, - const double availableHeight, - const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const double ownerWidth, - const double ownerHeight, - const bool performLayout, - const LayoutPassReason reason, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount); - -#ifdef DEBUG -static void YGNodePrintInternal( - const YGNodeRef node, - const YGPrintOptions options) { - std::string str; - facebook::yoga::YGNodeToString(str, node, options, 0); - Log::log(node, YGLogLevelDebug, nullptr, str.c_str()); -} - -YOGA_EXPORT void YGNodePrint( - const YGNodeRef node, - const YGPrintOptions options) { - YGNodePrintInternal(node, options); -} -#endif - -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 double YGNodePaddingAndBorderForAxis( - const YGNodeConstRef node, - const YGFlexDirection axis, - const double widthSize) { - return (node->getLeadingPaddingAndBorder(axis, widthSize) + - node->getTrailingPaddingAndBorder(axis, widthSize)) - .unwrap(); -} - -static inline YGAlign YGNodeAlignItem(const YGNode* node, const YGNode* 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 double YGBaseline(const YGNodeRef node, void* layoutContext) { - if (node->hasBaselineFunc()) { - - Event::publish(node); - - const double baseline = node->baseline( - node->getLayout().measuredDimensions[YGDimensionWidth], - node->getLayout().measuredDimensions[YGDimensionHeight], - layoutContext); - - Event::publish(node); - - 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 || - child->isReferenceBaseline()) { - baselineChild = child; - break; - } - - if (baselineChild == nullptr) { - baselineChild = child; - } - } - - if (baselineChild == nullptr) { - return node->getLayout().measuredDimensions[YGDimensionHeight]; - } - - const double baseline = YGBaseline(baselineChild, layoutContext); - 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() != YGPositionTypeAbsolute && - child->getStyle().alignSelf() == YGAlignBaseline) { - return true; - } - } - - return false; -} - -static inline double YGNodeDimWithMargin( - const YGNodeRef node, - const YGFlexDirection axis, - const double widthSize) { - return node->getLayout().measuredDimensions[dim[axis]] + - (node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)) - .unwrap(); -} - -static inline bool YGNodeIsStyleDimDefined( - const YGNodeRef node, - const YGFlexDirection axis, - const double 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.0) || - (node->getResolvedDimension(dim[axis]).unit == YGUnitPercent && - !isUndefined && - (node->getResolvedDimension(dim[axis]).value < 0.0 || - YGFloatIsUndefined(ownerSize)))); -} - -static inline bool YGNodeIsLayoutDimDefined( - const YGNodeRef node, - const YGFlexDirection axis) { - const double value = node->getLayout().measuredDimensions[dim[axis]]; - return !YGFloatIsUndefined(value) && value >= 0.0; -} - -static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( - const YGNodeConstRef node, - const YGFlexDirection axis, - const YGFloatOptional value, - const double 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 >= YGFloatOptional{0} && value > max) { - return max; - } - - if (min >= YGFloatOptional{0} && value < min) { - return min; - } - - return value; -} - -// Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't -// go below the padding and border amount. -static inline double YGNodeBoundAxis( - const YGNodeRef node, - const YGFlexDirection axis, - const double value, - const double axisSize, - const double widthSize) { - return YGFloatMax( - YGNodeBoundAxisWithinMinAndMax( - node, axis, YGFloatOptional{value}, axisSize) - .unwrap(), - YGNodePaddingAndBorderForAxis(node, axis, widthSize)); -} - -static void YGNodeSetChildTrailingPosition( - const YGNodeRef node, - const YGNodeRef child, - const YGFlexDirection axis) { - const double 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 YGNodeConstRef node, - const enum YGFlexDirection axis, - const double ownerAxisSize, - const double ownerWidth, - YGMeasureMode* mode, - double* 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.unwrap()) - ? *size - : maxSize.unwrap(); - break; - case YGMeasureModeUndefined: - if (!maxSize.isUndefined()) { - *mode = YGMeasureModeAtMost; - *size = maxSize.unwrap(); - } - break; - } -} - -static void YGNodeComputeFlexBasisForChild( - const YGNodeRef node, - const YGNodeRef child, - const double width, - const YGMeasureMode widthMode, - const double height, - const double ownerWidth, - const double ownerHeight, - const YGMeasureMode heightMode, - const YGDirection direction, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount) { - const YGFlexDirection mainAxis = - YGResolveFlexDirection(node->getStyle().flexDirection(), direction); - const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); - const double mainAxisSize = isMainAxisRow ? width : height; - const double mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; - - double childWidth; - double 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 != generationCount)) { - 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->getResolvedDimensions()[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->getResolvedDimensions()[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; - - auto marginRow = - child->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); - auto marginColumn = - child->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); - - if (isRowStyleDimDefined) { - childWidth = - YGResolveValue( - child->getResolvedDimensions()[YGDimensionWidth], ownerWidth) - .unwrap() + - marginRow; - childWidthMeasureMode = YGMeasureModeExactly; - } - if (isColumnStyleDimDefined) { - childHeight = - YGResolveValue( - child->getResolvedDimensions()[YGDimensionHeight], ownerHeight) - .unwrap() + - 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; - } - } - - const auto& childStyle = child->getStyle(); - if (!childStyle.aspectRatio().isUndefined()) { - if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { - childHeight = marginColumn + - (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); - childHeightMeasureMode = YGMeasureModeExactly; - } else if ( - isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { - childWidth = marginRow + - (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); - 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 (!childStyle.aspectRatio().isUndefined()) { - childHeight = - (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); - 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 (!childStyle.aspectRatio().isUndefined()) { - childWidth = - (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); - 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, - LayoutPassReason::kMeasureChild, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - - child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax( - child->getLayout().measuredDimensions[dim[mainAxis]], - YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)))); - } - child->setLayoutComputedFlexBasisGeneration(generationCount); -} - -static void YGNodeAbsoluteLayoutChild( - const YGNodeRef node, - const YGNodeRef child, - const double width, - const YGMeasureMode widthMode, - const double height, - const YGDirection direction, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount) { - const YGFlexDirection mainAxis = - YGResolveFlexDirection(node->getStyle().flexDirection(), direction); - const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); - const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); - - double childWidth = YGUndefined; - double childHeight = YGUndefined; - YGMeasureMode childWidthMeasureMode = YGMeasureModeUndefined; - YGMeasureMode childHeightMeasureMode = YGMeasureModeUndefined; - - auto marginRow = child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); - auto marginColumn = - child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); - - if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = - YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], width) - .unwrap() + - 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)) - - (child->getLeadingPosition(YGFlexDirectionRow, width) + - child->getTrailingPosition(YGFlexDirectionRow, width)) - .unwrap(); - childWidth = - YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); - } - } - - if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { - childHeight = YGResolveValue( - child->getResolvedDimensions()[YGDimensionHeight], height) - .unwrap() + - 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)) - - (child->getLeadingPosition(YGFlexDirectionColumn, height) + - child->getTrailingPosition(YGFlexDirectionColumn, height)) - .unwrap(); - 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. - const auto& childStyle = child->getStyle(); - if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) { - if (!childStyle.aspectRatio().isUndefined()) { - if (YGFloatIsUndefined(childWidth)) { - childWidth = marginRow + - (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); - } else if (YGFloatIsUndefined(childHeight)) { - childHeight = marginColumn + - (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); - } - } - } - - // 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, - LayoutPassReason::kAbsMeasureChild, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + - child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); - childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + - child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); - } - - YGLayoutNodeInternal( - child, - childWidth, - childHeight, - direction, - YGMeasureModeExactly, - YGMeasureModeExactly, - childWidth, - childHeight, - true, - LayoutPassReason::kAbsLayout, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - - if (child->isTrailingPosDefined(mainAxis) && - !child->isLeadingPositionDefined(mainAxis)) { - child->setLayoutPosition( - node->getLayout().measuredDimensions[dim[mainAxis]] - - child->getLayout().measuredDimensions[dim[mainAxis]] - - node->getTrailingBorder(mainAxis) - - child->getTrailingMargin(mainAxis, width).unwrap() - - child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height) - .unwrap(), - leading[mainAxis]); - } else if ( - !child->isLeadingPositionDefined(mainAxis) && - node->getStyle().justifyContent() == YGJustifyCenter) { - child->setLayoutPosition( - (node->getLayout().measuredDimensions[dim[mainAxis]] - - child->getLayout().measuredDimensions[dim[mainAxis]]) / - 2.0, - 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) - - child->getTrailingMargin(crossAxis, width).unwrap() - - child - ->getTrailingPosition(crossAxis, isMainAxisRow ? height : width) - .unwrap(), - leading[crossAxis]); - - } else if ( - !child->isLeadingPositionDefined(crossAxis) && - YGNodeAlignItem(node, child) == YGAlignCenter) { - child->setLayoutPosition( - (node->getLayout().measuredDimensions[dim[crossAxis]] - - child->getLayout().measuredDimensions[dim[crossAxis]]) / - 2.0, - 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, - double availableWidth, - double availableHeight, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const double ownerWidth, - const double ownerHeight, - LayoutData& layoutMarkerData, - void* const layoutContext, - const LayoutPassReason reason) { - YGAssertWithNode( - node, - node->hasMeasureFunc(), - "Expected node to have custom measure function"); - - if (widthMeasureMode == YGMeasureModeUndefined) { - availableWidth = YGUndefined; - } - if (heightMeasureMode == YGMeasureModeUndefined) { - availableHeight = YGUndefined; - } - - const auto& padding = node->getLayout().padding; - const auto& border = node->getLayout().border; - const double paddingAndBorderAxisRow = padding[YGEdgeLeft] + - padding[YGEdgeRight] + border[YGEdgeLeft] + border[YGEdgeRight]; - const double paddingAndBorderAxisColumn = padding[YGEdgeTop] + - padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom]; - - // We want to make sure we don't call measure with negative size - const double innerWidth = YGFloatIsUndefined(availableWidth) - ? availableWidth - : YGFloatMax(0, availableWidth - paddingAndBorderAxisRow); - const double innerHeight = YGFloatIsUndefined(availableHeight) - ? availableHeight - : YGFloatMax(0, availableHeight - paddingAndBorderAxisColumn); - - if (widthMeasureMode == YGMeasureModeExactly && - heightMeasureMode == YGMeasureModeExactly) { - // Don't bother sizing the text if both dimensions are already defined. - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth), - YGDimensionWidth); - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, - YGFlexDirectionColumn, - availableHeight, - ownerHeight, - ownerWidth), - YGDimensionHeight); - } else { - Event::publish(node); - - // Measure the text under the current constraints. - const YGSize measuredSize = node->measure( - innerWidth, - widthMeasureMode, - innerHeight, - heightMeasureMode, - layoutContext); - - layoutMarkerData.measureCallbacks += 1; - layoutMarkerData.measureCallbackReasonsCount[static_cast(reason)] += - 1; - - Event::publish( - node, - {layoutContext, - innerWidth, - widthMeasureMode, - innerHeight, - heightMeasureMode, - measuredSize.width, - measuredSize.height, - reason}); - - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, - YGFlexDirectionRow, - (widthMeasureMode == YGMeasureModeUndefined || - widthMeasureMode == YGMeasureModeAtMost) - ? measuredSize.width + paddingAndBorderAxisRow - : availableWidth, - ownerWidth, - ownerWidth), - YGDimensionWidth); - - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, - YGFlexDirectionColumn, - (heightMeasureMode == YGMeasureModeUndefined || - heightMeasureMode == YGMeasureModeAtMost) - ? measuredSize.height + paddingAndBorderAxisColumn - : availableHeight, - 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 double availableWidth, - const double availableHeight, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const double ownerWidth, - const double ownerHeight) { - const auto& padding = node->getLayout().padding; - const auto& border = node->getLayout().border; - - double width = availableWidth; - if (widthMeasureMode == YGMeasureModeUndefined || - widthMeasureMode == YGMeasureModeAtMost) { - width = padding[YGEdgeLeft] + padding[YGEdgeRight] + border[YGEdgeLeft] + - border[YGEdgeRight]; - } - node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionRow, width, ownerWidth, ownerWidth), - YGDimensionWidth); - - double height = availableHeight; - if (heightMeasureMode == YGMeasureModeUndefined || - heightMeasureMode == YGMeasureModeAtMost) { - height = padding[YGEdgeTop] + padding[YGEdgeBottom] + border[YGEdgeTop] + - border[YGEdgeBottom]; - } - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, YGFlexDirectionColumn, height, ownerHeight, ownerWidth), - YGDimensionHeight); -} - -static bool YGNodeFixedSizeSetMeasuredDimensions( - const YGNodeRef node, - const double availableWidth, - const double availableHeight, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const double ownerWidth, - const double ownerHeight) { - if ((!YGFloatIsUndefined(availableWidth) && - widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0) || - (!YGFloatIsUndefined(availableHeight) && - heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0) || - (widthMeasureMode == YGMeasureModeExactly && - heightMeasureMode == YGMeasureModeExactly)) { - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, - YGFlexDirectionRow, - YGFloatIsUndefined(availableWidth) || - (widthMeasureMode == YGMeasureModeAtMost && - availableWidth < 0.0) - ? 0.0 - : availableWidth, - ownerWidth, - ownerWidth), - YGDimensionWidth); - - node->setLayoutMeasuredDimension( - YGNodeBoundAxis( - node, - YGFlexDirectionColumn, - YGFloatIsUndefined(availableHeight) || - (heightMeasureMode == YGMeasureModeAtMost && - availableHeight < 0.0) - ? 0.0 - : availableHeight, - ownerHeight, - ownerWidth), - YGDimensionHeight); - return true; - } - - return false; -} - -static void YGZeroOutLayoutRecursivly( - const YGNodeRef node, - void* layoutContext) { - node->getLayout() = {}; - node->setLayoutDimension(0, 0); - node->setLayoutDimension(0, 1); - node->setHasNewLayout(true); - - node->iterChildrenAfterCloningIfNeeded( - YGZeroOutLayoutRecursivly, layoutContext); -} - -static double YGNodeCalculateAvailableInnerDim( - const YGNodeConstRef node, - const YGDimension dimension, - const double availableDim, - const double paddingAndBorder, - const double ownerDim) { - double availableInnerDim = availableDim - 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 double minInnerDim = minDimensionOptional.isUndefined() - ? 0.0 - : minDimensionOptional.unwrap() - paddingAndBorder; - - const YGFloatOptional maxDimensionOptional = - YGResolveValue(node->getStyle().maxDimensions()[dimension], ownerDim); - - const double maxInnerDim = maxDimensionOptional.isUndefined() - ? std::numeric_limits::max() - : maxDimensionOptional.unwrap() - paddingAndBorder; - availableInnerDim = - YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); - } - - return availableInnerDim; -} - -static double YGNodeComputeFlexBasisForChildren( - const YGNodeRef node, - const double availableInnerWidth, - const double availableInnerHeight, - YGMeasureMode widthMeasureMode, - YGMeasureMode heightMeasureMode, - YGDirection direction, - YGFlexDirection mainAxis, - const YGConfigRef config, - bool performLayout, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount) { - double totalOuterFlexBasis = 0.0; - YGNodeRef singleFlexChild = nullptr; - const 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 (child->isNodeFlexible()) { - if (singleFlexChild != nullptr || - YGFloatsEqual(child->resolveFlexGrow(), 0.0) || - YGFloatsEqual(child->resolveFlexShrink(), 0.0)) { - // There is already a flexible child, or this flexible child doesn't - // have flexGrow and flexShrink, abort - singleFlexChild = nullptr; - break; - } else { - singleFlexChild = child; - } - } - } - } - - for (auto child : children) { - child->resolveDimension(); - if (child->getStyle().display() == YGDisplayNone) { - YGZeroOutLayoutRecursivly(child, layoutContext); - child->setHasNewLayout(true); - child->setDirty(false); - continue; - } - if (performLayout) { - // Set the initial position (relative to the owner). - const YGDirection childDirection = child->resolveDirection(direction); - const double mainDim = YGFlexDirectionIsRow(mainAxis) - ? availableInnerWidth - : availableInnerHeight; - const double crossDim = YGFlexDirectionIsRow(mainAxis) - ? availableInnerHeight - : availableInnerWidth; - child->setPosition( - childDirection, mainDim, crossDim, availableInnerWidth); - } - - if (child->getStyle().positionType() == YGPositionTypeAbsolute) { - continue; - } - if (child == singleFlexChild) { - child->setLayoutComputedFlexBasisGeneration(generationCount); - child->setLayoutComputedFlexBasis(YGFloatOptional(0)); - } else { - YGNodeComputeFlexBasisForChild( - node, - child, - availableInnerWidth, - widthMeasureMode, - availableInnerHeight, - availableInnerWidth, - availableInnerHeight, - heightMeasureMode, - direction, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - } - - totalOuterFlexBasis += - (child->getLayout().computedFlexBasis + - child->getMarginForAxis(mainAxis, availableInnerWidth)) - .unwrap(); - } - - return totalOuterFlexBasis; -} - -// 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 double mainAxisownerSize, - const double availableInnerWidth, - const double availableInnerMainDim, - const uint32_t startOfLineIndex, - const uint32_t lineCount) { - YGCollectFlexItemsRowValues flexAlgoRowMeasurement = {}; - flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size()); - - double 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->getChildren().size(); endOfLineIndex++) { - const YGNodeRef child = node->getChild(endOfLineIndex); - if (child->getStyle().display() == YGDisplayNone || - child->getStyle().positionType() == YGPositionTypeAbsolute) { - continue; - } - child->setLineIndex(lineCount); - const double childMarginMainAxis = - child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap(); - const double flexBasisWithMinAndMaxConstraints = - YGNodeBoundAxisWithinMinAndMax( - child, - mainAxis, - child->getLayout().computedFlexBasis, - mainAxisownerSize) - .unwrap(); - - // 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() * - child->getLayout().computedFlexBasis.unwrap(); - } - - 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 double YGDistributeFreeSpaceSecondPass( - YGCollectFlexItemsRowValues& collectedFlexItemsValues, - const YGNodeRef node, - const YGFlexDirection mainAxis, - const YGFlexDirection crossAxis, - const double mainAxisownerSize, - const double availableInnerMainDim, - const double availableInnerCrossDim, - const double availableInnerWidth, - const double availableInnerHeight, - const bool flexBasisOverflows, - const YGMeasureMode measureModeCrossDim, - const bool performLayout, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount) { - double childFlexBasis = 0; - double flexShrinkScaledFactor = 0; - double flexGrowFactor = 0; - double deltaFreeSpace = 0; - const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); - const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; - - for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - childFlexBasis = YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - currentRelativeChild->getLayout().computedFlexBasis, - mainAxisownerSize) - .unwrap(); - double updatedMainSize = childFlexBasis; - - if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && - collectedFlexItemsValues.remainingFreeSpace < 0) { - flexShrinkScaledFactor = - -currentRelativeChild->resolveFlexShrink() * childFlexBasis; - // Is this child able to shrink? - if (flexShrinkScaledFactor != 0) { - double 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 double marginMain = - currentRelativeChild->getMarginForAxis(mainAxis, availableInnerWidth) - .unwrap(); - const double marginCross = - currentRelativeChild->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap(); - - double childCrossSize; - double childMainSize = updatedMainSize + marginMain; - YGMeasureMode childCrossMeasureMode; - YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; - - const auto& childStyle = currentRelativeChild->getStyle(); - if (!childStyle.aspectRatio().isUndefined()) { - childCrossSize = isMainAxisRow - ? (childMainSize - marginMain) / childStyle.aspectRatio().unwrap() - : (childMainSize - marginMain) * childStyle.aspectRatio().unwrap(); - 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 = - YGResolveValue( - currentRelativeChild->getResolvedDimension(dim[crossAxis]), - availableInnerCrossDim) - .unwrap() + - 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 double childWidth = isMainAxisRow ? childMainSize : childCrossSize; - const double childHeight = !isMainAxisRow ? childMainSize : childCrossSize; - - const YGMeasureMode childWidthMeasureMode = - isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; - const YGMeasureMode childHeightMeasureMode = - !isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; - - const bool isLayoutPass = performLayout && !requiresStretchLayout; - // Recursively call the layout algorithm for this child with the updated - // main size. - YGLayoutNodeInternal( - currentRelativeChild, - childWidth, - childHeight, - node->getLayout().direction(), - childWidthMeasureMode, - childHeightMeasureMode, - availableInnerWidth, - availableInnerHeight, - isLayoutPass, - isLayoutPass ? LayoutPassReason::kFlexLayout - : LayoutPassReason::kFlexMeasure, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - 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 double mainAxisownerSize, - const double availableInnerMainDim, - const double availableInnerWidth) { - double flexShrinkScaledFactor = 0; - double flexGrowFactor = 0; - double baseMainSize = 0; - double boundMainSize = 0; - double deltaFreeSpace = 0; - - for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { - double childFlexBasis = - YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, - mainAxis, - currentRelativeChild->getLayout().computedFlexBasis, - mainAxisownerSize) - .unwrap(); - - 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 -= - (-currentRelativeChild->resolveFlexShrink() * - currentRelativeChild->getLayout().computedFlexBasis.unwrap()); - } - } - } 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 -// the first pass. 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/CSS-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 double mainAxisownerSize, - const double availableInnerMainDim, - const double availableInnerCrossDim, - const double availableInnerWidth, - const double availableInnerHeight, - const bool flexBasisOverflows, - const YGMeasureMode measureModeCrossDim, - const bool performLayout, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount) { - const double 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 double distributedFreeSpace = YGDistributeFreeSpaceSecondPass( - collectedFlexItemsValues, - node, - mainAxis, - crossAxis, - mainAxisownerSize, - availableInnerMainDim, - availableInnerCrossDim, - availableInnerWidth, - availableInnerHeight, - flexBasisOverflows, - measureModeCrossDim, - performLayout, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - - 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 double mainAxisownerSize, - const double ownerWidth, - const double availableInnerMainDim, - const double availableInnerCrossDim, - const double availableInnerWidth, - const bool performLayout, - void* const layoutContext) { - const auto& style = node->getStyle(); - const double leadingPaddingAndBorderMain = - node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); - const double trailingPaddingAndBorderMain = - node->getTrailingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); - // If we are using "at most" rules in the main axis, make sure that - // remainingFreeSpace is 0 when min main dimension is not given - if (measureModeMainDim == YGMeasureModeAtMost && - collectedFlexItemsValues.remainingFreeSpace > 0) { - if (!style.minDimensions()[dim[mainAxis]].isUndefined() && - !YGResolveValue(style.minDimensions()[dim[mainAxis]], mainAxisownerSize) - .isUndefined()) { - // This condition makes sure that if the size of main dimension(after - // considering child nodes main dim, leading and trailing padding etc) - // falls below min dimension, then the remainingFreeSpace is reassigned - // considering the min dimension - - // `minAvailableMainDim` denotes minimum available space in which child - // can be laid out, it will exclude space consumed by padding and border. - const double minAvailableMainDim = - YGResolveValue( - style.minDimensions()[dim[mainAxis]], mainAxisownerSize) - .unwrap() - - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; - const double occupiedSpaceByChildNodes = - availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; - collectedFlexItemsValues.remainingFreeSpace = - YGFloatMax(0, minAvailableMainDim - occupiedSpaceByChildNodes); - } 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() != YGPositionTypeAbsolute) { - 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. - double leadingMainDim = 0; - double 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; - } - } - - collectedFlexItemsValues.mainDim = - leadingPaddingAndBorderMain + leadingMainDim; - collectedFlexItemsValues.crossDim = 0; - - double maxAscentForCurrentLine = 0; - double maxDescentForCurrentLine = 0; - bool isNodeBaselineLayout = YGIsBaselineLayout(node); - 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( - child->getLeadingPosition(mainAxis, availableInnerMainDim) - .unwrap() + - node->getLeadingBorder(mainAxis) + - child->getLeadingMargin(mainAxis, availableInnerWidth).unwrap(), - 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() != YGPositionTypeAbsolute) { - 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 + - child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap() + - childLayout.computedFlexBasis.unwrap(); - 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); - - if (isNodeBaselineLayout) { - // If the child is baseline aligned then the cross dimension is - // calculated by adding maxAscent and maxDescent from the baseline. - const double ascent = YGBaseline(child, layoutContext) + - child - ->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth) - .unwrap(); - const double descent = - child->getLayout().measuredDimensions[YGDimensionHeight] + - child - ->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth) - .unwrap() - - ascent; - - maxAscentForCurrentLine = - YGFloatMax(maxAscentForCurrentLine, ascent); - maxDescentForCurrentLine = - YGFloatMax(maxDescentForCurrentLine, descent); - } else { - // The cross dimension is the max of the elements dimension since - // there can only be one element in that cross dimension in the case - // when the items are not baseline aligned - 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 += trailingPaddingAndBorderMain; - - if (isNodeBaselineLayout) { - collectedFlexItemsValues.crossDim = - maxAscentForCurrentLine + maxDescentForCurrentLine; - } -} - -// -// This is the main routine that implements a subset of the flexbox layout -// algorithm described in the W3C CSS documentation: -// https://www.w3.org/TR/CSS3-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/CSS3-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 double availableWidth, - const double availableHeight, - const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const double ownerWidth, - const double ownerHeight, - const bool performLayout, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - const uint32_t depth, - const uint32_t generationCount, - const LayoutPassReason reason) { - 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"); - - (performLayout ? layoutMarkerData.layouts : layoutMarkerData.measures) += 1; - - // 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); - - const YGEdge startEdge = - direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight; - const YGEdge endEdge = direction == YGDirectionLTR ? YGEdgeRight : YGEdgeLeft; - - const double marginRowLeading = - node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap(); - node->setLayoutMargin(marginRowLeading, startEdge); - const double marginRowTrailing = - node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap(); - node->setLayoutMargin(marginRowTrailing, endEdge); - const double marginColumnLeading = - node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap(); - node->setLayoutMargin(marginColumnLeading, YGEdgeTop); - const double marginColumnTrailing = - node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap(); - node->setLayoutMargin(marginColumnTrailing, YGEdgeBottom); - - const double marginAxisRow = marginRowLeading + marginRowTrailing; - const double marginAxisColumn = marginColumnLeading + marginColumnTrailing; - - node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), startEdge); - node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), endEdge); - node->setLayoutBorder(node->getLeadingBorder(flexColumnDirection), YGEdgeTop); - node->setLayoutBorder( - node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); - - node->setLayoutPadding( - node->getLeadingPadding(flexRowDirection, ownerWidth).unwrap(), - startEdge); - node->setLayoutPadding( - node->getTrailingPadding(flexRowDirection, ownerWidth).unwrap(), endEdge); - node->setLayoutPadding( - node->getLeadingPadding(flexColumnDirection, ownerWidth).unwrap(), - YGEdgeTop); - node->setLayoutPadding( - node->getTrailingPadding(flexColumnDirection, ownerWidth).unwrap(), - YGEdgeBottom); - - if (node->hasMeasureFunc()) { - YGNodeWithMeasureFuncSetMeasuredDimensions( - node, - availableWidth - marginAxisRow, - availableHeight - marginAxisColumn, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight, - layoutMarkerData, - layoutContext, - reason); - return; - } - - const uint32_t childCount = YGNodeGetChildCount(node); - if (childCount == 0) { - YGNodeEmptyContainerSetMeasuredDimensions( - node, - availableWidth - marginAxisRow, - availableHeight - marginAxisColumn, - 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 - marginAxisRow, - availableHeight - marginAxisColumn, - 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(layoutContext); - // 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 double mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; - const double crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth; - - const double paddingAndBorderAxisMain = - YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth); - const double leadingPaddingAndBorderCross = - node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); - const double trailingPaddingAndBorderCross = - node->getTrailingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); - const double paddingAndBorderAxisCross = - leadingPaddingAndBorderCross + trailingPaddingAndBorderCross; - - YGMeasureMode measureModeMainDim = - isMainAxisRow ? widthMeasureMode : heightMeasureMode; - YGMeasureMode measureModeCrossDim = - isMainAxisRow ? heightMeasureMode : widthMeasureMode; - - const double paddingAndBorderAxisRow = - isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross; - const double paddingAndBorderAxisColumn = - isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; - - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - - double availableInnerWidth = YGNodeCalculateAvailableInnerDim( - node, - YGDimensionWidth, - availableWidth - marginAxisRow, - paddingAndBorderAxisRow, - ownerWidth); - double availableInnerHeight = YGNodeCalculateAvailableInnerDim( - node, - YGDimensionHeight, - availableHeight - marginAxisColumn, - paddingAndBorderAxisColumn, - ownerHeight); - - double availableInnerMainDim = - isMainAxisRow ? availableInnerWidth : availableInnerHeight; - const double availableInnerCrossDim = - isMainAxisRow ? availableInnerHeight : availableInnerWidth; - - // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - - double totalOuterFlexBasis = YGNodeComputeFlexBasisForChildren( - node, - availableInnerWidth, - availableInnerHeight, - widthMeasureMode, - heightMeasureMode, - direction, - mainAxis, - config, - performLayout, - layoutMarkerData, - layoutContext, - depth, - generationCount); - - 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. - double totalLineCrossDim = 0; - - // Max main dimension of all the lines. - double 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) { - const auto& minDimensions = node->getStyle().minDimensions(); - const auto& maxDimensions = node->getStyle().maxDimensions(); - const double minInnerWidth = - YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() - - paddingAndBorderAxisRow; - const double maxInnerWidth = - YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() - - paddingAndBorderAxisRow; - const double minInnerHeight = - YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight) - .unwrap() - - paddingAndBorderAxisColumn; - const double maxInnerHeight = - YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight) - .unwrap() - - paddingAndBorderAxisColumn; - - const double minInnerMainDim = - isMainAxisRow ? minInnerWidth : minInnerHeight; - const double maxInnerMainDim = - isMainAxisRow ? maxInnerWidth : maxInnerHeight; - - 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, - layoutMarkerData, - layoutContext, - depth, - generationCount); - } - - 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, - layoutContext); - - double 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( - child->getLeadingPosition(crossAxis, availableInnerCrossDim) - .unwrap() + - node->getLeadingBorder(crossAxis) + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), - 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) + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), - pos[crossAxis]); - } - } else { - double 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)) { - double childMainSize = - child->getLayout().measuredDimensions[dim[mainAxis]]; - const auto& childStyle = child->getStyle(); - double childCrossSize = !childStyle.aspectRatio().isUndefined() - ? child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap() + - (isMainAxisRow - ? childMainSize / childStyle.aspectRatio().unwrap() - : childMainSize * childStyle.aspectRatio().unwrap()) - : collectedFlexItemsValues.crossDim; - - childMainSize += - child->getMarginForAxis(mainAxis, availableInnerWidth) - .unwrap(); - - YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; - YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; - YGConstrainMaxSizeForMode( - child, - mainAxis, - availableInnerMainDim, - availableInnerWidth, - &childMainMeasureMode, - &childMainSize); - YGConstrainMaxSizeForMode( - child, - crossAxis, - availableInnerCrossDim, - availableInnerWidth, - &childCrossMeasureMode, - &childCrossSize); - - const double childWidth = - isMainAxisRow ? childMainSize : childCrossSize; - const double childHeight = - !isMainAxisRow ? childMainSize : childCrossSize; - - auto alignContent = node->getStyle().alignContent(); - auto crossAxisDoesNotGrow = - alignContent != YGAlignStretch && isNodeFlexWrap; - const YGMeasureMode childWidthMeasureMode = - YGFloatIsUndefined(childWidth) || - (!isMainAxisRow && crossAxisDoesNotGrow) - ? YGMeasureModeUndefined - : YGMeasureModeExactly; - const YGMeasureMode childHeightMeasureMode = - YGFloatIsUndefined(childHeight) || - (isMainAxisRow && crossAxisDoesNotGrow) - ? YGMeasureModeUndefined - : YGMeasureModeExactly; - - YGLayoutNodeInternal( - child, - childWidth, - childHeight, - direction, - childWidthMeasureMode, - childHeightMeasureMode, - availableInnerWidth, - availableInnerHeight, - true, - LayoutPassReason::kStretch, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - } - } else { - const double remainingCrossDim = containerCrossAxis - - YGNodeDimWithMargin(child, crossAxis, availableInnerWidth); - - if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto && - child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { - leadingCrossDim += YGFloatMax(0.0, remainingCrossDim / 2); - } else if ( - child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { - // No-Op - } else if ( - child->marginLeadingValue(crossAxis).unit == YGUnitAuto) { - leadingCrossDim += YGFloatMax(0.0, 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 - // currentLead stores the size of the cross dim - if (performLayout && (isNodeFlexWrap || YGIsBaselineLayout(node))) { - double crossDimLead = 0; - double currentLead = leadingPaddingAndBorderCross; - if (!YGFloatIsUndefined(availableInnerCrossDim)) { - const double remainingAlignContentDim = - availableInnerCrossDim - totalLineCrossDim; - 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 - double lineHeight = 0; - double maxAscentForCurrentLine = 0; - double maxDescentForCurrentLine = 0; - for (ii = startIndex; ii < childCount; ii++) { - const YGNodeRef child = node->getChild(ii); - if (child->getStyle().display() == YGDisplayNone) { - continue; - } - if (child->getStyle().positionType() != YGPositionTypeAbsolute) { - if (child->getLineIndex() != i) { - break; - } - if (YGNodeIsLayoutDimDefined(child, crossAxis)) { - lineHeight = YGFloatMax( - lineHeight, - child->getLayout().measuredDimensions[dim[crossAxis]] + - child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap()); - } - if (YGNodeAlignItem(node, child) == YGAlignBaseline) { - const double ascent = YGBaseline(child, layoutContext) + - child - ->getLeadingMargin( - YGFlexDirectionColumn, availableInnerWidth) - .unwrap(); - const double descent = - child->getLayout().measuredDimensions[YGDimensionHeight] + - child - ->getMarginForAxis( - YGFlexDirectionColumn, availableInnerWidth) - .unwrap() - - 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() != YGPositionTypeAbsolute) { - switch (YGNodeAlignItem(node, child)) { - case YGAlignFlexStart: { - child->setLayoutPosition( - currentLead + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), - pos[crossAxis]); - break; - } - case YGAlignFlexEnd: { - child->setLayoutPosition( - currentLead + lineHeight - - child->getTrailingMargin(crossAxis, availableInnerWidth) - .unwrap() - - child->getLayout().measuredDimensions[dim[crossAxis]], - pos[crossAxis]); - break; - } - case YGAlignCenter: { - double childHeight = - child->getLayout().measuredDimensions[dim[crossAxis]]; - - child->setLayoutPosition( - currentLead + (lineHeight - childHeight) / 2, - pos[crossAxis]); - break; - } - case YGAlignStretch: { - child->setLayoutPosition( - currentLead + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), - 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 double childWidth = isMainAxisRow - ? (child->getLayout() - .measuredDimensions[YGDimensionWidth] + - child->getMarginForAxis(mainAxis, availableInnerWidth) - .unwrap()) - : lineHeight; - - const double childHeight = !isMainAxisRow - ? (child->getLayout() - .measuredDimensions[YGDimensionHeight] + - child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap()) - : lineHeight; - - if (!(YGFloatsEqual( - childWidth, - child->getLayout() - .measuredDimensions[YGDimensionWidth]) && - YGFloatsEqual( - childHeight, - child->getLayout() - .measuredDimensions[YGDimensionHeight]))) { - YGLayoutNodeInternal( - child, - childWidth, - childHeight, - direction, - YGMeasureModeExactly, - YGMeasureModeExactly, - availableInnerWidth, - availableInnerHeight, - true, - LayoutPassReason::kMultilineStretch, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - } - } - break; - } - case YGAlignBaseline: { - child->setLayoutPosition( - currentLead + maxAscentForCurrentLine - - YGBaseline(child, layoutContext) + - child - ->getLeadingPosition( - YGFlexDirectionColumn, availableInnerCrossDim) - .unwrap(), - 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, - YGNodeBoundAxisWithinMinAndMax( - node, - mainAxis, - YGFloatOptional{maxLineMainDim}, - mainAxisownerSize) - .unwrap()), - 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, - YGNodeBoundAxisWithinMinAndMax( - node, - crossAxis, - YGFloatOptional{ - totalLineCrossDim + paddingAndBorderAxisCross}, - crossAxisownerSize) - .unwrap()), - 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() != YGPositionTypeAbsolute) { - 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().display() == YGDisplayNone || - child->getStyle().positionType() != YGPositionTypeAbsolute) { - continue; - } - YGNodeAbsoluteLayoutChild( - node, - child, - availableInnerWidth, - isMainAxisRow ? measureModeMainDim : measureModeCrossDim, - availableInnerHeight, - direction, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount); - } - - // 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); - } - } - } - } -} - -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) { - constexpr auto N = enums::count(); - const char* kMeasureModeNames[N] = {"UNDEFINED", "EXACTLY", "AT_MOST"}; - const char* kLayoutModeNames[N] = { - "LAY_UNDEFINED", "LAY_EXACTLY", "LAY_AT_MOST"}; - - if (mode >= N) { - return ""; - } - - return performLayout ? kLayoutModeNames[mode] : kMeasureModeNames[mode]; -} - -static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( - YGMeasureMode sizeMode, - double size, - double lastComputedSize) { - return sizeMode == YGMeasureModeExactly && - YGFloatsEqual(size, lastComputedSize); -} - -static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits( - YGMeasureMode sizeMode, - double size, - YGMeasureMode lastSizeMode, - double lastComputedSize) { - return sizeMode == YGMeasureModeAtMost && - lastSizeMode == YGMeasureModeUndefined && - (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); -} - -static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( - YGMeasureMode sizeMode, - double size, - YGMeasureMode lastSizeMode, - double lastSize, - double lastComputedSize) { - return lastSizeMode == YGMeasureModeAtMost && - sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && - !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && - lastSize > size && - (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize)); -} - -YOGA_EXPORT double YGRoundValueToPixelGrid( - const double value, - const double pointScaleFactor, - const bool forceCeil, - const bool forceFloor) { - double scaledValue = value * pointScaleFactor; - // We want to calculate `fractial` such that `floor(scaledValue) = scaledValue - // - fractial`. - double fractial = fmod(scaledValue, 1.0); - if (fractial < 0) { - // This branch is for handling negative numbers for `value`. - // - // Regarding `floor` and `ceil`. Note that for a number x, `floor(x) <= x <= - // ceil(x)` even for negative numbers. Here are a couple of examples: - // - x = 2.2: floor( 2.2) = 2, ceil( 2.2) = 3 - // - x = -2.2: floor(-2.2) = -3, ceil(-2.2) = -2 - // - // Regarding `fmod`. For fractional negative numbers, `fmod` returns a - // negative number. For example, `fmod(-2.2) = -0.2`. However, we want - // `fractial` to be the number such that subtracting it from `value` will - // give us `floor(value)`. In the case of negative numbers, adding 1 to - // `fmod(value)` gives us this. Let's continue the example from above: - // - fractial = fmod(-2.2) = -0.2 - // - Add 1 to the fraction: fractial2 = fractial + 1 = -0.2 + 1 = 0.8 - // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3 - ++fractial; - } - if (YGDoubleEqual(fractial, 0)) { - // First we check if the value is already rounded - scaledValue = scaledValue - fractial; - } else if (YGDoubleEqual(fractial, 1.0)) { - scaledValue = scaledValue - fractial + 1.0; - } else if (forceCeil) { - // Next we check if we need to use forced rounding - scaledValue = scaledValue - fractial + 1.0; - } else if (forceFloor) { - scaledValue = scaledValue - fractial; - } else { - // Finally we just round the value - scaledValue = scaledValue - fractial + - (!YGDoubleIsUndefined(fractial) && - (fractial > 0.5 || YGDoubleEqual(fractial, 0.5)) - ? 1.0 - : 0.0); - } - return (YGDoubleIsUndefined(scaledValue) || - YGDoubleIsUndefined(pointScaleFactor)) - ? YGUndefined - : (scaledValue / pointScaleFactor); -} - -YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( - const YGMeasureMode widthMode, - const double width, - const YGMeasureMode heightMode, - const double height, - const YGMeasureMode lastWidthMode, - const double lastWidth, - const YGMeasureMode lastHeightMode, - const double lastHeight, - const double lastComputedWidth, - const double lastComputedHeight, - const double marginRow, - const double marginColumn, - const YGConfigRef config) { - if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) || - (!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) { - return false; - } - bool useRoundedComparison = - config != nullptr && config->pointScaleFactor != 0; - const double effectiveWidth = useRoundedComparison - ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false) - : width; - const double effectiveHeight = useRoundedComparison - ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false) - : height; - const double effectiveLastWidth = useRoundedComparison - ? YGRoundValueToPixelGrid( - lastWidth, config->pointScaleFactor, false, false) - : lastWidth; - const double 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 double availableWidth, - const double availableHeight, - const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, - const double ownerWidth, - const double ownerHeight, - const bool performLayout, - const LayoutPassReason reason, - const YGConfigRef config, - LayoutData& layoutMarkerData, - void* const layoutContext, - uint32_t depth, - const uint32_t generationCount) { - YGLayout* layout = &node->getLayout(); - - depth++; - - const bool needToVisitNode = - (node->isDirty() && layout->generationCount != generationCount) || - layout->lastOwnerDirection != ownerDirection; - - if (needToVisitNode) { - // Invalidate the cached results. - layout->nextCachedMeasurementsIndex = 0; - layout->cachedLayout.availableWidth = -1; - layout->cachedLayout.availableHeight = -1; - layout->cachedLayout.widthMeasureMode = YGMeasureModeUndefined; - layout->cachedLayout.heightMeasureMode = YGMeasureModeUndefined; - 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->hasMeasureFunc()) { - const double marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); - const double marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); - - // 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; - - (performLayout ? layoutMarkerData.cachedLayouts - : layoutMarkerData.cachedMeasures) += 1; - - if (gPrintChanges && gPrintSkips) { - Log::log( - node, - YGLogLevelVerbose, - nullptr, - "%s%d.{[skipped] ", - YGSpacer(depth), - depth); - node->print(layoutContext); - Log::log( - node, - YGLogLevelVerbose, - nullptr, - "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, - LayoutPassReasonToString(reason)); - } - } else { - if (gPrintChanges) { - Log::log( - node, - YGLogLevelVerbose, - nullptr, - "%s%d.{%s", - YGSpacer(depth), - depth, - needToVisitNode ? "*" : ""); - node->print(layoutContext); - Log::log( - node, - YGLogLevelVerbose, - nullptr, - "wm: %s, hm: %s, aw: %f ah: %f %s\n", - YGMeasureModeName(widthMeasureMode, performLayout), - YGMeasureModeName(heightMeasureMode, performLayout), - availableWidth, - availableHeight, - LayoutPassReasonToString(reason)); - } - - YGNodelayoutImpl( - node, - availableWidth, - availableHeight, - ownerDirection, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight, - performLayout, - config, - layoutMarkerData, - layoutContext, - depth, - generationCount, - reason); - - if (gPrintChanges) { - Log::log( - node, - YGLogLevelVerbose, - nullptr, - "%s%d.}%s", - YGSpacer(depth), - depth, - needToVisitNode ? "*" : ""); - node->print(layoutContext); - Log::log( - node, - YGLogLevelVerbose, - nullptr, - "wm: %s, hm: %s, d: (%f, %f) %s\n", - YGMeasureModeName(widthMeasureMode, performLayout), - YGMeasureModeName(heightMeasureMode, performLayout), - layout->measuredDimensions[YGDimensionWidth], - layout->measuredDimensions[YGDimensionHeight], - LayoutPassReasonToString(reason)); - } - - layout->lastOwnerDirection = ownerDirection; - - if (cachedResults == nullptr) { - if (layout->nextCachedMeasurementsIndex + 1 > - (uint32_t) layoutMarkerData.maxMeasureCache) { - layoutMarkerData.maxMeasureCache = - layout->nextCachedMeasurementsIndex + 1; - } - if (layout->nextCachedMeasurementsIndex == YG_MAX_CACHED_RESULT_COUNT) { - if (gPrintChanges) { - Log::log(node, YGLogLevelVerbose, nullptr, "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); - } - - layout->generationCount = generationCount; - - LayoutType layoutType; - if (performLayout) { - layoutType = !needToVisitNode && cachedResults == &layout->cachedLayout - ? LayoutType::kCachedLayout - : LayoutType::kLayout; - } else { - layoutType = cachedResults != nullptr ? LayoutType::kCachedMeasure - : LayoutType::kMeasure; - } - Event::publish(node, {layoutType, layoutContext}); - - return (needToVisitNode || cachedResults == nullptr); -} - -YOGA_EXPORT void YGConfigSetPointScaleFactor( - const YGConfigRef config, - const double pixelsInPoint) { - YGAssertWithConfig( - config, - pixelsInPoint >= 0.0, - "Scale factor should not be less than zero"); - - // We store points for Pixel as we will use it for rounding - if (pixelsInPoint == 0.0) { - // Zero is used to skip rounding - config->pointScaleFactor = 0.0; - } else { - config->pointScaleFactor = pixelsInPoint; - } -} - -static void YGRoundToPixelGrid( - const YGNodeRef node, - const double pointScaleFactor, - const double absoluteLeft, - const double absoluteTop) { - if (pointScaleFactor == 0.0) { - return; - } - - const double nodeLeft = node->getLayout().position[YGEdgeLeft]; - const double nodeTop = node->getLayout().position[YGEdgeTop]; - - const double nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; - const double nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; - - const double absoluteNodeLeft = absoluteLeft + nodeLeft; - const double absoluteNodeTop = absoluteTop + nodeTop; - - const double absoluteNodeRight = absoluteNodeLeft + nodeWidth; - const double 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 = - !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && - !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); - const bool hasFractionalHeight = - !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && - !YGDoubleEqual(fmod(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); - } -} - -static void unsetUseLegacyFlagRecursively(YGNodeRef node) { - node->getConfig()->useLegacyStretchBehaviour = false; - for (auto child : node->getChildren()) { - unsetUseLegacyFlagRecursively(child); - } -} - -YOGA_EXPORT void YGNodeCalculateLayoutWithContext( - const YGNodeRef node, - const double ownerWidth, - const double ownerHeight, - const YGDirection ownerDirection, - void* layoutContext) { - - Event::publish(node, {layoutContext}); - LayoutData markerData = {}; - - // 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.fetch_add(1, std::memory_order_relaxed); - node->resolveDimension(); - double width = YGUndefined; - YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; - const auto& maxDimensions = node->getStyle().maxDimensions(); - if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { - width = - (YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) - .unwrap(); - widthMeasureMode = YGMeasureModeExactly; - } else if (!YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth) - .isUndefined()) { - width = - YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap(); - widthMeasureMode = YGMeasureModeAtMost; - } else { - width = ownerWidth; - widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined - : YGMeasureModeExactly; - } - - double height = YGUndefined; - YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; - if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { - height = (YGResolveValue( - node->getResolvedDimension(dim[YGFlexDirectionColumn]), - ownerHeight) + - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) - .unwrap(); - heightMeasureMode = YGMeasureModeExactly; - } else if (!YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight) - .isUndefined()) { - height = - YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap(); - heightMeasureMode = YGMeasureModeAtMost; - } else { - height = ownerHeight; - heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined - : YGMeasureModeExactly; - } - if (YGLayoutNodeInternal( - node, - width, - height, - ownerDirection, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight, - true, - LayoutPassReason::kInitial, - node->getConfig(), - markerData, - layoutContext, - 0, // tree root - gCurrentGenerationCount.load(std::memory_order_relaxed))) { - node->setPosition( - node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth); - YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0, 0.0); - -#ifdef DEBUG - if (node->getConfig()->printTree) { - YGNodePrint( - node, - (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); - } -#endif - } - - Event::publish(node, {layoutContext, &markerData}); - - // 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 nodeWithoutLegacyFlag = YGNodeDeepClone(node); - nodeWithoutLegacyFlag->resolveDimension(); - // Recursively mark nodes as dirty - nodeWithoutLegacyFlag->markDirtyAndPropogateDownwards(); - gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed); - // Rerun the layout, and calculate the diff - unsetUseLegacyFlagRecursively(nodeWithoutLegacyFlag); - LayoutData layoutMarkerData = {}; - if (YGLayoutNodeInternal( - nodeWithoutLegacyFlag, - width, - height, - ownerDirection, - widthMeasureMode, - heightMeasureMode, - ownerWidth, - ownerHeight, - true, - LayoutPassReason::kInitial, - nodeWithoutLegacyFlag->getConfig(), - layoutMarkerData, - layoutContext, - 0, // tree root - gCurrentGenerationCount.load(std::memory_order_relaxed))) { - nodeWithoutLegacyFlag->setPosition( - nodeWithoutLegacyFlag->getLayout().direction(), - ownerWidth, - ownerHeight, - ownerWidth); - YGRoundToPixelGrid( - nodeWithoutLegacyFlag, - nodeWithoutLegacyFlag->getConfig()->pointScaleFactor, - 0.0, - 0.0); - - // Set whether the two layouts are different or not. - auto neededLegacyStretchBehaviour = - !nodeWithoutLegacyFlag->isLayoutTreeEqualToNode(*node); - node->setLayoutDoesLegacyFlagAffectsLayout(neededLegacyStretchBehaviour); - -#ifdef DEBUG - if (nodeWithoutLegacyFlag->getConfig()->printTree) { - YGNodePrint( - nodeWithoutLegacyFlag, - (YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle)); - } -#endif - } - YGConfigFreeRecursive(nodeWithoutLegacyFlag); - YGNodeFreeRecursive(nodeWithoutLegacyFlag); - } -} - -YOGA_EXPORT void YGNodeCalculateLayout( - const YGNodeRef node, - const double ownerWidth, - const double ownerHeight, - const YGDirection ownerDirection) { - YGNodeCalculateLayoutWithContext( - node, ownerWidth, ownerHeight, ownerDirection, nullptr); -} - -YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { - if (logger != nullptr) { - config->setLogger(logger); - } else { -#ifdef ANDROID - config->setLogger(&YGAndroidLog); -#else - config->setLogger(&YGDefaultLog); -#endif - } -} - -YOGA_EXPORT void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( - const YGConfigRef config, - const bool shouldDiffLayout) { - config->shouldDiffLayoutWithoutLegacyStretchBehaviour = shouldDiffLayout; -} - -void YGAssert(const bool condition, const char* message) { - if (!condition) { - Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message); - throwLogicalErrorWithMessage(message); - } -} - -void YGAssertWithNode( - const YGNodeRef node, - const bool condition, - const char* message) { - if (!condition) { - Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message); - throwLogicalErrorWithMessage(message); - } -} - -void YGAssertWithConfig( - const YGConfigRef config, - const bool condition, - const char* message) { - if (!condition) { - Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message); - throwLogicalErrorWithMessage(message); - } -} - -YOGA_EXPORT 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]; -} - -YOGA_EXPORT void YGConfigSetUseWebDefaults( - const YGConfigRef config, - const bool enabled) { - config->useWebDefaults = enabled; -} - -YOGA_EXPORT void YGConfigSetUseLegacyStretchBehaviour( - const YGConfigRef config, - const bool useLegacyStretchBehaviour) { - config->useLegacyStretchBehaviour = useLegacyStretchBehaviour; -} - -bool YGConfigGetUseWebDefaults(const YGConfigRef config) { - return config->useWebDefaults; -} - -YOGA_EXPORT void YGConfigSetContext(const YGConfigRef config, void* context) { - config->context = context; -} - -YOGA_EXPORT void* YGConfigGetContext(const YGConfigRef config) { - return config->context; -} - -YOGA_EXPORT void YGConfigSetCloneNodeFunc( - const YGConfigRef config, - const YGCloneNodeFunc callback) { - config->setCloneNodeCallback(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 --git a/yoga/Yoga.h b/yoga/Yoga.h index aa9439ca84..2a4f20591e 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -7,370 +7,15 @@ #pragma once -#include -#include -#include -#include -#include -#include - -#ifndef __cplusplus -#include -#endif - -#include "YGEnums.h" -#include "YGMacros.h" -#include "YGValue.h" - -YG_EXTERN_C_BEGIN - -typedef struct YGSize { - double width; - double height; -} YGSize; - -typedef struct YGConfig* YGConfigRef; - -typedef struct YGNode* YGNodeRef; -typedef const struct YGNode* YGNodeConstRef; - -typedef YGSize (*YGMeasureFunc)( - YGNodeRef node, - double width, - YGMeasureMode widthMode, - double height, - YGMeasureMode heightMode); -typedef double (*YGBaselineFunc)(YGNodeRef node, double width, double height); -typedef void (*YGDirtiedFunc)(YGNodeRef node); -typedef void (*YGPrintFunc)(YGNodeRef node); -typedef void (*YGNodeCleanupFunc)(YGNodeRef node); -typedef int (*YGLogger)( - YGConfigRef config, - 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(YGConfigRef config); -WIN_EXPORT YGNodeRef YGNodeClone(YGNodeRef node); -WIN_EXPORT void YGNodeFree(YGNodeRef node); -WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( - YGNodeRef node, - YGNodeCleanupFunc cleanup); -WIN_EXPORT void YGNodeFreeRecursive(YGNodeRef node); -WIN_EXPORT void YGNodeReset(YGNodeRef node); - -WIN_EXPORT void YGNodeInsertChild( - YGNodeRef node, - YGNodeRef child, - uint32_t index); - -WIN_EXPORT void YGNodeSwapChild( - YGNodeRef node, - YGNodeRef child, - uint32_t index); - -WIN_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); -WIN_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node); -WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index); -WIN_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node); -WIN_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node); -WIN_EXPORT uint32_t YGNodeGetChildCount(YGNodeRef node); -WIN_EXPORT void YGNodeSetChildren( - YGNodeRef owner, - const YGNodeRef children[], - uint32_t count); - -WIN_EXPORT void YGNodeSetIsReferenceBaseline( - YGNodeRef node, - bool isReferenceBaseline); - -WIN_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node); - -WIN_EXPORT void YGNodeCalculateLayout( - YGNodeRef node, - double availableWidth, - double availableHeight, - YGDirection ownerDirection); - -// Mark a node as dirty. Only valid for nodes with a custom measure function -// set. -// -// Yoga knows when to mark all other nodes as dirty but because nodes with -// measure functions depend on information not known to Yoga they must perform -// this dirty marking manually. -WIN_EXPORT void YGNodeMarkDirty(YGNodeRef node); - -// Marks the current node and all its descendants as dirty. -// -// Intended to be used for Yoga benchmarks. Don't use in production, as calling -// `YGCalculateLayout` will cause the recalculation of each and every node. -WIN_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(YGNodeRef node); - -WIN_EXPORT void YGNodePrint(YGNodeRef node, YGPrintOptions options); - -WIN_EXPORT bool YGFloatIsUndefined(double value); - -WIN_EXPORT bool YGNodeCanUseCachedMeasurement( - YGMeasureMode widthMode, - double width, - YGMeasureMode heightMode, - double height, - YGMeasureMode lastWidthMode, - double lastWidth, - YGMeasureMode lastHeightMode, - double lastHeight, - double lastComputedWidth, - double lastComputedHeight, - double marginRow, - double marginColumn, - YGConfigRef config); - -WIN_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeRef srcNode); - -WIN_EXPORT const void* YGNodeGetContext(YGNodeRef node); -WIN_EXPORT void YGNodeSetContext(YGNodeRef node, const void* context); -void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled); -bool YGNodeHasMeasureFunc(YGNodeRef node); -WIN_EXPORT void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc); -bool YGNodeHasBaselineFunc(YGNodeRef node); -void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc); -YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node); -void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc); -void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc); -WIN_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node); -WIN_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout); -YGNodeType YGNodeGetNodeType(YGNodeRef node); -void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType); -WIN_EXPORT bool YGNodeIsDirty(YGNodeRef node); -bool YGNodeLayoutGetDidUseLegacyFlag(YGNodeRef node); - -WIN_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction); -WIN_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetFlexDirection( - YGNodeRef node, - YGFlexDirection flexDirection); -WIN_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetJustifyContent( - YGNodeRef node, - YGJustify justifyContent); -WIN_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetAlignContent( - YGNodeRef node, - YGAlign alignContent); -WIN_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems); -WIN_EXPORT YGAlign YGNodeStyleGetAlignItems(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf); -WIN_EXPORT YGAlign YGNodeStyleGetAlignSelf(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetPositionType( - YGNodeRef node, - YGPositionType positionType); -WIN_EXPORT YGPositionType YGNodeStyleGetPositionType(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap); -WIN_EXPORT YGWrap YGNodeStyleGetFlexWrap(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetOverflow(YGNodeRef node, YGOverflow overflow); -WIN_EXPORT YGOverflow YGNodeStyleGetOverflow(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetDisplay(YGNodeRef node, YGDisplay display); -WIN_EXPORT YGDisplay YGNodeStyleGetDisplay(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetFlex(YGNodeRef node, double flex); -WIN_EXPORT double YGNodeStyleGetFlex(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetFlexGrow(YGNodeRef node, double flexGrow); -WIN_EXPORT double YGNodeStyleGetFlexGrow(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetFlexShrink(YGNodeRef node, double flexShrink); -WIN_EXPORT double YGNodeStyleGetFlexShrink(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetFlexBasis(YGNodeRef node, double flexBasis); -WIN_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, double flexBasis); -WIN_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node); -WIN_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetPosition( - YGNodeRef node, - YGEdge edge, - double position); -WIN_EXPORT void YGNodeStyleSetPositionPercent( - YGNodeRef node, - YGEdge edge, - double position); -WIN_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge); - -WIN_EXPORT void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, double margin); -WIN_EXPORT void YGNodeStyleSetMarginPercent( - YGNodeRef node, - YGEdge edge, - double margin); -WIN_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge); -WIN_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge); - -WIN_EXPORT void YGNodeStyleSetPadding( - YGNodeRef node, - YGEdge edge, - double padding); -WIN_EXPORT void YGNodeStyleSetPaddingPercent( - YGNodeRef node, - YGEdge edge, - double padding); -WIN_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge); - -WIN_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, double border); -WIN_EXPORT double YGNodeStyleGetBorder(YGNodeConstRef node, YGEdge edge); - -WIN_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, double width); -WIN_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, double width); -WIN_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node); -WIN_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, double height); -WIN_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, double height); -WIN_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node); -WIN_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetMinWidth(YGNodeRef node, double minWidth); -WIN_EXPORT void YGNodeStyleSetMinWidthPercent(YGNodeRef node, double minWidth); -WIN_EXPORT YGValue YGNodeStyleGetMinWidth(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetMinHeight(YGNodeRef node, double minHeight); -WIN_EXPORT void YGNodeStyleSetMinHeightPercent(YGNodeRef node, double minHeight); -WIN_EXPORT YGValue YGNodeStyleGetMinHeight(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetMaxWidth(YGNodeRef node, double maxWidth); -WIN_EXPORT void YGNodeStyleSetMaxWidthPercent(YGNodeRef node, double maxWidth); -WIN_EXPORT YGValue YGNodeStyleGetMaxWidth(YGNodeConstRef node); - -WIN_EXPORT void YGNodeStyleSetMaxHeight(YGNodeRef node, double maxHeight); -WIN_EXPORT void YGNodeStyleSetMaxHeightPercent(YGNodeRef node, double maxHeight); -WIN_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node); - -// 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 -WIN_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, double aspectRatio); -WIN_EXPORT double YGNodeStyleGetAspectRatio(YGNodeConstRef node); - -WIN_EXPORT double YGNodeLayoutGetLeft(YGNodeRef node); -WIN_EXPORT double YGNodeLayoutGetTop(YGNodeRef node); -WIN_EXPORT double YGNodeLayoutGetRight(YGNodeRef node); -WIN_EXPORT double YGNodeLayoutGetBottom(YGNodeRef node); -WIN_EXPORT double YGNodeLayoutGetWidth(YGNodeRef node); -WIN_EXPORT double YGNodeLayoutGetHeight(YGNodeRef node); -WIN_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeRef node); -WIN_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeRef node); -bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(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. -WIN_EXPORT double YGNodeLayoutGetMargin(YGNodeRef node, YGEdge edge); -WIN_EXPORT double YGNodeLayoutGetBorder(YGNodeRef node, YGEdge edge); -WIN_EXPORT double YGNodeLayoutGetPadding(YGNodeRef node, YGEdge edge); - -WIN_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger); -WIN_EXPORT void YGAssert(bool condition, const char* message); -WIN_EXPORT void YGAssertWithNode( - YGNodeRef node, - bool condition, - const char* message); -WIN_EXPORT void YGAssertWithConfig( - YGConfigRef config, - 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( - YGConfigRef config, - double pixelsInPoint); -void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( - YGConfigRef config, - 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( - YGConfigRef config, - bool useLegacyStretchBehaviour); - -// YGConfig -WIN_EXPORT YGConfigRef YGConfigNew(void); -WIN_EXPORT void YGConfigFree(YGConfigRef config); -WIN_EXPORT void YGConfigCopy(YGConfigRef dest, YGConfigRef src); -WIN_EXPORT int32_t YGConfigGetInstanceCount(void); - -WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled( - YGConfigRef config, - YGExperimentalFeature feature, - bool enabled); -WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled( - YGConfigRef config, - YGExperimentalFeature feature); - -// Using the web defaults is the preferred configuration for new projects. Usage -// of non web defaults should be considered as legacy. -WIN_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled); -WIN_EXPORT bool YGConfigGetUseWebDefaults(YGConfigRef config); - -WIN_EXPORT void YGConfigSetCloneNodeFunc( - YGConfigRef config, - YGCloneNodeFunc callback); - -// Export only for C# -WIN_EXPORT YGConfigRef YGConfigGetDefault(void); - -WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context); -WIN_EXPORT void* YGConfigGetContext(YGConfigRef config); - -WIN_EXPORT double YGRoundValueToPixelGrid( - double value, - double pointScaleFactor, - bool forceCeil, - bool forceFloor); - -YG_EXTERN_C_END - -#ifdef __cplusplus -YG_EXTERN_CXX_BEGIN - -#include -#include - -// Calls f on each node in the tree including the given node argument. -void YGTraversePreOrder( - YGNodeRef node, - std::function&& f); - -void YGNodeSetChildren(YGNodeRef owner, const std::vector& children); +/** + * `#include ` includes all of Yoga's public headers. + */ -YG_EXTERN_CXX_END -#endif +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/yoga/algorithm/AbsoluteLayout.cpp b/yoga/algorithm/AbsoluteLayout.cpp new file mode 100644 index 0000000000..b14ec39b4b --- /dev/null +++ b/yoga/algorithm/AbsoluteLayout.cpp @@ -0,0 +1,563 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include + +namespace facebook::yoga { + +static inline void setFlexStartLayoutPosition( + const yoga::Node* const parent, + yoga::Node* child, + const Direction direction, + const FlexDirection axis, + const double containingBlockWidth) { + double position = child->style().computeFlexStartMargin( + axis, direction, containingBlockWidth) + + parent->getLayout().border(flexStartEdge(axis)); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + position += parent->getLayout().padding(flexStartEdge(axis)); + } + + child->setLayoutPosition(position, flexStartEdge(axis)); +} + +static inline void setFlexEndLayoutPosition( + const yoga::Node* const parent, + yoga::Node* child, + const Direction direction, + const FlexDirection axis, + const double containingBlockWidth) { + double flexEndPosition = parent->getLayout().border(flexEndEdge(axis)) + + child->style().computeFlexEndMargin( + axis, direction, containingBlockWidth); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + flexEndPosition += parent->getLayout().padding(flexEndEdge(axis)); + } + + child->setLayoutPosition( + getPositionOfOppositeEdge(flexEndPosition, axis, parent, child), + flexStartEdge(axis)); +} + +static inline void setCenterLayoutPosition( + const yoga::Node* const parent, + yoga::Node* child, + const Direction direction, + const FlexDirection axis, + const double containingBlockWidth) { + double parentContentBoxSize = + parent->getLayout().measuredDimension(dimension(axis)) - + parent->getLayout().border(flexStartEdge(axis)) - + parent->getLayout().border(flexEndEdge(axis)); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + parentContentBoxSize -= parent->getLayout().padding(flexStartEdge(axis)); + parentContentBoxSize -= parent->getLayout().padding(flexEndEdge(axis)); + } + + const double childOuterSize = + child->getLayout().measuredDimension(dimension(axis)) + + child->style().computeMarginForAxis(axis, containingBlockWidth); + + double position = (parentContentBoxSize - childOuterSize) / 2.0 + + parent->getLayout().border(flexStartEdge(axis)) + + child->style().computeFlexStartMargin( + axis, direction, containingBlockWidth); + + if (!child->hasErrata(Errata::AbsolutePositionWithoutInsetsExcludesPadding)) { + position += parent->getLayout().padding(flexStartEdge(axis)); + } + + child->setLayoutPosition(position, flexStartEdge(axis)); +} + +static void justifyAbsoluteChild( + const yoga::Node* const parent, + yoga::Node* child, + const Direction direction, + const FlexDirection mainAxis, + const double containingBlockWidth) { + const Justify parentJustifyContent = parent->style().justifyContent(); + switch (parentJustifyContent) { + case Justify::FlexStart: + case Justify::SpaceBetween: + setFlexStartLayoutPosition( + parent, child, direction, mainAxis, containingBlockWidth); + break; + case Justify::FlexEnd: + setFlexEndLayoutPosition( + parent, child, direction, mainAxis, containingBlockWidth); + break; + case Justify::Center: + case Justify::SpaceAround: + case Justify::SpaceEvenly: + setCenterLayoutPosition( + parent, child, direction, mainAxis, containingBlockWidth); + break; + } +} + +static void alignAbsoluteChild( + const yoga::Node* const parent, + yoga::Node* child, + const Direction direction, + const FlexDirection crossAxis, + const double containingBlockWidth) { + Align itemAlign = resolveChildAlignment(parent, child); + const Wrap parentWrap = parent->style().flexWrap(); + if (parentWrap == Wrap::WrapReverse) { + if (itemAlign == Align::FlexEnd) { + itemAlign = Align::FlexStart; + } else if (itemAlign != Align::Center) { + itemAlign = Align::FlexEnd; + } + } + + switch (itemAlign) { + case Align::Auto: + case Align::FlexStart: + case Align::Baseline: + case Align::SpaceAround: + case Align::SpaceBetween: + case Align::Stretch: + case Align::SpaceEvenly: + setFlexStartLayoutPosition( + parent, child, direction, crossAxis, containingBlockWidth); + break; + case Align::FlexEnd: + setFlexEndLayoutPosition( + parent, child, direction, crossAxis, containingBlockWidth); + break; + case Align::Center: + setCenterLayoutPosition( + parent, child, direction, crossAxis, containingBlockWidth); + break; + } +} + +/* + * Absolutely positioned nodes do not participate in flex layout and thus their + * positions can be determined independently from the rest of their siblings. + * For each axis there are essentially two cases: + * + * 1) The node has insets defined. In this case we can just use these to + * determine the position of the node. + * 2) The node does not have insets defined. In this case we look at the style + * of the parent to position the node. Things like justify content and + * align content will move absolute children around. If none of these + * special properties are defined, the child is positioned at the start + * (defined by flex direction) of the leading flex line. + * + * This function does that positioning for the given axis. The spec has more + * information on this topic: https://www.w3.org/TR/css-flexbox-1/#abspos-items + */ +static void positionAbsoluteChild( + const yoga::Node* const containingNode, + const yoga::Node* const parent, + yoga::Node* child, + const Direction direction, + const FlexDirection axis, + const bool isMainAxis, + const double containingBlockWidth, + const double containingBlockHeight) { + const bool isAxisRow = isRow(axis); + const double containingBlockSize = + isAxisRow ? containingBlockWidth : containingBlockHeight; + + // The inline-start position takes priority over the end position in the case + // that they are both set and the node has a fixed width. Thus we only have 2 + // cases here: if inline-start is defined and if inline-end is defined. + // + // Despite checking inline-start to honor prioritization of insets, we write + // to the flex-start edge because this algorithm works by positioning on the + // flex-start edge and then filling in the flex-end direction at the end if + // necessary. + if (child->style().isInlineStartPositionDefined(axis, direction) && + !child->style().isInlineStartPositionAuto(axis, direction)) { + const double positionRelativeToInlineStart = + child->style().computeInlineStartPosition( + axis, direction, containingBlockSize) + + containingNode->style().computeInlineStartBorder(axis, direction) + + child->style().computeInlineStartMargin( + axis, direction, containingBlockSize); + const double positionRelativeToFlexStart = + inlineStartEdge(axis, direction) != flexStartEdge(axis) + ? getPositionOfOppositeEdge( + positionRelativeToInlineStart, axis, containingNode, child) + : positionRelativeToInlineStart; + + child->setLayoutPosition(positionRelativeToFlexStart, flexStartEdge(axis)); + } else if ( + child->style().isInlineEndPositionDefined(axis, direction) && + !child->style().isInlineEndPositionAuto(axis, direction)) { + const double positionRelativeToInlineStart = + containingNode->getLayout().measuredDimension(dimension(axis)) - + child->getLayout().measuredDimension(dimension(axis)) - + containingNode->style().computeInlineEndBorder(axis, direction) - + child->style().computeInlineEndMargin( + axis, direction, containingBlockSize) - + child->style().computeInlineEndPosition( + axis, direction, containingBlockSize); + const double positionRelativeToFlexStart = + inlineStartEdge(axis, direction) != flexStartEdge(axis) + ? getPositionOfOppositeEdge( + positionRelativeToInlineStart, axis, containingNode, child) + : positionRelativeToInlineStart; + + child->setLayoutPosition(positionRelativeToFlexStart, flexStartEdge(axis)); + } else { + isMainAxis ? justifyAbsoluteChild( + parent, child, direction, axis, containingBlockWidth) + : alignAbsoluteChild( + parent, child, direction, axis, containingBlockWidth); + } +} + +void layoutAbsoluteChild( + const yoga::Node* const containingNode, + const yoga::Node* const node, + yoga::Node* const child, + const double containingBlockWidth, + const double containingBlockHeight, + const SizingMode widthMode, + const Direction direction, + LayoutData& layoutMarkerData, + const uint32_t depth, + const uint32_t generationCount) { + const FlexDirection mainAxis = + resolveDirection(node->style().flexDirection(), direction); + const FlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); + const bool isMainAxisRow = isRow(mainAxis); + + double childWidth = YGUndefined; + double childHeight = YGUndefined; + SizingMode childWidthSizingMode = SizingMode::MaxContent; + SizingMode childHeightSizingMode = SizingMode::MaxContent; + + auto marginRow = child->style().computeMarginForAxis( + FlexDirection::Row, containingBlockWidth); + auto marginColumn = child->style().computeMarginForAxis( + FlexDirection::Column, containingBlockWidth); + + if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) { + childWidth = child + ->getResolvedDimension( + direction, + Dimension::Width, + containingBlockWidth, + containingBlockWidth) + .unwrap() + + 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->style().isFlexStartPositionDefined( + FlexDirection::Row, direction) && + child->style().isFlexEndPositionDefined( + FlexDirection::Row, direction) && + !child->style().isFlexStartPositionAuto( + FlexDirection::Row, direction) && + !child->style().isFlexEndPositionAuto(FlexDirection::Row, direction)) { + childWidth = + containingNode->getLayout().measuredDimension(Dimension::Width) - + (containingNode->style().computeFlexStartBorder( + FlexDirection::Row, direction) + + containingNode->style().computeFlexEndBorder( + FlexDirection::Row, direction)) - + (child->style().computeFlexStartPosition( + FlexDirection::Row, direction, containingBlockWidth) + + child->style().computeFlexEndPosition( + FlexDirection::Row, direction, containingBlockWidth)); + childWidth = boundAxis( + child, + FlexDirection::Row, + direction, + childWidth, + containingBlockWidth, + containingBlockWidth); + } + } + + if (child->hasDefiniteLength(Dimension::Height, containingBlockHeight)) { + childHeight = child + ->getResolvedDimension( + direction, + Dimension::Height, + containingBlockHeight, + containingBlockWidth) + .unwrap() + + 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->style().isFlexStartPositionDefined( + FlexDirection::Column, direction) && + child->style().isFlexEndPositionDefined( + FlexDirection::Column, direction) && + !child->style().isFlexStartPositionAuto( + FlexDirection::Column, direction) && + !child->style().isFlexEndPositionAuto( + FlexDirection::Column, direction)) { + childHeight = + containingNode->getLayout().measuredDimension(Dimension::Height) - + (containingNode->style().computeFlexStartBorder( + FlexDirection::Column, direction) + + containingNode->style().computeFlexEndBorder( + FlexDirection::Column, direction)) - + (child->style().computeFlexStartPosition( + FlexDirection::Column, direction, containingBlockHeight) + + child->style().computeFlexEndPosition( + FlexDirection::Column, direction, containingBlockHeight)); + childHeight = boundAxis( + child, + FlexDirection::Column, + direction, + childHeight, + containingBlockHeight, + containingBlockWidth); + } + } + + // 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. + const auto& childStyle = child->style(); + if (yoga::isUndefined(childWidth) ^ yoga::isUndefined(childHeight)) { + if (childStyle.aspectRatio().isDefined()) { + if (yoga::isUndefined(childWidth)) { + childWidth = marginRow + + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); + } else if (yoga::isUndefined(childHeight)) { + childHeight = marginColumn + + (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); + } + } + } + + // If we're still missing one or the other dimension, measure the content. + if (yoga::isUndefined(childWidth) || yoga::isUndefined(childHeight)) { + childWidthSizingMode = yoga::isUndefined(childWidth) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + childHeightSizingMode = yoga::isUndefined(childHeight) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + + // 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 && yoga::isUndefined(childWidth) && + widthMode != SizingMode::MaxContent && + yoga::isDefined(containingBlockWidth) && containingBlockWidth > 0) { + childWidth = containingBlockWidth; + childWidthSizingMode = SizingMode::FitContent; + } + + calculateLayoutInternal( + child, + childWidth, + childHeight, + direction, + childWidthSizingMode, + childHeightSizingMode, + containingBlockWidth, + containingBlockHeight, + false, + LayoutPassReason::kAbsMeasureChild, + layoutMarkerData, + depth, + generationCount); + childWidth = child->getLayout().measuredDimension(Dimension::Width) + + child->style().computeMarginForAxis( + FlexDirection::Row, containingBlockWidth); + childHeight = child->getLayout().measuredDimension(Dimension::Height) + + child->style().computeMarginForAxis( + FlexDirection::Column, containingBlockWidth); + } + + calculateLayoutInternal( + child, + childWidth, + childHeight, + direction, + SizingMode::StretchFit, + SizingMode::StretchFit, + containingBlockWidth, + containingBlockHeight, + true, + LayoutPassReason::kAbsLayout, + layoutMarkerData, + depth, + generationCount); + + positionAbsoluteChild( + containingNode, + node, + child, + direction, + mainAxis, + true /*isMainAxis*/, + containingBlockWidth, + containingBlockHeight); + positionAbsoluteChild( + containingNode, + node, + child, + direction, + crossAxis, + false /*isMainAxis*/, + containingBlockWidth, + containingBlockHeight); +} + +bool layoutAbsoluteDescendants( + yoga::Node* containingNode, + yoga::Node* currentNode, + SizingMode widthSizingMode, + Direction currentNodeDirection, + LayoutData& layoutMarkerData, + uint32_t currentDepth, + uint32_t generationCount, + double currentNodeLeftOffsetFromContainingBlock, + double currentNodeTopOffsetFromContainingBlock, + double containingNodeAvailableInnerWidth, + double containingNodeAvailableInnerHeight) { + bool hasNewLayout = false; + for (auto child : currentNode->getLayoutChildren()) { + if (child->style().display() == Display::None) { + continue; + } else if (child->style().positionType() == PositionType::Absolute) { + const bool absoluteErrata = + currentNode->hasErrata(Errata::AbsolutePercentAgainstInnerSize); + const double containingBlockWidth = absoluteErrata + ? containingNodeAvailableInnerWidth + : containingNode->getLayout().measuredDimension(Dimension::Width) - + containingNode->style().computeBorderForAxis(FlexDirection::Row); + const double containingBlockHeight = absoluteErrata + ? containingNodeAvailableInnerHeight + : containingNode->getLayout().measuredDimension(Dimension::Height) - + containingNode->style().computeBorderForAxis( + FlexDirection::Column); + + layoutAbsoluteChild( + containingNode, + currentNode, + child, + containingBlockWidth, + containingBlockHeight, + widthSizingMode, + currentNodeDirection, + layoutMarkerData, + currentDepth, + generationCount); + + hasNewLayout = hasNewLayout || child->getHasNewLayout(); + + /* + * At this point the child has its position set but only on its the + * parent's flexStart edge. Additionally, this position should be + * interpreted relative to the containing block of the child if it had + * insets defined. So we need to adjust the position by subtracting the + * the parents offset from the containing block. However, getting that + * offset is complicated since the two nodes can have different main/cross + * axes. + */ + const FlexDirection parentMainAxis = resolveDirection( + currentNode->style().flexDirection(), currentNodeDirection); + const FlexDirection parentCrossAxis = + resolveCrossDirection(parentMainAxis, currentNodeDirection); + + if (needsTrailingPosition(parentMainAxis)) { + const bool mainInsetsDefined = isRow(parentMainAxis) + ? child->style().horizontalInsetsDefined() + : child->style().verticalInsetsDefined(); + setChildTrailingPosition( + mainInsetsDefined ? containingNode : currentNode, + child, + parentMainAxis); + } + if (needsTrailingPosition(parentCrossAxis)) { + const bool crossInsetsDefined = isRow(parentCrossAxis) + ? child->style().horizontalInsetsDefined() + : child->style().verticalInsetsDefined(); + setChildTrailingPosition( + crossInsetsDefined ? containingNode : currentNode, + child, + parentCrossAxis); + } + + /* + * At this point we know the left and top physical edges of the child are + * set with positions that are relative to the containing block if insets + * are defined + */ + const double childLeftPosition = + child->getLayout().position(PhysicalEdge::Left); + const double childTopPosition = + child->getLayout().position(PhysicalEdge::Top); + + const double childLeftOffsetFromParent = + child->style().horizontalInsetsDefined() + ? (childLeftPosition - currentNodeLeftOffsetFromContainingBlock) + : childLeftPosition; + const double childTopOffsetFromParent = + child->style().verticalInsetsDefined() + ? (childTopPosition - currentNodeTopOffsetFromContainingBlock) + : childTopPosition; + + child->setLayoutPosition(childLeftOffsetFromParent, PhysicalEdge::Left); + child->setLayoutPosition(childTopOffsetFromParent, PhysicalEdge::Top); + } else if ( + child->style().positionType() == PositionType::Static && + !child->alwaysFormsContainingBlock()) { + // We may write new layout results for absolute descendants of "child" + // which are positioned relative to the current containing block instead + // of their parent. "child" may not be dirty, or have new constraints, so + // absolute positioning may be the first time during this layout pass that + // we need to mutate these descendents. Make sure the path of + // nodes to them is mutable before positioning. + child->cloneChildrenIfNeeded(); + const Direction childDirection = + child->resolveDirection(currentNodeDirection); + // By now all descendants of the containing block that are not absolute + // will have their positions set for left and top. + const double childLeftOffsetFromContainingBlock = + currentNodeLeftOffsetFromContainingBlock + + child->getLayout().position(PhysicalEdge::Left); + const double childTopOffsetFromContainingBlock = + currentNodeTopOffsetFromContainingBlock + + child->getLayout().position(PhysicalEdge::Top); + + hasNewLayout = layoutAbsoluteDescendants( + containingNode, + child, + widthSizingMode, + childDirection, + layoutMarkerData, + currentDepth + 1, + generationCount, + childLeftOffsetFromContainingBlock, + childTopOffsetFromContainingBlock, + containingNodeAvailableInnerWidth, + containingNodeAvailableInnerHeight) || + hasNewLayout; + + if (hasNewLayout) { + child->setHasNewLayout(hasNewLayout); + } + } + } + return hasNewLayout; +} +} // namespace facebook::yoga diff --git a/yoga/algorithm/AbsoluteLayout.h b/yoga/algorithm/AbsoluteLayout.h new file mode 100644 index 0000000000..9c39eb20bc --- /dev/null +++ b/yoga/algorithm/AbsoluteLayout.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +void layoutAbsoluteChild( + const yoga::Node* containingNode, + const yoga::Node* node, + yoga::Node* child, + double containingBlockWidth, + double containingBlockHeight, + SizingMode widthMode, + Direction direction, + LayoutData& layoutMarkerData, + uint32_t depth, + uint32_t generationCount); + +// Returns if some absolute descendant has new layout +bool layoutAbsoluteDescendants( + yoga::Node* containingNode, + yoga::Node* currentNode, + SizingMode widthSizingMode, + Direction currentNodeDirection, + LayoutData& layoutMarkerData, + uint32_t currentDepth, + uint32_t generationCount, + double currentNodeMainOffsetFromContainingBlock, + double currentNodeCrossOffsetFromContainingBlock, + double containingNodeAvailableInnerWidth, + double containingNodeAvailableInnerHeight); + +} // namespace facebook::yoga diff --git a/yoga/algorithm/Align.h b/yoga/algorithm/Align.h new file mode 100644 index 0000000000..bb21fe5dca --- /dev/null +++ b/yoga/algorithm/Align.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +inline Align resolveChildAlignment( + const yoga::Node* node, + const yoga::Node* child) { + const Align align = child->style().alignSelf() == Align::Auto + ? node->style().alignItems() + : child->style().alignSelf(); + if (align == Align::Baseline && isColumn(node->style().flexDirection())) { + return Align::FlexStart; + } + return align; +} + +/** + * Fallback alignment to use on overflow + * https://www.w3.org/TR/css-align-3/#distribution-values + */ +constexpr Align fallbackAlignment(Align align) { + switch (align) { + // Fallback to flex-start + case Align::SpaceBetween: + case Align::Stretch: + return Align::FlexStart; + + // Fallback to safe center. TODO (T208209388): This should be aligned to + // Start instead of FlexStart (for row-reverse containers) + case Align::SpaceAround: + case Align::SpaceEvenly: + return Align::FlexStart; + default: + return align; + } +} + +/** + * Fallback alignment to use on overflow + * https://www.w3.org/TR/css-align-3/#distribution-values + */ +constexpr Justify fallbackAlignment(Justify align) { + switch (align) { + // Fallback to flex-start + case Justify::SpaceBetween: + // TODO: Support `justify-content: stretch` + // case Justify::Stretch: + return Justify::FlexStart; + + // Fallback to safe center. TODO (T208209388): This should be aligned to + // Start instead of FlexStart (for row-reverse containers) + case Justify::SpaceAround: + case Justify::SpaceEvenly: + return Justify::FlexStart; + default: + return align; + } +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/Baseline.cpp b/yoga/algorithm/Baseline.cpp new file mode 100644 index 0000000000..c622231e50 --- /dev/null +++ b/yoga/algorithm/Baseline.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include + +namespace facebook::yoga { + +double calculateBaseline(const yoga::Node* node) { + if (node->hasBaselineFunc()) { + Event::publish(node); + + const double baseline = node->baseline( + node->getLayout().measuredDimension(Dimension::Width), + node->getLayout().measuredDimension(Dimension::Height)); + + Event::publish(node); + + yoga::assertFatalWithNode( + node, + !std::isnan(baseline), + "Expect custom baseline function to not return NaN"); + return baseline; + } + + yoga::Node* baselineChild = nullptr; + for (auto child : node->getLayoutChildren()) { + if (child->getLineIndex() > 0) { + break; + } + if (child->style().positionType() == PositionType::Absolute) { + continue; + } + if (resolveChildAlignment(node, child) == Align::Baseline || + child->isReferenceBaseline()) { + baselineChild = child; + break; + } + + if (baselineChild == nullptr) { + baselineChild = child; + } + } + + if (baselineChild == nullptr) { + return node->getLayout().measuredDimension(Dimension::Height); + } + + const double baseline = calculateBaseline(baselineChild); + return baseline + baselineChild->getLayout().position(PhysicalEdge::Top); +} + +bool isBaselineLayout(const yoga::Node* node) { + if (isColumn(node->style().flexDirection())) { + return false; + } + if (node->style().alignItems() == Align::Baseline) { + return true; + } + for (auto child : node->getLayoutChildren()) { + if (child->style().positionType() != PositionType::Absolute && + child->style().alignSelf() == Align::Baseline) { + return true; + } + } + + return false; +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/Baseline.h b/yoga/algorithm/Baseline.h new file mode 100644 index 0000000000..4036d6ab14 --- /dev/null +++ b/yoga/algorithm/Baseline.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +// Calculate baseline represented as an offset from the top edge of the node. +double calculateBaseline(const yoga::Node* node); + +// Whether any of the children of this node participate in baseline alignment +bool isBaselineLayout(const yoga::Node* node); + +} // namespace facebook::yoga diff --git a/yoga/algorithm/BoundAxis.h b/yoga/algorithm/BoundAxis.h new file mode 100644 index 0000000000..f2f221e1b2 --- /dev/null +++ b/yoga/algorithm/BoundAxis.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +inline double paddingAndBorderForAxis( + const yoga::Node* const node, + const FlexDirection axis, + const Direction direction, + const double widthSize) { + return node->style().computeInlineStartPaddingAndBorder( + axis, direction, widthSize) + + node->style().computeInlineEndPaddingAndBorder( + axis, direction, widthSize); +} + +inline FloatOptional boundAxisWithinMinAndMax( + const yoga::Node* const node, + const Direction direction, + const FlexDirection axis, + const FloatOptional value, + const double axisSize, + const double widthSize) { + FloatOptional min; + FloatOptional max; + + if (isColumn(axis)) { + min = node->style().resolvedMinDimension( + direction, Dimension::Height, axisSize, widthSize); + max = node->style().resolvedMaxDimension( + direction, Dimension::Height, axisSize, widthSize); + } else if (isRow(axis)) { + min = node->style().resolvedMinDimension( + direction, Dimension::Width, axisSize, widthSize); + max = node->style().resolvedMaxDimension( + direction, Dimension::Width, axisSize, widthSize); + } + + if (max >= FloatOptional{0} && value > max) { + return max; + } + + if (min >= FloatOptional{0} && value < min) { + return min; + } + + return value; +} + +// Like boundAxisWithinMinAndMax but also ensures that the value doesn't +// go below the padding and border amount. +inline double boundAxis( + const yoga::Node* const node, + const FlexDirection axis, + const Direction direction, + const double value, + const double axisSize, + const double widthSize) { + return yoga::maxOrDefined( + boundAxisWithinMinAndMax( + node, direction, axis, FloatOptional{value}, axisSize, widthSize) + .unwrap(), + paddingAndBorderForAxis(node, axis, direction, widthSize)); +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/Cache.cpp b/yoga/algorithm/Cache.cpp new file mode 100644 index 0000000000..200de4e696 --- /dev/null +++ b/yoga/algorithm/Cache.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 facebook::yoga { + +static inline bool sizeIsExactAndMatchesOldMeasuredSize( + SizingMode sizeMode, + double size, + double lastComputedSize) { + return sizeMode == SizingMode::StretchFit && + yoga::inexactEquals(size, lastComputedSize); +} + +static inline bool oldSizeIsMaxContentAndStillFits( + SizingMode sizeMode, + double size, + SizingMode lastSizeMode, + double lastComputedSize) { + return sizeMode == SizingMode::FitContent && + lastSizeMode == SizingMode::MaxContent && + (size >= lastComputedSize || yoga::inexactEquals(size, lastComputedSize)); +} + +static inline bool newSizeIsStricterAndStillValid( + SizingMode sizeMode, + double size, + SizingMode lastSizeMode, + double lastSize, + double lastComputedSize) { + return lastSizeMode == SizingMode::FitContent && + sizeMode == SizingMode::FitContent && yoga::isDefined(lastSize) && + yoga::isDefined(size) && yoga::isDefined(lastComputedSize) && + lastSize > size && + (lastComputedSize <= size || yoga::inexactEquals(size, lastComputedSize)); +} + +bool canUseCachedMeasurement( + const SizingMode widthMode, + const double availableWidth, + const SizingMode heightMode, + const double availableHeight, + const SizingMode lastWidthMode, + const double lastAvailableWidth, + const SizingMode lastHeightMode, + const double lastAvailableHeight, + const double lastComputedWidth, + const double lastComputedHeight, + const double marginRow, + const double marginColumn, + const yoga::Config* const config) { + if ((yoga::isDefined(lastComputedHeight) && lastComputedHeight < 0) || + ((yoga::isDefined(lastComputedWidth)) && lastComputedWidth < 0)) { + return false; + } + + const double pointScaleFactor = config->getPointScaleFactor(); + + bool useRoundedComparison = config != nullptr && pointScaleFactor != 0; + const double effectiveWidth = useRoundedComparison + ? roundValueToPixelGrid(availableWidth, pointScaleFactor, false, false) + : availableWidth; + const double effectiveHeight = useRoundedComparison + ? roundValueToPixelGrid(availableHeight, pointScaleFactor, false, false) + : availableHeight; + const double effectiveLastWidth = useRoundedComparison + ? roundValueToPixelGrid( + lastAvailableWidth, pointScaleFactor, false, false) + : lastAvailableWidth; + const double effectiveLastHeight = useRoundedComparison + ? roundValueToPixelGrid( + lastAvailableHeight, pointScaleFactor, false, false) + : lastAvailableHeight; + + const bool hasSameWidthSpec = lastWidthMode == widthMode && + yoga::inexactEquals(effectiveLastWidth, effectiveWidth); + const bool hasSameHeightSpec = lastHeightMode == heightMode && + yoga::inexactEquals(effectiveLastHeight, effectiveHeight); + + const bool widthIsCompatible = + hasSameWidthSpec || + sizeIsExactAndMatchesOldMeasuredSize( + widthMode, availableWidth - marginRow, lastComputedWidth) || + oldSizeIsMaxContentAndStillFits( + widthMode, + availableWidth - marginRow, + lastWidthMode, + lastComputedWidth) || + newSizeIsStricterAndStillValid( + widthMode, + availableWidth - marginRow, + lastWidthMode, + lastAvailableWidth, + lastComputedWidth); + + const bool heightIsCompatible = hasSameHeightSpec || + sizeIsExactAndMatchesOldMeasuredSize( + heightMode, + availableHeight - marginColumn, + lastComputedHeight) || + oldSizeIsMaxContentAndStillFits(heightMode, + availableHeight - marginColumn, + lastHeightMode, + lastComputedHeight) || + newSizeIsStricterAndStillValid(heightMode, + availableHeight - marginColumn, + lastHeightMode, + lastAvailableHeight, + lastComputedHeight); + + return widthIsCompatible && heightIsCompatible; +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/Cache.h b/yoga/algorithm/Cache.h new file mode 100644 index 0000000000..ecfe249321 --- /dev/null +++ b/yoga/algorithm/Cache.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +bool canUseCachedMeasurement( + SizingMode widthMode, + double availableWidth, + SizingMode heightMode, + double availableHeight, + SizingMode lastWidthMode, + double lastAvailableWidth, + SizingMode lastHeightMode, + double lastAvailableHeight, + double lastComputedWidth, + double lastComputedHeight, + double marginRow, + double marginColumn, + const yoga::Config* config); + +} // namespace facebook::yoga diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp new file mode 100644 index 0000000000..6fa1974ef9 --- /dev/null +++ b/yoga/algorithm/CalculateLayout.cpp @@ -0,0 +1,2428 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook::yoga { + +std::atomic gCurrentGenerationCount(0); + +static void constrainMaxSizeForMode( + const yoga::Node* node, + Direction direction, + FlexDirection axis, + double ownerAxisSize, + double ownerWidth, + /*in_out*/ SizingMode* mode, + /*in_out*/ double* size) { + const FloatOptional maxSize = + node->style().resolvedMaxDimension( + direction, dimension(axis), ownerAxisSize, ownerWidth) + + FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth)); + switch (*mode) { + case SizingMode::StretchFit: + case SizingMode::FitContent: + *size = (maxSize.isUndefined() || *size < maxSize.unwrap()) + ? *size + : maxSize.unwrap(); + break; + case SizingMode::MaxContent: + if (maxSize.isDefined()) { + *mode = SizingMode::FitContent; + *size = maxSize.unwrap(); + } + break; + } +} + +static void computeFlexBasisForChild( + const yoga::Node* const node, + yoga::Node* const child, + const double width, + const SizingMode widthMode, + const double height, + const double ownerWidth, + const double ownerHeight, + const SizingMode heightMode, + const Direction direction, + LayoutData& layoutMarkerData, + const uint32_t depth, + const uint32_t generationCount) { + const FlexDirection mainAxis = + resolveDirection(node->style().flexDirection(), direction); + const bool isMainAxisRow = isRow(mainAxis); + const double mainAxisSize = isMainAxisRow ? width : height; + const double mainAxisOwnerSize = isMainAxisRow ? ownerWidth : ownerHeight; + + double childWidth = YGUndefined; + double childHeight = YGUndefined; + SizingMode childWidthSizingMode; + SizingMode childHeightSizingMode; + + const FloatOptional resolvedFlexBasis = child->resolveFlexBasis( + direction, mainAxis, mainAxisOwnerSize, ownerWidth); + const bool isRowStyleDimDefined = + child->hasDefiniteLength(Dimension::Width, ownerWidth); + const bool isColumnStyleDimDefined = + child->hasDefiniteLength(Dimension::Height, ownerHeight); + + if (resolvedFlexBasis.isDefined() && yoga::isDefined(mainAxisSize)) { + if (child->getLayout().computedFlexBasis.isUndefined() || + (child->getConfig()->isExperimentalFeatureEnabled( + ExperimentalFeature::WebFlexBasis) && + child->getLayout().computedFlexBasisGeneration != generationCount)) { + const FloatOptional paddingAndBorder = FloatOptional( + paddingAndBorderForAxis(child, mainAxis, direction, ownerWidth)); + child->setLayoutComputedFlexBasis( + yoga::maxOrDefined(resolvedFlexBasis, paddingAndBorder)); + } + } else if (isMainAxisRow && isRowStyleDimDefined) { + // The width is definite, so use that as the flex basis. + const FloatOptional paddingAndBorder = + FloatOptional(paddingAndBorderForAxis( + child, FlexDirection::Row, direction, ownerWidth)); + + child->setLayoutComputedFlexBasis(yoga::maxOrDefined( + child->getResolvedDimension( + direction, Dimension::Width, ownerWidth, ownerWidth), + paddingAndBorder)); + } else if (!isMainAxisRow && isColumnStyleDimDefined) { + // The height is definite, so use that as the flex basis. + const FloatOptional paddingAndBorder = + FloatOptional(paddingAndBorderForAxis( + child, FlexDirection::Column, direction, ownerWidth)); + child->setLayoutComputedFlexBasis(yoga::maxOrDefined( + child->getResolvedDimension( + direction, Dimension::Height, ownerHeight, ownerWidth), + paddingAndBorder)); + } else { + // Compute the flex basis and hypothetical main size (i.e. the clamped flex + // basis). + childWidthSizingMode = SizingMode::MaxContent; + childHeightSizingMode = SizingMode::MaxContent; + + auto marginRow = + child->style().computeMarginForAxis(FlexDirection::Row, ownerWidth); + auto marginColumn = + child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); + + if (isRowStyleDimDefined) { + childWidth = child + ->getResolvedDimension( + direction, Dimension::Width, ownerWidth, ownerWidth) + .unwrap() + + marginRow; + childWidthSizingMode = SizingMode::StretchFit; + } + if (isColumnStyleDimDefined) { + childHeight = + child + ->getResolvedDimension( + direction, Dimension::Height, ownerHeight, ownerWidth) + .unwrap() + + marginColumn; + childHeightSizingMode = SizingMode::StretchFit; + } + + // The W3C spec doesn't say anything about the 'overflow' property, but all + // major browsers appear to implement the following logic. + if ((!isMainAxisRow && node->style().overflow() == Overflow::Scroll) || + node->style().overflow() != Overflow::Scroll) { + if (yoga::isUndefined(childWidth) && yoga::isDefined(width)) { + childWidth = width; + childWidthSizingMode = SizingMode::FitContent; + } + } + + if ((isMainAxisRow && node->style().overflow() == Overflow::Scroll) || + node->style().overflow() != Overflow::Scroll) { + if (yoga::isUndefined(childHeight) && yoga::isDefined(height)) { + childHeight = height; + childHeightSizingMode = SizingMode::FitContent; + } + } + + const auto& childStyle = child->style(); + if (childStyle.aspectRatio().isDefined()) { + if (!isMainAxisRow && childWidthSizingMode == SizingMode::StretchFit) { + childHeight = marginColumn + + (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); + childHeightSizingMode = SizingMode::StretchFit; + } else if ( + isMainAxisRow && childHeightSizingMode == SizingMode::StretchFit) { + childWidth = marginRow + + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); + childWidthSizingMode = SizingMode::StretchFit; + } + } + + // 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 = + yoga::isDefined(width) && widthMode == SizingMode::StretchFit; + const bool childWidthStretch = + resolveChildAlignment(node, child) == Align::Stretch && + childWidthSizingMode != SizingMode::StretchFit; + if (!isMainAxisRow && !isRowStyleDimDefined && hasExactWidth && + childWidthStretch) { + childWidth = width; + childWidthSizingMode = SizingMode::StretchFit; + if (childStyle.aspectRatio().isDefined()) { + childHeight = + (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); + childHeightSizingMode = SizingMode::StretchFit; + } + } + + const bool hasExactHeight = + yoga::isDefined(height) && heightMode == SizingMode::StretchFit; + const bool childHeightStretch = + resolveChildAlignment(node, child) == Align::Stretch && + childHeightSizingMode != SizingMode::StretchFit; + if (isMainAxisRow && !isColumnStyleDimDefined && hasExactHeight && + childHeightStretch) { + childHeight = height; + childHeightSizingMode = SizingMode::StretchFit; + + if (childStyle.aspectRatio().isDefined()) { + childWidth = + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); + childWidthSizingMode = SizingMode::StretchFit; + } + } + + constrainMaxSizeForMode( + child, + direction, + FlexDirection::Row, + ownerWidth, + ownerWidth, + &childWidthSizingMode, + &childWidth); + constrainMaxSizeForMode( + child, + direction, + FlexDirection::Column, + ownerHeight, + ownerWidth, + &childHeightSizingMode, + &childHeight); + + // Measure the child + calculateLayoutInternal( + child, + childWidth, + childHeight, + direction, + childWidthSizingMode, + childHeightSizingMode, + ownerWidth, + ownerHeight, + false, + LayoutPassReason::kMeasureChild, + layoutMarkerData, + depth, + generationCount); + + child->setLayoutComputedFlexBasis(FloatOptional(yoga::maxOrDefined( + child->getLayout().measuredDimension(dimension(mainAxis)), + paddingAndBorderForAxis(child, mainAxis, direction, ownerWidth)))); + } + child->setLayoutComputedFlexBasisGeneration(generationCount); +} + +static void measureNodeWithMeasureFunc( + yoga::Node* const node, + const Direction direction, + double availableWidth, + double availableHeight, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, + const double ownerWidth, + const double ownerHeight, + LayoutData& layoutMarkerData, + const LayoutPassReason reason) { + yoga::assertFatalWithNode( + node, + node->hasMeasureFunc(), + "Expected node to have custom measure function"); + + if (widthSizingMode == SizingMode::MaxContent) { + availableWidth = YGUndefined; + } + if (heightSizingMode == SizingMode::MaxContent) { + availableHeight = YGUndefined; + } + + const auto& layout = node->getLayout(); + const double paddingAndBorderAxisRow = layout.padding(PhysicalEdge::Left) + + layout.padding(PhysicalEdge::Right) + layout.border(PhysicalEdge::Left) + + layout.border(PhysicalEdge::Right); + const double paddingAndBorderAxisColumn = layout.padding(PhysicalEdge::Top) + + layout.padding(PhysicalEdge::Bottom) + layout.border(PhysicalEdge::Top) + + layout.border(PhysicalEdge::Bottom); + + // We want to make sure we don't call measure with negative size + const double innerWidth = yoga::isUndefined(availableWidth) + ? availableWidth + : yoga::maxOrDefined(0.0, availableWidth - paddingAndBorderAxisRow); + const double innerHeight = yoga::isUndefined(availableHeight) + ? availableHeight + : yoga::maxOrDefined(0.0, availableHeight - paddingAndBorderAxisColumn); + + if (widthSizingMode == SizingMode::StretchFit && + heightSizingMode == SizingMode::StretchFit) { + // Don't bother sizing the text if both dimensions are already defined. + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Row, + direction, + availableWidth, + ownerWidth, + ownerWidth), + Dimension::Width); + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Column, + direction, + availableHeight, + ownerHeight, + ownerWidth), + Dimension::Height); + } else { + Event::publish(node); + + // Measure the text under the current constraints. + const YGSize measuredSize = node->measure( + innerWidth, + measureMode(widthSizingMode), + innerHeight, + measureMode(heightSizingMode)); + + layoutMarkerData.measureCallbacks += 1; + layoutMarkerData.measureCallbackReasonsCount[static_cast(reason)] += + 1; + + Event::publish( + node, + {innerWidth, + unscopedEnum(measureMode(widthSizingMode)), + innerHeight, + unscopedEnum(measureMode(heightSizingMode)), + measuredSize.width, + measuredSize.height, + reason}); + + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Row, + direction, + (widthSizingMode == SizingMode::MaxContent || + widthSizingMode == SizingMode::FitContent) + ? measuredSize.width + paddingAndBorderAxisRow + : availableWidth, + ownerWidth, + ownerWidth), + Dimension::Width); + + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Column, + direction, + (heightSizingMode == SizingMode::MaxContent || + heightSizingMode == SizingMode::FitContent) + ? measuredSize.height + paddingAndBorderAxisColumn + : availableHeight, + ownerHeight, + ownerWidth), + Dimension::Height); + } +} + +// 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 measureNodeWithoutChildren( + yoga::Node* const node, + const Direction direction, + const double availableWidth, + const double availableHeight, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, + const double ownerWidth, + const double ownerHeight) { + const auto& layout = node->getLayout(); + + double width = availableWidth; + if (widthSizingMode == SizingMode::MaxContent || + widthSizingMode == SizingMode::FitContent) { + width = layout.padding(PhysicalEdge::Left) + + layout.padding(PhysicalEdge::Right) + + layout.border(PhysicalEdge::Left) + layout.border(PhysicalEdge::Right); + } + node->setLayoutMeasuredDimension( + boundAxis( + node, FlexDirection::Row, direction, width, ownerWidth, ownerWidth), + Dimension::Width); + + double height = availableHeight; + if (heightSizingMode == SizingMode::MaxContent || + heightSizingMode == SizingMode::FitContent) { + height = layout.padding(PhysicalEdge::Top) + + layout.padding(PhysicalEdge::Bottom) + + layout.border(PhysicalEdge::Top) + layout.border(PhysicalEdge::Bottom); + } + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Column, + direction, + height, + ownerHeight, + ownerWidth), + Dimension::Height); +} + +static bool measureNodeWithFixedSize( + yoga::Node* const node, + const Direction direction, + const double availableWidth, + const double availableHeight, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, + const double ownerWidth, + const double ownerHeight) { + if ((yoga::isDefined(availableWidth) && + widthSizingMode == SizingMode::FitContent && availableWidth <= 0.0) || + (yoga::isDefined(availableHeight) && + heightSizingMode == SizingMode::FitContent && availableHeight <= 0.0) || + (widthSizingMode == SizingMode::StretchFit && + heightSizingMode == SizingMode::StretchFit)) { + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Row, + direction, + yoga::isUndefined(availableWidth) || + (widthSizingMode == SizingMode::FitContent && + availableWidth < 0.0) + ? 0.0 + : availableWidth, + ownerWidth, + ownerWidth), + Dimension::Width); + + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Column, + direction, + yoga::isUndefined(availableHeight) || + (heightSizingMode == SizingMode::FitContent && + availableHeight < 0.0) + ? 0.0 + : availableHeight, + ownerHeight, + ownerWidth), + Dimension::Height); + return true; + } + + return false; +} + +static void zeroOutLayoutRecursively(yoga::Node* const node) { + node->getLayout() = {}; + node->setLayoutDimension(0, Dimension::Width); + node->setLayoutDimension(0, Dimension::Height); + node->setHasNewLayout(true); + + node->cloneChildrenIfNeeded(); + for (const auto child : node->getChildren()) { + zeroOutLayoutRecursively(child); + } +} + +static void cleanupContentsNodesRecursively(yoga::Node* const node) { + for (auto child : node->getChildren()) { + if (child->style().display() == Display::Contents) { + child->getLayout() = {}; + child->setLayoutDimension(0, Dimension::Width); + child->setLayoutDimension(0, Dimension::Height); + child->setHasNewLayout(true); + child->setDirty(false); + child->cloneChildrenIfNeeded(); + + cleanupContentsNodesRecursively(child); + } + } +} + +static double calculateAvailableInnerDimension( + const yoga::Node* const node, + const Direction direction, + const Dimension dimension, + const double availableDim, + const double paddingAndBorder, + const double ownerDim, + const double ownerWidth) { + double availableInnerDim = availableDim - paddingAndBorder; + // Max dimension overrides predefined dimension value; Min dimension in turn + // overrides both of the above + if (yoga::isDefined(availableInnerDim)) { + // We want to make sure our available height does not violate min and max + // constraints + const FloatOptional minDimensionOptional = + node->style().resolvedMinDimension( + direction, dimension, ownerDim, ownerWidth); + const double minInnerDim = minDimensionOptional.isUndefined() + ? 0.0 + : minDimensionOptional.unwrap() - paddingAndBorder; + + const FloatOptional maxDimensionOptional = + node->style().resolvedMaxDimension( + direction, dimension, ownerDim, ownerWidth); + + const double maxInnerDim = maxDimensionOptional.isUndefined() + ? FLT_MAX + : maxDimensionOptional.unwrap() - paddingAndBorder; + availableInnerDim = yoga::maxOrDefined( + yoga::minOrDefined(availableInnerDim, maxInnerDim), minInnerDim); + } + + return availableInnerDim; +} + +static double computeFlexBasisForChildren( + yoga::Node* const node, + const double availableInnerWidth, + const double availableInnerHeight, + SizingMode widthSizingMode, + SizingMode heightSizingMode, + Direction direction, + FlexDirection mainAxis, + bool performLayout, + LayoutData& layoutMarkerData, + const uint32_t depth, + const uint32_t generationCount) { + double totalOuterFlexBasis = 0.0; + YGNodeRef singleFlexChild = nullptr; + auto children = node->getLayoutChildren(); + SizingMode sizingModeMainDim = + isRow(mainAxis) ? widthSizingMode : heightSizingMode; + // 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 (sizingModeMainDim == SizingMode::StretchFit) { + for (auto child : children) { + if (child->isNodeFlexible()) { + if (singleFlexChild != nullptr || + yoga::inexactEquals(child->resolveFlexGrow(), 0.0) || + yoga::inexactEquals(child->resolveFlexShrink(), 0.0)) { + // There is already a flexible child, or this flexible child doesn't + // have flexGrow and flexShrink, abort + singleFlexChild = nullptr; + break; + } else { + singleFlexChild = child; + } + } + } + } + + for (auto child : children) { + child->processDimensions(); + if (child->style().display() == Display::None) { + zeroOutLayoutRecursively(child); + child->setHasNewLayout(true); + child->setDirty(false); + continue; + } + if (performLayout) { + // Set the initial position (relative to the owner). + const Direction childDirection = child->resolveDirection(direction); + child->setPosition( + childDirection, availableInnerWidth, availableInnerHeight); + } + + if (child->style().positionType() == PositionType::Absolute) { + continue; + } + if (child == singleFlexChild) { + child->setLayoutComputedFlexBasisGeneration(generationCount); + child->setLayoutComputedFlexBasis(FloatOptional(0)); + } else { + computeFlexBasisForChild( + node, + child, + availableInnerWidth, + widthSizingMode, + availableInnerHeight, + availableInnerWidth, + availableInnerHeight, + heightSizingMode, + direction, + layoutMarkerData, + depth, + generationCount); + } + + totalOuterFlexBasis += + (child->getLayout().computedFlexBasis.unwrap() + + child->style().computeMarginForAxis(mainAxis, availableInnerWidth)); + } + + return totalOuterFlexBasis; +} + +// 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 distributeFreeSpaceFirstPass is called. +static double distributeFreeSpaceSecondPass( + FlexLine& flexLine, + yoga::Node* const node, + const FlexDirection mainAxis, + const FlexDirection crossAxis, + const Direction direction, + const double ownerWidth, + const double mainAxisOwnerSize, + const double availableInnerMainDim, + const double availableInnerCrossDim, + const double availableInnerWidth, + const double availableInnerHeight, + const bool mainAxisOverflows, + const SizingMode sizingModeCrossDim, + const bool performLayout, + LayoutData& layoutMarkerData, + const uint32_t depth, + const uint32_t generationCount) { + double childFlexBasis = 0; + double flexShrinkScaledFactor = 0; + double flexGrowFactor = 0; + double deltaFreeSpace = 0; + const bool isMainAxisRow = isRow(mainAxis); + const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap; + + for (auto currentLineChild : flexLine.itemsInFlow) { + childFlexBasis = boundAxisWithinMinAndMax( + currentLineChild, + direction, + mainAxis, + currentLineChild->getLayout().computedFlexBasis, + mainAxisOwnerSize, + ownerWidth) + .unwrap(); + double updatedMainSize = childFlexBasis; + + if (yoga::isDefined(flexLine.layout.remainingFreeSpace) && + flexLine.layout.remainingFreeSpace < 0) { + flexShrinkScaledFactor = + -currentLineChild->resolveFlexShrink() * childFlexBasis; + // Is this child able to shrink? + if (flexShrinkScaledFactor != 0) { + double childSize = YGUndefined; + + if (yoga::isDefined(flexLine.layout.totalFlexShrinkScaledFactors) && + flexLine.layout.totalFlexShrinkScaledFactors == 0) { + childSize = childFlexBasis + flexShrinkScaledFactor; + } else { + childSize = childFlexBasis + + (flexLine.layout.remainingFreeSpace / + flexLine.layout.totalFlexShrinkScaledFactors) * + flexShrinkScaledFactor; + } + + updatedMainSize = boundAxis( + currentLineChild, + mainAxis, + direction, + childSize, + availableInnerMainDim, + availableInnerWidth); + } + } else if ( + yoga::isDefined(flexLine.layout.remainingFreeSpace) && + flexLine.layout.remainingFreeSpace > 0) { + flexGrowFactor = currentLineChild->resolveFlexGrow(); + + // Is this child able to grow? + if (!std::isnan(flexGrowFactor) && flexGrowFactor != 0) { + updatedMainSize = boundAxis( + currentLineChild, + mainAxis, + direction, + childFlexBasis + + flexLine.layout.remainingFreeSpace / + flexLine.layout.totalFlexGrowFactors * flexGrowFactor, + availableInnerMainDim, + availableInnerWidth); + } + } + + deltaFreeSpace += updatedMainSize - childFlexBasis; + + const double marginMain = currentLineChild->style().computeMarginForAxis( + mainAxis, availableInnerWidth); + const double marginCross = currentLineChild->style().computeMarginForAxis( + crossAxis, availableInnerWidth); + + double childCrossSize = YGUndefined; + double childMainSize = updatedMainSize + marginMain; + SizingMode childCrossSizingMode; + SizingMode childMainSizingMode = SizingMode::StretchFit; + + const auto& childStyle = currentLineChild->style(); + if (childStyle.aspectRatio().isDefined()) { + childCrossSize = isMainAxisRow + ? (childMainSize - marginMain) / childStyle.aspectRatio().unwrap() + : (childMainSize - marginMain) * childStyle.aspectRatio().unwrap(); + childCrossSizingMode = SizingMode::StretchFit; + + childCrossSize += marginCross; + } else if ( + !std::isnan(availableInnerCrossDim) && + !currentLineChild->hasDefiniteLength( + dimension(crossAxis), availableInnerCrossDim) && + sizingModeCrossDim == SizingMode::StretchFit && + !(isNodeFlexWrap && mainAxisOverflows) && + resolveChildAlignment(node, currentLineChild) == Align::Stretch && + !currentLineChild->style().flexStartMarginIsAuto( + crossAxis, direction) && + !currentLineChild->style().flexEndMarginIsAuto(crossAxis, direction)) { + childCrossSize = availableInnerCrossDim; + childCrossSizingMode = SizingMode::StretchFit; + } else if (!currentLineChild->hasDefiniteLength( + dimension(crossAxis), availableInnerCrossDim)) { + childCrossSize = availableInnerCrossDim; + childCrossSizingMode = yoga::isUndefined(childCrossSize) + ? SizingMode::MaxContent + : SizingMode::FitContent; + } else { + childCrossSize = currentLineChild + ->getResolvedDimension( + direction, + dimension(crossAxis), + availableInnerCrossDim, + availableInnerWidth) + .unwrap() + + marginCross; + const bool isLoosePercentageMeasurement = + currentLineChild->getProcessedDimension(dimension(crossAxis)) + .isPercent() && + sizingModeCrossDim != SizingMode::StretchFit; + childCrossSizingMode = + yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement + ? SizingMode::MaxContent + : SizingMode::StretchFit; + } + + constrainMaxSizeForMode( + currentLineChild, + direction, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainSizingMode, + &childMainSize); + constrainMaxSizeForMode( + currentLineChild, + direction, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossSizingMode, + &childCrossSize); + + const bool requiresStretchLayout = + !currentLineChild->hasDefiniteLength( + dimension(crossAxis), availableInnerCrossDim) && + resolveChildAlignment(node, currentLineChild) == Align::Stretch && + !currentLineChild->style().flexStartMarginIsAuto( + crossAxis, direction) && + !currentLineChild->style().flexEndMarginIsAuto(crossAxis, direction); + + const double childWidth = isMainAxisRow ? childMainSize : childCrossSize; + const double childHeight = !isMainAxisRow ? childMainSize : childCrossSize; + + const SizingMode childWidthSizingMode = + isMainAxisRow ? childMainSizingMode : childCrossSizingMode; + const SizingMode childHeightSizingMode = + !isMainAxisRow ? childMainSizingMode : childCrossSizingMode; + + const bool isLayoutPass = performLayout && !requiresStretchLayout; + // Recursively call the layout algorithm for this child with the updated + // main size. + calculateLayoutInternal( + currentLineChild, + childWidth, + childHeight, + node->getLayout().direction(), + childWidthSizingMode, + childHeightSizingMode, + availableInnerWidth, + availableInnerHeight, + isLayoutPass, + isLayoutPass ? LayoutPassReason::kFlexLayout + : LayoutPassReason::kFlexMeasure, + layoutMarkerData, + depth, + generationCount); + node->setLayoutHadOverflow( + node->getLayout().hadOverflow() || + currentLineChild->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 distributeFreeSpaceFirstPass( + FlexLine& flexLine, + const Direction direction, + const FlexDirection mainAxis, + const double ownerWidth, + const double mainAxisOwnerSize, + const double availableInnerMainDim, + const double availableInnerWidth) { + double flexShrinkScaledFactor = 0; + double flexGrowFactor = 0; + double baseMainSize = 0; + double boundMainSize = 0; + double deltaFreeSpace = 0; + + for (auto currentLineChild : flexLine.itemsInFlow) { + double childFlexBasis = boundAxisWithinMinAndMax( + currentLineChild, + direction, + mainAxis, + currentLineChild->getLayout().computedFlexBasis, + mainAxisOwnerSize, + ownerWidth) + .unwrap(); + + if (flexLine.layout.remainingFreeSpace < 0) { + flexShrinkScaledFactor = + -currentLineChild->resolveFlexShrink() * childFlexBasis; + + // Is this child able to shrink? + if (yoga::isDefined(flexShrinkScaledFactor) && + flexShrinkScaledFactor != 0) { + baseMainSize = childFlexBasis + + flexLine.layout.remainingFreeSpace / + flexLine.layout.totalFlexShrinkScaledFactors * + flexShrinkScaledFactor; + boundMainSize = boundAxis( + currentLineChild, + mainAxis, + direction, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); + if (yoga::isDefined(baseMainSize) && yoga::isDefined(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; + flexLine.layout.totalFlexShrinkScaledFactors -= + (-currentLineChild->resolveFlexShrink() * + currentLineChild->getLayout().computedFlexBasis.unwrap()); + } + } + } else if ( + yoga::isDefined(flexLine.layout.remainingFreeSpace) && + flexLine.layout.remainingFreeSpace > 0) { + flexGrowFactor = currentLineChild->resolveFlexGrow(); + + // Is this child able to grow? + if (yoga::isDefined(flexGrowFactor) && flexGrowFactor != 0) { + baseMainSize = childFlexBasis + + flexLine.layout.remainingFreeSpace / + flexLine.layout.totalFlexGrowFactors * flexGrowFactor; + boundMainSize = boundAxis( + currentLineChild, + mainAxis, + direction, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); + + if (yoga::isDefined(baseMainSize) && yoga::isDefined(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; + flexLine.layout.totalFlexGrowFactors -= flexGrowFactor; + } + } + } + } + flexLine.layout.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 +// the first pass. 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/CSS-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 resolveFlexibleLength( + yoga::Node* const node, + FlexLine& flexLine, + const FlexDirection mainAxis, + const FlexDirection crossAxis, + const Direction direction, + const double ownerWidth, + const double mainAxisOwnerSize, + const double availableInnerMainDim, + const double availableInnerCrossDim, + const double availableInnerWidth, + const double availableInnerHeight, + const bool mainAxisOverflows, + const SizingMode sizingModeCrossDim, + const bool performLayout, + LayoutData& layoutMarkerData, + const uint32_t depth, + const uint32_t generationCount) { + const double originalFreeSpace = flexLine.layout.remainingFreeSpace; + // First pass: detect the flex items whose min/max constraints trigger + distributeFreeSpaceFirstPass( + flexLine, + direction, + mainAxis, + ownerWidth, + mainAxisOwnerSize, + availableInnerMainDim, + availableInnerWidth); + + // Second pass: resolve the sizes of the flexible items + const double distributedFreeSpace = distributeFreeSpaceSecondPass( + flexLine, + node, + mainAxis, + crossAxis, + direction, + ownerWidth, + mainAxisOwnerSize, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + availableInnerHeight, + mainAxisOverflows, + sizingModeCrossDim, + performLayout, + layoutMarkerData, + depth, + generationCount); + + flexLine.layout.remainingFreeSpace = originalFreeSpace - distributedFreeSpace; +} + +static void justifyMainAxis( + yoga::Node* const node, + FlexLine& flexLine, + const FlexDirection mainAxis, + const FlexDirection crossAxis, + const Direction direction, + const SizingMode sizingModeMainDim, + const SizingMode sizingModeCrossDim, + const double mainAxisOwnerSize, + const double ownerWidth, + const double availableInnerMainDim, + const double availableInnerCrossDim, + const double availableInnerWidth, + const bool performLayout) { + const auto& style = node->style(); + + const double leadingPaddingAndBorderMain = + node->style().computeFlexStartPaddingAndBorder( + mainAxis, direction, ownerWidth); + const double trailingPaddingAndBorderMain = + node->style().computeFlexEndPaddingAndBorder( + mainAxis, direction, ownerWidth); + + const double gap = + node->style().computeGapForAxis(mainAxis, availableInnerMainDim); + // If we are using "at most" rules in the main axis, make sure that + // remainingFreeSpace is 0 when min main dimension is not given + if (sizingModeMainDim == SizingMode::FitContent && + flexLine.layout.remainingFreeSpace > 0) { + if (style.minDimension(dimension(mainAxis)).isDefined() && + style + .resolvedMinDimension( + direction, dimension(mainAxis), mainAxisOwnerSize, ownerWidth) + .isDefined()) { + // This condition makes sure that if the size of main dimension(after + // considering child nodes main dim, leading and trailing padding etc) + // falls below min dimension, then the remainingFreeSpace is reassigned + // considering the min dimension + + // `minAvailableMainDim` denotes minimum available space in which child + // can be laid out, it will exclude space consumed by padding and border. + const double minAvailableMainDim = + style + .resolvedMinDimension( + direction, dimension(mainAxis), mainAxisOwnerSize, ownerWidth) + .unwrap() - + leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; + const double occupiedSpaceByChildNodes = + availableInnerMainDim - flexLine.layout.remainingFreeSpace; + flexLine.layout.remainingFreeSpace = yoga::maxOrDefined( + 0.0, minAvailableMainDim - occupiedSpaceByChildNodes); + } else { + flexLine.layout.remainingFreeSpace = 0; + } + } + + // 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. + double leadingMainDim = 0; + double betweenMainDim = gap; + const Justify justifyContent = flexLine.layout.remainingFreeSpace >= 0 + ? node->style().justifyContent() + : fallbackAlignment(node->style().justifyContent()); + + if (flexLine.numberOfAutoMargins == 0) { + switch (justifyContent) { + case Justify::Center: + leadingMainDim = flexLine.layout.remainingFreeSpace / 2; + break; + case Justify::FlexEnd: + leadingMainDim = flexLine.layout.remainingFreeSpace; + break; + case Justify::SpaceBetween: + if (flexLine.itemsInFlow.size() > 1) { + betweenMainDim += flexLine.layout.remainingFreeSpace / + static_cast(flexLine.itemsInFlow.size() - 1); + } + break; + case Justify::SpaceEvenly: + // Space is distributed evenly across all elements + leadingMainDim = flexLine.layout.remainingFreeSpace / + static_cast(flexLine.itemsInFlow.size() + 1); + betweenMainDim += leadingMainDim; + break; + case Justify::SpaceAround: + // Space on the edges is half of the space between elements + leadingMainDim = 0.5 * flexLine.layout.remainingFreeSpace / + static_cast(flexLine.itemsInFlow.size()); + betweenMainDim += leadingMainDim * 2; + break; + case Justify::FlexStart: + break; + } + } + + flexLine.layout.mainDim = leadingPaddingAndBorderMain + leadingMainDim; + flexLine.layout.crossDim = 0; + + double maxAscentForCurrentLine = 0; + double maxDescentForCurrentLine = 0; + bool isNodeBaselineLayout = isBaselineLayout(node); + for (auto child : flexLine.itemsInFlow) { + const LayoutResults& childLayout = child->getLayout(); + if (child->style().flexStartMarginIsAuto(mainAxis, direction) && + flexLine.layout.remainingFreeSpace > 0.0) { + flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / + static_cast(flexLine.numberOfAutoMargins); + } + + if (performLayout) { + child->setLayoutPosition( + childLayout.position(flexStartEdge(mainAxis)) + + flexLine.layout.mainDim, + flexStartEdge(mainAxis)); + } + + if (child != flexLine.itemsInFlow.back()) { + flexLine.layout.mainDim += betweenMainDim; + } + + if (child->style().flexEndMarginIsAuto(mainAxis, direction) && + flexLine.layout.remainingFreeSpace > 0.0) { + flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / + static_cast(flexLine.numberOfAutoMargins); + } + bool canSkipFlex = + !performLayout && sizingModeCrossDim == SizingMode::StretchFit; + 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 + // dimensionWithMargin. + flexLine.layout.mainDim += + child->style().computeMarginForAxis(mainAxis, availableInnerWidth) + + childLayout.computedFlexBasis.unwrap(); + flexLine.layout.crossDim = availableInnerCrossDim; + } else { + // The main dimension is the sum of all the elements dimension plus + // the spacing. + flexLine.layout.mainDim += + child->dimensionWithMargin(mainAxis, availableInnerWidth); + + if (isNodeBaselineLayout) { + // If the child is baseline aligned then the cross dimension is + // calculated by adding maxAscent and maxDescent from the baseline. + const double ascent = calculateBaseline(child) + + child->style().computeFlexStartMargin( + FlexDirection::Column, direction, availableInnerWidth); + const double descent = + child->getLayout().measuredDimension(Dimension::Height) + + child->style().computeMarginForAxis( + FlexDirection::Column, availableInnerWidth) - + ascent; + + maxAscentForCurrentLine = + yoga::maxOrDefined(maxAscentForCurrentLine, ascent); + maxDescentForCurrentLine = + yoga::maxOrDefined(maxDescentForCurrentLine, descent); + } else { + // The cross dimension is the max of the elements dimension since + // there can only be one element in that cross dimension in the case + // when the items are not baseline aligned + flexLine.layout.crossDim = yoga::maxOrDefined( + flexLine.layout.crossDim, + child->dimensionWithMargin(crossAxis, availableInnerWidth)); + } + } + } + flexLine.layout.mainDim += trailingPaddingAndBorderMain; + + if (isNodeBaselineLayout) { + flexLine.layout.crossDim = + maxAscentForCurrentLine + maxDescentForCurrentLine; + } +} + +// +// This is the main routine that implements a subset of the flexbox layout +// algorithm described in the W3C CSS documentation: +// https://www.w3.org/TR/CSS3-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 laid 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) +// - widthSizingMode: indicates the sizing rules for the width (see below +// for explanation) +// - heightSizingMode: 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 laid 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. +// +// When calling calculateLayoutImpl and calculateLayoutInternal, if the +// caller passes an available size of undefined then it must also pass a +// measure mode of SizingMode::MaxContent in that dimension. +// +static void calculateLayoutImpl( + yoga::Node* const node, + const double availableWidth, + const double availableHeight, + const Direction ownerDirection, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, + const double ownerWidth, + const double ownerHeight, + const bool performLayout, + const LayoutPassReason reason, + LayoutData& layoutMarkerData, + const uint32_t depth, + const uint32_t generationCount) { + yoga::assertFatalWithNode( + node, + yoga::isUndefined(availableWidth) + ? widthSizingMode == SizingMode::MaxContent + : true, + "availableWidth is indefinite so widthSizingMode must be " + "SizingMode::MaxContent"); + yoga::assertFatalWithNode( + node, + yoga::isUndefined(availableHeight) + ? heightSizingMode == SizingMode::MaxContent + : true, + "availableHeight is indefinite so heightSizingMode must be " + "SizingMode::MaxContent"); + + (performLayout ? layoutMarkerData.layouts : layoutMarkerData.measures) += 1; + + // Set the resolved resolution in the node's layout. + const Direction direction = node->resolveDirection(ownerDirection); + node->setLayoutDirection(direction); + + const FlexDirection flexRowDirection = + resolveDirection(FlexDirection::Row, direction); + const FlexDirection flexColumnDirection = + resolveDirection(FlexDirection::Column, direction); + + const auto startEdge = + direction == Direction::LTR ? PhysicalEdge::Left : PhysicalEdge::Right; + const auto endEdge = + direction == Direction::LTR ? PhysicalEdge::Right : PhysicalEdge::Left; + + const double marginRowLeading = node->style().computeInlineStartMargin( + flexRowDirection, direction, ownerWidth); + node->setLayoutMargin(marginRowLeading, startEdge); + const double marginRowTrailing = node->style().computeInlineEndMargin( + flexRowDirection, direction, ownerWidth); + node->setLayoutMargin(marginRowTrailing, endEdge); + const double marginColumnLeading = node->style().computeInlineStartMargin( + flexColumnDirection, direction, ownerWidth); + node->setLayoutMargin(marginColumnLeading, PhysicalEdge::Top); + const double marginColumnTrailing = node->style().computeInlineEndMargin( + flexColumnDirection, direction, ownerWidth); + node->setLayoutMargin(marginColumnTrailing, PhysicalEdge::Bottom); + + const double marginAxisRow = marginRowLeading + marginRowTrailing; + const double marginAxisColumn = marginColumnLeading + marginColumnTrailing; + + node->setLayoutBorder( + node->style().computeInlineStartBorder(flexRowDirection, direction), + startEdge); + node->setLayoutBorder( + node->style().computeInlineEndBorder(flexRowDirection, direction), + endEdge); + node->setLayoutBorder( + node->style().computeInlineStartBorder(flexColumnDirection, direction), + PhysicalEdge::Top); + node->setLayoutBorder( + node->style().computeInlineEndBorder(flexColumnDirection, direction), + PhysicalEdge::Bottom); + + node->setLayoutPadding( + node->style().computeInlineStartPadding( + flexRowDirection, direction, ownerWidth), + startEdge); + node->setLayoutPadding( + node->style().computeInlineEndPadding( + flexRowDirection, direction, ownerWidth), + endEdge); + node->setLayoutPadding( + node->style().computeInlineStartPadding( + flexColumnDirection, direction, ownerWidth), + PhysicalEdge::Top); + node->setLayoutPadding( + node->style().computeInlineEndPadding( + flexColumnDirection, direction, ownerWidth), + PhysicalEdge::Bottom); + + if (node->hasMeasureFunc()) { + measureNodeWithMeasureFunc( + node, + direction, + availableWidth - marginAxisRow, + availableHeight - marginAxisColumn, + widthSizingMode, + heightSizingMode, + ownerWidth, + ownerHeight, + layoutMarkerData, + reason); + + // Clean and update all display: contents nodes with a direct path to the + // current node as they will not be traversed + cleanupContentsNodesRecursively(node); + return; + } + + const auto childCount = node->getLayoutChildCount(); + if (childCount == 0) { + measureNodeWithoutChildren( + node, + direction, + availableWidth - marginAxisRow, + availableHeight - marginAxisColumn, + widthSizingMode, + heightSizingMode, + ownerWidth, + ownerHeight); + + // Clean and update all display: contents nodes with a direct path to the + // current node as they will not be traversed + cleanupContentsNodesRecursively(node); + 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 && + measureNodeWithFixedSize( + node, + direction, + availableWidth - marginAxisRow, + availableHeight - marginAxisColumn, + widthSizingMode, + heightSizingMode, + ownerWidth, + ownerHeight)) { + // Clean and update all display: contents nodes with a direct path to the + // current node as they will not be traversed + cleanupContentsNodesRecursively(node); + 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); + + // Clean and update all display: contents nodes with a direct path to the + // current node as they will not be traversed + cleanupContentsNodesRecursively(node); + + // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM + const FlexDirection mainAxis = + resolveDirection(node->style().flexDirection(), direction); + const FlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); + const bool isMainAxisRow = isRow(mainAxis); + const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap; + + const double mainAxisOwnerSize = isMainAxisRow ? ownerWidth : ownerHeight; + const double crossAxisOwnerSize = isMainAxisRow ? ownerHeight : ownerWidth; + + const double paddingAndBorderAxisMain = + paddingAndBorderForAxis(node, mainAxis, direction, ownerWidth); + const double paddingAndBorderAxisCross = + paddingAndBorderForAxis(node, crossAxis, direction, ownerWidth); + const double leadingPaddingAndBorderCross = + node->style().computeFlexStartPaddingAndBorder( + crossAxis, direction, ownerWidth); + + SizingMode sizingModeMainDim = + isMainAxisRow ? widthSizingMode : heightSizingMode; + SizingMode sizingModeCrossDim = + isMainAxisRow ? heightSizingMode : widthSizingMode; + + const double paddingAndBorderAxisRow = + isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross; + const double paddingAndBorderAxisColumn = + isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; + + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS + + double availableInnerWidth = calculateAvailableInnerDimension( + node, + direction, + Dimension::Width, + availableWidth - marginAxisRow, + paddingAndBorderAxisRow, + ownerWidth, + ownerWidth); + double availableInnerHeight = calculateAvailableInnerDimension( + node, + direction, + Dimension::Height, + availableHeight - marginAxisColumn, + paddingAndBorderAxisColumn, + ownerHeight, + ownerWidth); + + double availableInnerMainDim = + isMainAxisRow ? availableInnerWidth : availableInnerHeight; + const double availableInnerCrossDim = + isMainAxisRow ? availableInnerHeight : availableInnerWidth; + + // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM + + // Computed basis + margins + gap + double totalMainDim = 0; + totalMainDim += computeFlexBasisForChildren( + node, + availableInnerWidth, + availableInnerHeight, + widthSizingMode, + heightSizingMode, + direction, + mainAxis, + performLayout, + layoutMarkerData, + depth, + generationCount); + + if (childCount > 1) { + totalMainDim += + node->style().computeGapForAxis(mainAxis, availableInnerMainDim) * + static_cast(childCount - 1); + } + + const bool mainAxisOverflows = + (sizingModeMainDim != SizingMode::MaxContent) && + totalMainDim > availableInnerMainDim; + + if (isNodeFlexWrap && mainAxisOverflows && + sizingModeMainDim == SizingMode::FitContent) { + sizingModeMainDim = SizingMode::StretchFit; + } + // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES + + // Iterator representing the beginning of the current line + Node::LayoutableChildren::Iterator startOfLineIterator = + node->getLayoutChildren().begin(); + + // Number of lines. + size_t lineCount = 0; + + // Accumulated cross dimensions of all lines so far. + double totalLineCrossDim = 0; + + const double crossAxisGap = + node->style().computeGapForAxis(crossAxis, availableInnerCrossDim); + + // Max main dimension of all the lines. + double maxLineMainDim = 0; + for (; startOfLineIterator != node->getLayoutChildren().end(); lineCount++) { + auto flexLine = calculateFlexLine( + node, + ownerDirection, + ownerWidth, + mainAxisOwnerSize, + availableInnerWidth, + availableInnerMainDim, + startOfLineIterator, + lineCount); + + // If we don't need to measure the cross axis, we can skip the entire flex + // step. + const bool canSkipFlex = + !performLayout && sizingModeCrossDim == SizingMode::StretchFit; + + // 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 (sizingModeMainDim != SizingMode::StretchFit) { + const auto& style = node->style(); + const double minInnerWidth = + style + .resolvedMinDimension( + direction, Dimension::Width, ownerWidth, ownerWidth) + .unwrap() - + paddingAndBorderAxisRow; + const double maxInnerWidth = + style + .resolvedMaxDimension( + direction, Dimension::Width, ownerWidth, ownerWidth) + .unwrap() - + paddingAndBorderAxisRow; + const double minInnerHeight = + style + .resolvedMinDimension( + direction, Dimension::Height, ownerHeight, ownerWidth) + .unwrap() - + paddingAndBorderAxisColumn; + const double maxInnerHeight = + style + .resolvedMaxDimension( + direction, Dimension::Height, ownerHeight, ownerWidth) + .unwrap() - + paddingAndBorderAxisColumn; + + const double minInnerMainDim = + isMainAxisRow ? minInnerWidth : minInnerHeight; + const double maxInnerMainDim = + isMainAxisRow ? maxInnerWidth : maxInnerHeight; + + if (yoga::isDefined(minInnerMainDim) && + flexLine.sizeConsumed < minInnerMainDim) { + availableInnerMainDim = minInnerMainDim; + } else if ( + yoga::isDefined(maxInnerMainDim) && + flexLine.sizeConsumed > maxInnerMainDim) { + availableInnerMainDim = maxInnerMainDim; + } else { + bool useLegacyStretchBehaviour = + node->hasErrata(Errata::StretchFlexBasis); + + if (!useLegacyStretchBehaviour && + ((yoga::isDefined(flexLine.layout.totalFlexGrowFactors) && + flexLine.layout.totalFlexGrowFactors == 0) || + (yoga::isDefined(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 = flexLine.sizeConsumed; + } + + sizeBasedOnContent = !useLegacyStretchBehaviour; + } + } + + if (!sizeBasedOnContent && yoga::isDefined(availableInnerMainDim)) { + flexLine.layout.remainingFreeSpace = + availableInnerMainDim - flexLine.sizeConsumed; + } else if (flexLine.sizeConsumed < 0) { + // availableInnerMainDim is indefinite which means the node is being sized + // based on its content. sizeConsumed is negative which means + // the node will allocate 0 points for its content. Consequently, + // remainingFreeSpace is 0 - sizeConsumed. + flexLine.layout.remainingFreeSpace = -flexLine.sizeConsumed; + } + + if (!canSkipFlex) { + resolveFlexibleLength( + node, + flexLine, + mainAxis, + crossAxis, + direction, + ownerWidth, + mainAxisOwnerSize, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + availableInnerHeight, + mainAxisOverflows, + sizingModeCrossDim, + performLayout, + layoutMarkerData, + depth, + generationCount); + } + + node->setLayoutHadOverflow( + node->getLayout().hadOverflow() || + (flexLine.layout.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. + + justifyMainAxis( + node, + flexLine, + mainAxis, + crossAxis, + direction, + sizingModeMainDim, + sizingModeCrossDim, + mainAxisOwnerSize, + ownerWidth, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + performLayout); + + double containerCrossAxis = availableInnerCrossDim; + if (sizingModeCrossDim == SizingMode::MaxContent || + sizingModeCrossDim == SizingMode::FitContent) { + // Compute the cross axis from the max cross dimension of the children. + containerCrossAxis = + boundAxis( + node, + crossAxis, + direction, + flexLine.layout.crossDim + paddingAndBorderAxisCross, + crossAxisOwnerSize, + ownerWidth) - + paddingAndBorderAxisCross; + } + + // If there's no flex wrap, the cross dimension is defined by the container. + if (!isNodeFlexWrap && sizingModeCrossDim == SizingMode::StretchFit) { + flexLine.layout.crossDim = availableInnerCrossDim; + } + + // As-per https://www.w3.org/TR/css-flexbox-1/#cross-sizing, the + // cross-size of the line within a single-line container should be bound to + // min/max constraints before alignment within the line. In a multi-line + // container, affecting alignment between the lines. + if (!isNodeFlexWrap) { + flexLine.layout.crossDim = + boundAxis( + node, + crossAxis, + direction, + flexLine.layout.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 (auto child : flexLine.itemsInFlow) { + double 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 Align alignItem = resolveChildAlignment(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 == Align::Stretch && + !child->style().flexStartMarginIsAuto(crossAxis, direction) && + !child->style().flexEndMarginIsAuto(crossAxis, direction)) { + // If the child defines a definite size for its cross axis, there's + // no need to stretch. + if (!child->hasDefiniteLength( + dimension(crossAxis), availableInnerCrossDim)) { + double childMainSize = + child->getLayout().measuredDimension(dimension(mainAxis)); + const auto& childStyle = child->style(); + double childCrossSize = childStyle.aspectRatio().isDefined() + ? child->style().computeMarginForAxis( + crossAxis, availableInnerWidth) + + (isMainAxisRow + ? childMainSize / childStyle.aspectRatio().unwrap() + : childMainSize * childStyle.aspectRatio().unwrap()) + : flexLine.layout.crossDim; + + childMainSize += child->style().computeMarginForAxis( + mainAxis, availableInnerWidth); + + SizingMode childMainSizingMode = SizingMode::StretchFit; + SizingMode childCrossSizingMode = SizingMode::StretchFit; + constrainMaxSizeForMode( + child, + direction, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainSizingMode, + &childMainSize); + constrainMaxSizeForMode( + child, + direction, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossSizingMode, + &childCrossSize); + + const double childWidth = + isMainAxisRow ? childMainSize : childCrossSize; + const double childHeight = + !isMainAxisRow ? childMainSize : childCrossSize; + + auto alignContent = node->style().alignContent(); + auto crossAxisDoesNotGrow = + alignContent != Align::Stretch && isNodeFlexWrap; + const SizingMode childWidthSizingMode = + yoga::isUndefined(childWidth) || + (!isMainAxisRow && crossAxisDoesNotGrow) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + const SizingMode childHeightSizingMode = + yoga::isUndefined(childHeight) || + (isMainAxisRow && crossAxisDoesNotGrow) + ? SizingMode::MaxContent + : SizingMode::StretchFit; + + calculateLayoutInternal( + child, + childWidth, + childHeight, + direction, + childWidthSizingMode, + childHeightSizingMode, + availableInnerWidth, + availableInnerHeight, + true, + LayoutPassReason::kStretch, + layoutMarkerData, + depth, + generationCount); + } + } else { + const double remainingCrossDim = containerCrossAxis - + child->dimensionWithMargin(crossAxis, availableInnerWidth); + + if (child->style().flexStartMarginIsAuto(crossAxis, direction) && + child->style().flexEndMarginIsAuto(crossAxis, direction)) { + leadingCrossDim += yoga::maxOrDefined(0.0, remainingCrossDim / 2); + } else if (child->style().flexEndMarginIsAuto(crossAxis, direction)) { + // No-Op + } else if (child->style().flexStartMarginIsAuto( + crossAxis, direction)) { + leadingCrossDim += yoga::maxOrDefined(0.0, remainingCrossDim); + } else if (alignItem == Align::FlexStart) { + // No-Op + } else if (alignItem == Align::Center) { + leadingCrossDim += remainingCrossDim / 2; + } else { + leadingCrossDim += remainingCrossDim; + } + } + // And we apply the position + child->setLayoutPosition( + child->getLayout().position(flexStartEdge(crossAxis)) + + totalLineCrossDim + leadingCrossDim, + flexStartEdge(crossAxis)); + } + } + + const double appliedCrossGap = lineCount != 0 ? crossAxisGap : 0.0; + totalLineCrossDim += flexLine.layout.crossDim + appliedCrossGap; + maxLineMainDim = + yoga::maxOrDefined(maxLineMainDim, flexLine.layout.mainDim); + } + + // STEP 8: MULTI-LINE CONTENT ALIGNMENT + // currentLead stores the size of the cross dim + if (performLayout && (isNodeFlexWrap || isBaselineLayout(node))) { + double leadPerLine = 0; + double currentLead = leadingPaddingAndBorderCross; + double extraSpacePerLine = 0; + + const double unclampedCrossDim = sizingModeCrossDim == SizingMode::StretchFit + ? availableInnerCrossDim + paddingAndBorderAxisCross + : node->hasDefiniteLength(dimension(crossAxis), crossAxisOwnerSize) + ? node->getResolvedDimension( + direction, + dimension(crossAxis), + crossAxisOwnerSize, + ownerWidth) + .unwrap() + : totalLineCrossDim + paddingAndBorderAxisCross; + + const double innerCrossDim = boundAxis( + node, + crossAxis, + direction, + unclampedCrossDim, + crossAxisOwnerSize, + ownerWidth) - + paddingAndBorderAxisCross; + + const double remainingAlignContentDim = innerCrossDim - totalLineCrossDim; + + const auto alignContent = remainingAlignContentDim >= 0 + ? node->style().alignContent() + : fallbackAlignment(node->style().alignContent()); + + switch (alignContent) { + case Align::FlexEnd: + currentLead += remainingAlignContentDim; + break; + case Align::Center: + currentLead += remainingAlignContentDim / 2; + break; + case Align::Stretch: + extraSpacePerLine = + remainingAlignContentDim / static_cast(lineCount); + break; + case Align::SpaceAround: + currentLead += + remainingAlignContentDim / (2 * static_cast(lineCount)); + leadPerLine = remainingAlignContentDim / static_cast(lineCount); + break; + case Align::SpaceEvenly: + currentLead += + remainingAlignContentDim / static_cast(lineCount + 1); + leadPerLine = + remainingAlignContentDim / static_cast(lineCount + 1); + break; + case Align::SpaceBetween: + if (lineCount > 1) { + leadPerLine = + remainingAlignContentDim / static_cast(lineCount - 1); + } + break; + case Align::Auto: + case Align::FlexStart: + case Align::Baseline: + break; + } + Node::LayoutableChildren::Iterator endIterator = + node->getLayoutChildren().begin(); + for (size_t i = 0; i < lineCount; i++) { + const Node::LayoutableChildren::Iterator startIterator = endIterator; + auto iterator = startIterator; + + // compute the line's height and find the endIndex + double lineHeight = 0; + double maxAscentForCurrentLine = 0; + double maxDescentForCurrentLine = 0; + for (; iterator != node->getLayoutChildren().end(); iterator++) { + const auto child = *iterator; + if (child->style().display() == Display::None) { + continue; + } + if (child->style().positionType() != PositionType::Absolute) { + if (child->getLineIndex() != i) { + break; + } + if (child->isLayoutDimensionDefined(crossAxis)) { + lineHeight = yoga::maxOrDefined( + lineHeight, + child->getLayout().measuredDimension(dimension(crossAxis)) + + child->style().computeMarginForAxis( + crossAxis, availableInnerWidth)); + } + if (resolveChildAlignment(node, child) == Align::Baseline) { + const double ascent = calculateBaseline(child) + + child->style().computeFlexStartMargin( + FlexDirection::Column, direction, availableInnerWidth); + const double descent = + child->getLayout().measuredDimension(Dimension::Height) + + child->style().computeMarginForAxis( + FlexDirection::Column, availableInnerWidth) - + ascent; + maxAscentForCurrentLine = + yoga::maxOrDefined(maxAscentForCurrentLine, ascent); + maxDescentForCurrentLine = + yoga::maxOrDefined(maxDescentForCurrentLine, descent); + lineHeight = yoga::maxOrDefined( + lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine); + } + } + } + endIterator = iterator; + currentLead += i != 0 ? crossAxisGap : 0; + lineHeight += extraSpacePerLine; + + for (iterator = startIterator; iterator != endIterator; iterator++) { + const auto child = *iterator; + if (child->style().display() == Display::None) { + continue; + } + if (child->style().positionType() != PositionType::Absolute) { + switch (resolveChildAlignment(node, child)) { + case Align::FlexStart: { + child->setLayoutPosition( + currentLead + + child->style().computeFlexStartPosition( + crossAxis, direction, availableInnerWidth), + flexStartEdge(crossAxis)); + break; + } + case Align::FlexEnd: { + child->setLayoutPosition( + currentLead + lineHeight - + child->style().computeFlexEndMargin( + crossAxis, direction, availableInnerWidth) - + child->getLayout().measuredDimension( + dimension(crossAxis)), + flexStartEdge(crossAxis)); + break; + } + case Align::Center: { + double childHeight = + child->getLayout().measuredDimension(dimension(crossAxis)); + + child->setLayoutPosition( + currentLead + (lineHeight - childHeight) / 2, + flexStartEdge(crossAxis)); + break; + } + case Align::Stretch: { + child->setLayoutPosition( + currentLead + + child->style().computeFlexStartMargin( + crossAxis, direction, availableInnerWidth), + flexStartEdge(crossAxis)); + + // Remeasure child with the line height as it as been only + // measured with the owners height yet. + if (!child->hasDefiniteLength( + dimension(crossAxis), availableInnerCrossDim)) { + const double childWidth = isMainAxisRow + ? (child->getLayout().measuredDimension(Dimension::Width) + + child->style().computeMarginForAxis( + mainAxis, availableInnerWidth)) + : leadPerLine + lineHeight; + + const double childHeight = !isMainAxisRow + ? (child->getLayout().measuredDimension(Dimension::Height) + + child->style().computeMarginForAxis( + crossAxis, availableInnerWidth)) + : leadPerLine + lineHeight; + + if (!(yoga::inexactEquals( + childWidth, + child->getLayout().measuredDimension( + Dimension::Width)) && + yoga::inexactEquals( + childHeight, + child->getLayout().measuredDimension( + Dimension::Height)))) { + calculateLayoutInternal( + child, + childWidth, + childHeight, + direction, + SizingMode::StretchFit, + SizingMode::StretchFit, + availableInnerWidth, + availableInnerHeight, + true, + LayoutPassReason::kMultilineStretch, + layoutMarkerData, + depth, + generationCount); + } + } + break; + } + case Align::Baseline: { + child->setLayoutPosition( + currentLead + maxAscentForCurrentLine - + calculateBaseline(child) + + child->style().computeFlexStartPosition( + FlexDirection::Column, + direction, + availableInnerCrossDim), + PhysicalEdge::Top); + + break; + } + case Align::Auto: + case Align::SpaceBetween: + case Align::SpaceAround: + case Align::SpaceEvenly: + break; + } + } + } + + currentLead = currentLead + leadPerLine + lineHeight; + } + } + + // STEP 9: COMPUTING FINAL DIMENSIONS + + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Row, + direction, + availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), + Dimension::Width); + + node->setLayoutMeasuredDimension( + boundAxis( + node, + FlexDirection::Column, + direction, + availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), + Dimension::Height); + + // If the user didn't specify a width or height for the node, set the + // dimensions based on the children. + if (sizingModeMainDim == SizingMode::MaxContent || + (node->style().overflow() != Overflow::Scroll && + sizingModeMainDim == SizingMode::FitContent)) { + // 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( + boundAxis( + node, + mainAxis, + direction, + maxLineMainDim, + mainAxisOwnerSize, + ownerWidth), + dimension(mainAxis)); + + } else if ( + sizingModeMainDim == SizingMode::FitContent && + node->style().overflow() == Overflow::Scroll) { + node->setLayoutMeasuredDimension( + yoga::maxOrDefined( + yoga::minOrDefined( + availableInnerMainDim + paddingAndBorderAxisMain, + boundAxisWithinMinAndMax( + node, + direction, + mainAxis, + FloatOptional{maxLineMainDim}, + mainAxisOwnerSize, + ownerWidth) + .unwrap()), + paddingAndBorderAxisMain), + dimension(mainAxis)); + } + + if (sizingModeCrossDim == SizingMode::MaxContent || + (node->style().overflow() != Overflow::Scroll && + sizingModeCrossDim == SizingMode::FitContent)) { + // 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( + boundAxis( + node, + crossAxis, + direction, + totalLineCrossDim + paddingAndBorderAxisCross, + crossAxisOwnerSize, + ownerWidth), + dimension(crossAxis)); + + } else if ( + sizingModeCrossDim == SizingMode::FitContent && + node->style().overflow() == Overflow::Scroll) { + node->setLayoutMeasuredDimension( + yoga::maxOrDefined( + yoga::minOrDefined( + availableInnerCrossDim + paddingAndBorderAxisCross, + boundAxisWithinMinAndMax( + node, + direction, + crossAxis, + FloatOptional{ + totalLineCrossDim + paddingAndBorderAxisCross}, + crossAxisOwnerSize, + ownerWidth) + .unwrap()), + paddingAndBorderAxisCross), + dimension(crossAxis)); + } + + // As we only wrapped in normal direction yet, we need to reverse the + // positions on wrap-reverse. + if (performLayout && node->style().flexWrap() == Wrap::WrapReverse) { + for (auto child : node->getLayoutChildren()) { + if (child->style().positionType() != PositionType::Absolute) { + child->setLayoutPosition( + node->getLayout().measuredDimension(dimension(crossAxis)) - + child->getLayout().position(flexStartEdge(crossAxis)) - + child->getLayout().measuredDimension(dimension(crossAxis)), + flexStartEdge(crossAxis)); + } + } + } + + if (performLayout) { + // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN + const bool needsMainTrailingPos = needsTrailingPosition(mainAxis); + const bool needsCrossTrailingPos = needsTrailingPosition(crossAxis); + + if (needsMainTrailingPos || needsCrossTrailingPos) { + for (auto child : node->getLayoutChildren()) { + // Absolute children will be handled by their containing block since we + // cannot guarantee that their positions are set when their parents are + // done with layout. + if (child->style().display() == Display::None || + child->style().positionType() == PositionType::Absolute) { + continue; + } + if (needsMainTrailingPos) { + setChildTrailingPosition(node, child, mainAxis); + } + + if (needsCrossTrailingPos) { + setChildTrailingPosition(node, child, crossAxis); + } + } + } + + // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN + // Let the containing block layout its absolute descendants. + if (node->style().positionType() != PositionType::Static || + node->alwaysFormsContainingBlock() || depth == 1) { + layoutAbsoluteDescendants( + node, + node, + isMainAxisRow ? sizingModeMainDim : sizingModeCrossDim, + direction, + layoutMarkerData, + depth, + generationCount, + 0.0, + 0.0, + availableInnerWidth, + availableInnerHeight); + } + } +} + +// +// This is a wrapper around the calculateLayoutImpl function. It determines +// whether the layout request is redundant and can be skipped. +// +// Parameters: +// Input parameters are the same as calculateLayoutImpl (see above) +// Return parameter is true if layout was performed, false if skipped +// +bool calculateLayoutInternal( + yoga::Node* const node, + const double availableWidth, + const double availableHeight, + const Direction ownerDirection, + const SizingMode widthSizingMode, + const SizingMode heightSizingMode, + const double ownerWidth, + const double ownerHeight, + const bool performLayout, + const LayoutPassReason reason, + LayoutData& layoutMarkerData, + uint32_t depth, + const uint32_t generationCount) { + LayoutResults* layout = &node->getLayout(); + + depth++; + + const bool needToVisitNode = + (node->isDirty() && layout->generationCount != generationCount) || + layout->configVersion != node->getConfig()->getVersion() || + layout->lastOwnerDirection != ownerDirection; + + if (needToVisitNode) { + // Invalidate the cached results. + layout->nextCachedMeasurementsIndex = 0; + layout->cachedLayout.availableWidth = -1; + layout->cachedLayout.availableHeight = -1; + layout->cachedLayout.widthSizingMode = SizingMode::MaxContent; + layout->cachedLayout.heightSizingMode = SizingMode::MaxContent; + layout->cachedLayout.computedWidth = -1; + layout->cachedLayout.computedHeight = -1; + } + + CachedMeasurement* 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 laid 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->hasMeasureFunc()) { + const double marginAxisRow = + node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth); + const double marginAxisColumn = + node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); + + // First, try to use the layout cache. + if (canUseCachedMeasurement( + widthSizingMode, + availableWidth, + heightSizingMode, + availableHeight, + layout->cachedLayout.widthSizingMode, + layout->cachedLayout.availableWidth, + layout->cachedLayout.heightSizingMode, + layout->cachedLayout.availableHeight, + layout->cachedLayout.computedWidth, + layout->cachedLayout.computedHeight, + marginAxisRow, + marginAxisColumn, + node->getConfig())) { + cachedResults = &layout->cachedLayout; + } else { + // Try to use the measurement cache. + for (size_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (canUseCachedMeasurement( + widthSizingMode, + availableWidth, + heightSizingMode, + availableHeight, + layout->cachedMeasurements[i].widthSizingMode, + layout->cachedMeasurements[i].availableWidth, + layout->cachedMeasurements[i].heightSizingMode, + layout->cachedMeasurements[i].availableHeight, + layout->cachedMeasurements[i].computedWidth, + layout->cachedMeasurements[i].computedHeight, + marginAxisRow, + marginAxisColumn, + node->getConfig())) { + cachedResults = &layout->cachedMeasurements[i]; + break; + } + } + } + } else if (performLayout) { + if (yoga::inexactEquals( + layout->cachedLayout.availableWidth, availableWidth) && + yoga::inexactEquals( + layout->cachedLayout.availableHeight, availableHeight) && + layout->cachedLayout.widthSizingMode == widthSizingMode && + layout->cachedLayout.heightSizingMode == heightSizingMode) { + cachedResults = &layout->cachedLayout; + } + } else { + for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (yoga::inexactEquals( + layout->cachedMeasurements[i].availableWidth, availableWidth) && + yoga::inexactEquals( + layout->cachedMeasurements[i].availableHeight, availableHeight) && + layout->cachedMeasurements[i].widthSizingMode == widthSizingMode && + layout->cachedMeasurements[i].heightSizingMode == heightSizingMode) { + cachedResults = &layout->cachedMeasurements[i]; + break; + } + } + } + + if (!needToVisitNode && cachedResults != nullptr) { + layout->setMeasuredDimension( + Dimension::Width, cachedResults->computedWidth); + layout->setMeasuredDimension( + Dimension::Height, cachedResults->computedHeight); + + (performLayout ? layoutMarkerData.cachedLayouts + : layoutMarkerData.cachedMeasures) += 1; + } else { + calculateLayoutImpl( + node, + availableWidth, + availableHeight, + ownerDirection, + widthSizingMode, + heightSizingMode, + ownerWidth, + ownerHeight, + performLayout, + reason, + layoutMarkerData, + depth, + generationCount); + + layout->lastOwnerDirection = ownerDirection; + layout->configVersion = node->getConfig()->getVersion(); + + if (cachedResults == nullptr) { + layoutMarkerData.maxMeasureCache = std::max( + layoutMarkerData.maxMeasureCache, + layout->nextCachedMeasurementsIndex + 1u); + + if (layout->nextCachedMeasurementsIndex == + LayoutResults::MaxCachedMeasurements) { + layout->nextCachedMeasurementsIndex = 0; + } + + CachedMeasurement* newCacheEntry = nullptr; + 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->widthSizingMode = widthSizingMode; + newCacheEntry->heightSizingMode = heightSizingMode; + newCacheEntry->computedWidth = + layout->measuredDimension(Dimension::Width); + newCacheEntry->computedHeight = + layout->measuredDimension(Dimension::Height); + } + } + + if (performLayout) { + node->setLayoutDimension( + node->getLayout().measuredDimension(Dimension::Width), + Dimension::Width); + node->setLayoutDimension( + node->getLayout().measuredDimension(Dimension::Height), + Dimension::Height); + + node->setHasNewLayout(true); + node->setDirty(false); + } + + layout->generationCount = generationCount; + + LayoutType layoutType; + if (performLayout) { + layoutType = !needToVisitNode && cachedResults == &layout->cachedLayout + ? LayoutType::kCachedLayout + : LayoutType::kLayout; + } else { + layoutType = cachedResults != nullptr ? LayoutType::kCachedMeasure + : LayoutType::kMeasure; + } + Event::publish(node, {layoutType}); + + return (needToVisitNode || cachedResults == nullptr); +} + +void calculateLayout( + yoga::Node* const node, + const double ownerWidth, + const double ownerHeight, + const Direction ownerDirection) { + Event::publish(node); + LayoutData markerData = {}; + + // 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.fetch_add(1, std::memory_order_relaxed); + node->processDimensions(); + const Direction direction = node->resolveDirection(ownerDirection); + double width = YGUndefined; + SizingMode widthSizingMode = SizingMode::MaxContent; + const auto& style = node->style(); + if (node->hasDefiniteLength(Dimension::Width, ownerWidth)) { + width = + (node->getResolvedDimension( + direction, + dimension(FlexDirection::Row), + ownerWidth, + ownerWidth) + .unwrap() + + node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth)); + widthSizingMode = SizingMode::StretchFit; + } else if (style + .resolvedMaxDimension( + direction, Dimension::Width, ownerWidth, ownerWidth) + .isDefined()) { + width = style + .resolvedMaxDimension( + direction, Dimension::Width, ownerWidth, ownerWidth) + .unwrap(); + widthSizingMode = SizingMode::FitContent; + } else { + width = ownerWidth; + widthSizingMode = yoga::isUndefined(width) ? SizingMode::MaxContent + : SizingMode::StretchFit; + } + + double height = YGUndefined; + SizingMode heightSizingMode = SizingMode::MaxContent; + if (node->hasDefiniteLength(Dimension::Height, ownerHeight)) { + height = + (node->getResolvedDimension( + direction, + dimension(FlexDirection::Column), + ownerHeight, + ownerWidth) + .unwrap() + + node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth)); + heightSizingMode = SizingMode::StretchFit; + } else if (style + .resolvedMaxDimension( + direction, Dimension::Height, ownerHeight, ownerWidth) + .isDefined()) { + height = style + .resolvedMaxDimension( + direction, Dimension::Height, ownerHeight, ownerWidth) + .unwrap(); + heightSizingMode = SizingMode::FitContent; + } else { + height = ownerHeight; + heightSizingMode = yoga::isUndefined(height) ? SizingMode::MaxContent + : SizingMode::StretchFit; + } + if (calculateLayoutInternal( + node, + width, + height, + ownerDirection, + widthSizingMode, + heightSizingMode, + ownerWidth, + ownerHeight, + true, + LayoutPassReason::kInitial, + markerData, + 0, // tree root + gCurrentGenerationCount.load(std::memory_order_relaxed))) { + node->setPosition(node->getLayout().direction(), ownerWidth, ownerHeight); + roundLayoutResultsToPixelGrid(node, 0.0, 0.0); + } + + Event::publish(node, {&markerData}); +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/CalculateLayout.h b/yoga/algorithm/CalculateLayout.h new file mode 100644 index 0000000000..9542b263a5 --- /dev/null +++ b/yoga/algorithm/CalculateLayout.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +void calculateLayout( + yoga::Node* node, + double ownerWidth, + double ownerHeight, + Direction ownerDirection); + +bool calculateLayoutInternal( + yoga::Node* node, + double availableWidth, + double availableHeight, + Direction ownerDirection, + SizingMode widthSizingMode, + SizingMode heightSizingMode, + double ownerWidth, + double ownerHeight, + bool performLayout, + LayoutPassReason reason, + LayoutData& layoutMarkerData, + uint32_t depth, + uint32_t generationCount); + +} // namespace facebook::yoga diff --git a/yoga/algorithm/FlexDirection.h b/yoga/algorithm/FlexDirection.h new file mode 100644 index 0000000000..1dcc939480 --- /dev/null +++ b/yoga/algorithm/FlexDirection.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include + +namespace facebook::yoga { + +inline bool isRow(const FlexDirection flexDirection) { + return flexDirection == FlexDirection::Row || + flexDirection == FlexDirection::RowReverse; +} + +inline bool isColumn(const FlexDirection flexDirection) { + return flexDirection == FlexDirection::Column || + flexDirection == FlexDirection::ColumnReverse; +} + +inline FlexDirection resolveDirection( + const FlexDirection flexDirection, + const Direction direction) { + if (direction == Direction::RTL) { + if (flexDirection == FlexDirection::Row) { + return FlexDirection::RowReverse; + } else if (flexDirection == FlexDirection::RowReverse) { + return FlexDirection::Row; + } + } + + return flexDirection; +} + +inline FlexDirection resolveCrossDirection( + const FlexDirection flexDirection, + const Direction direction) { + return isColumn(flexDirection) + ? resolveDirection(FlexDirection::Row, direction) + : FlexDirection::Column; +} + +inline PhysicalEdge flexStartEdge(FlexDirection flexDirection) { + switch (flexDirection) { + case FlexDirection::Column: + return PhysicalEdge::Top; + case FlexDirection::ColumnReverse: + return PhysicalEdge::Bottom; + case FlexDirection::Row: + return PhysicalEdge::Left; + case FlexDirection::RowReverse: + return PhysicalEdge::Right; + } + + fatalWithMessage("Invalid FlexDirection"); +} + +inline PhysicalEdge flexEndEdge(FlexDirection flexDirection) { + switch (flexDirection) { + case FlexDirection::Column: + return PhysicalEdge::Bottom; + case FlexDirection::ColumnReverse: + return PhysicalEdge::Top; + case FlexDirection::Row: + return PhysicalEdge::Right; + case FlexDirection::RowReverse: + return PhysicalEdge::Left; + } + + fatalWithMessage("Invalid FlexDirection"); +} + +inline PhysicalEdge inlineStartEdge( + FlexDirection flexDirection, + Direction direction) { + if (isRow(flexDirection)) { + return direction == Direction::RTL ? PhysicalEdge::Right + : PhysicalEdge::Left; + } + + return PhysicalEdge::Top; +} + +inline PhysicalEdge inlineEndEdge( + FlexDirection flexDirection, + Direction direction) { + if (isRow(flexDirection)) { + return direction == Direction::RTL ? PhysicalEdge::Left + : PhysicalEdge::Right; + } + + return PhysicalEdge::Bottom; +} + +inline Dimension dimension(FlexDirection flexDirection) { + switch (flexDirection) { + case FlexDirection::Column: + return Dimension::Height; + case FlexDirection::ColumnReverse: + return Dimension::Height; + case FlexDirection::Row: + return Dimension::Width; + case FlexDirection::RowReverse: + return Dimension::Width; + } + + fatalWithMessage("Invalid FlexDirection"); +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/FlexLine.cpp b/yoga/algorithm/FlexLine.cpp new file mode 100644 index 0000000000..bbc91ab54a --- /dev/null +++ b/yoga/algorithm/FlexLine.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include + +namespace facebook::yoga { + +FlexLine calculateFlexLine( + yoga::Node* const node, + const Direction ownerDirection, + const double ownerWidth, + const double mainAxisOwnerSize, + const double availableInnerWidth, + const double availableInnerMainDim, + Node::LayoutableChildren::Iterator& iterator, + const size_t lineCount) { + std::vector itemsInFlow; + itemsInFlow.reserve(node->getChildCount()); + + double sizeConsumed = 0.0; + double totalFlexGrowFactors = 0.0; + double totalFlexShrinkScaledFactors = 0.0; + size_t numberOfAutoMargins = 0; + yoga::Node* firstElementInLine = nullptr; + + double sizeConsumedIncludingMinConstraint = 0; + const Direction direction = node->resolveDirection(ownerDirection); + const FlexDirection mainAxis = + resolveDirection(node->style().flexDirection(), direction); + const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap; + const double gap = + node->style().computeGapForAxis(mainAxis, availableInnerMainDim); + + const auto childrenEnd = node->getLayoutChildren().end(); + // Add items to the current line until it's full or we run out of items. + for (; iterator != childrenEnd; iterator++) { + auto child = *iterator; + if (child->style().display() == Display::None || + child->style().positionType() == PositionType::Absolute) { + continue; + } + + if (firstElementInLine == nullptr) { + firstElementInLine = child; + } + + if (child->style().flexStartMarginIsAuto(mainAxis, ownerDirection)) { + numberOfAutoMargins++; + } + if (child->style().flexEndMarginIsAuto(mainAxis, ownerDirection)) { + numberOfAutoMargins++; + } + + child->setLineIndex(lineCount); + const double childMarginMainAxis = + child->style().computeMarginForAxis(mainAxis, availableInnerWidth); + const double childLeadingGapMainAxis = + child == firstElementInLine ? 0.0 : gap; + const double flexBasisWithMinAndMaxConstraints = + boundAxisWithinMinAndMax( + child, + direction, + mainAxis, + child->getLayout().computedFlexBasis, + mainAxisOwnerSize, + ownerWidth) + .unwrap(); + + // 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 (sizeConsumedIncludingMinConstraint + flexBasisWithMinAndMaxConstraints + + childMarginMainAxis + childLeadingGapMainAxis > + availableInnerMainDim && + isNodeFlexWrap && !itemsInFlow.empty()) { + break; + } + + sizeConsumedIncludingMinConstraint += flexBasisWithMinAndMaxConstraints + + childMarginMainAxis + childLeadingGapMainAxis; + sizeConsumed += flexBasisWithMinAndMaxConstraints + childMarginMainAxis + + childLeadingGapMainAxis; + + if (child->isNodeFlexible()) { + totalFlexGrowFactors += child->resolveFlexGrow(); + + // Unlike the grow factor, the shrink factor is scaled relative to the + // child dimension. + totalFlexShrinkScaledFactors += -child->resolveFlexShrink() * + child->getLayout().computedFlexBasis.unwrap(); + } + + itemsInFlow.push_back(child); + } + + // The total flex factor needs to be floored to 1. + if (totalFlexGrowFactors > 0 && totalFlexGrowFactors < 1) { + totalFlexGrowFactors = 1; + } + + // The total flex shrink factor needs to be floored to 1. + if (totalFlexShrinkScaledFactors > 0 && totalFlexShrinkScaledFactors < 1) { + totalFlexShrinkScaledFactors = 1; + } + + return FlexLine{ + .itemsInFlow = std::move(itemsInFlow), + .sizeConsumed = sizeConsumed, + .numberOfAutoMargins = numberOfAutoMargins, + .layout = FlexLineRunningLayout{ + totalFlexGrowFactors, + totalFlexShrinkScaledFactors, + }}; +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/FlexLine.h b/yoga/algorithm/FlexLine.h new file mode 100644 index 0000000000..d89eb5f604 --- /dev/null +++ b/yoga/algorithm/FlexLine.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +struct FlexLineRunningLayout { + // Total flex grow factors of flex items which are to be laid in the current + // line. This is decremented as free space is distributed. + double totalFlexGrowFactors{0.0}; + + // Total flex shrink factors of flex items which are to be laid in the current + // line. This is decremented as free space is distributed. + double totalFlexShrinkScaledFactors{0.0}; + + // The amount of available space within inner dimensions of the line which may + // still be distributed. + double remainingFreeSpace{0.0}; + + // 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. + double mainDim{0.0}; + + // The size of the crossDim for the row after considering size, padding, + // margin and border of flex items. Used for calculating containers crossSize. + double crossDim{0.0}; +}; + +struct FlexLine { + // List of children which are part of the line flow. This means they are not + // positioned absolutely, or with `display: "none"`, and do not overflow the + // available dimensions. + const std::vector itemsInFlow{}; + + // 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. + const double sizeConsumed{0.0}; + + // Number of edges along the line flow with an auto margin. + const size_t numberOfAutoMargins{0}; + + // Layout information about the line computed in steps after line-breaking + FlexLineRunningLayout layout{}; +}; + +// Calculates where a line starting at a given index should break, returning +// information about the collective children on the liune. +// +// This function assumes that all the children of node have their +// computedFlexBasis properly computed(To do this use +// computeFlexBasisForChildren function). +FlexLine calculateFlexLine( + yoga::Node* node, + Direction ownerDirection, + double ownerWidth, + double mainAxisOwnerSize, + double availableInnerWidth, + double availableInnerMainDim, + Node::LayoutableChildren::Iterator& iterator, + size_t lineCount); + +} // namespace facebook::yoga diff --git a/yoga/algorithm/PixelGrid.cpp b/yoga/algorithm/PixelGrid.cpp new file mode 100644 index 0000000000..e6579f1f7e --- /dev/null +++ b/yoga/algorithm/PixelGrid.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 facebook::yoga { + +double roundValueToPixelGrid( + const double value, + const double pointScaleFactor, + const bool forceCeil, + const bool forceFloor) { + double scaledValue = value * pointScaleFactor; + // We want to calculate `fractial` such that `floor(scaledValue) = scaledValue + // - fractial`. + double fractial = fmod(scaledValue, 1.0); + if (fractial < 0) { + // This branch is for handling negative numbers for `value`. + // + // Regarding `floor` and `ceil`. Note that for a number x, `floor(x) <= x <= + // ceil(x)` even for negative numbers. Here are a couple of examples: + // - x = 2.2: floor( 2.2) = 2, ceil( 2.2) = 3 + // - x = -2.2: floor(-2.2) = -3, ceil(-2.2) = -2 + // + // Regarding `fmodf`. For fractional negative numbers, `fmodf` returns a + // negative number. For example, `fmodf(-2.2) = -0.2`. However, we want + // `fractial` to be the number such that subtracting it from `value` will + // give us `floor(value)`. In the case of negative numbers, adding 1 to + // `fmodf(value)` gives us this. Let's continue the example from above: + // - fractial = fmodf(-2.2) = -0.2 + // - Add 1 to the fraction: fractial2 = fractial + 1 = -0.2 + 1 = 0.8 + // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3 + ++fractial; + } + if (yoga::inexactEquals(fractial, 0)) { + // First we check if the value is already rounded + scaledValue = scaledValue - fractial; + } else if (yoga::inexactEquals(fractial, 1.0)) { + scaledValue = scaledValue - fractial + 1.0; + } else if (forceCeil) { + // Next we check if we need to use forced rounding + scaledValue = scaledValue - fractial + 1.0; + } else if (forceFloor) { + scaledValue = scaledValue - fractial; + } else { + // Finally we just round the value + scaledValue = scaledValue - fractial + + (!std::isnan(fractial) && + (fractial > 0.5 || yoga::inexactEquals(fractial, 0.5)) + ? 1.0 + : 0.0); + } + return (std::isnan(scaledValue) || std::isnan(pointScaleFactor)) + ? YGUndefined + : (double)(scaledValue / pointScaleFactor); +} + +void roundLayoutResultsToPixelGrid( + yoga::Node* const node, + const double absoluteLeft, + const double absoluteTop) { + const auto pointScaleFactor = + static_cast(node->getConfig()->getPointScaleFactor()); + + const double nodeLeft = node->getLayout().position(PhysicalEdge::Left); + const double nodeTop = node->getLayout().position(PhysicalEdge::Top); + + const double nodeWidth = node->getLayout().dimension(Dimension::Width); + const double nodeHeight = node->getLayout().dimension(Dimension::Height); + + const double absoluteNodeLeft = absoluteLeft + nodeLeft; + const double absoluteNodeTop = absoluteTop + nodeTop; + + const double absoluteNodeRight = absoluteNodeLeft + nodeWidth; + const double absoluteNodeBottom = absoluteNodeTop + nodeHeight; + + if (pointScaleFactor != 0.0) { + // 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() == NodeType::Text; + + node->setLayoutPosition( + roundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding), + PhysicalEdge::Left); + + node->setLayoutPosition( + roundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding), + PhysicalEdge::Top); + + // 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 double scaledNodeWith = nodeWidth * pointScaleFactor; + const bool hasFractionalWidth = + !yoga::inexactEquals(round(scaledNodeWith), scaledNodeWith); + + const double scaledNodeHeight = nodeHeight * pointScaleFactor; + const bool hasFractionalHeight = + !yoga::inexactEquals(round(scaledNodeHeight), scaledNodeHeight); + + node->setLayoutDimension( + roundValueToPixelGrid( + absoluteNodeRight, + pointScaleFactor, + (textRounding && hasFractionalWidth), + (textRounding && !hasFractionalWidth)) - + roundValueToPixelGrid( + absoluteNodeLeft, pointScaleFactor, false, textRounding), + Dimension::Width); + + node->setLayoutDimension( + roundValueToPixelGrid( + absoluteNodeBottom, + pointScaleFactor, + (textRounding && hasFractionalHeight), + (textRounding && !hasFractionalHeight)) - + roundValueToPixelGrid( + absoluteNodeTop, pointScaleFactor, false, textRounding), + Dimension::Height); + } + + for (yoga::Node* child : node->getChildren()) { + roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop); + } +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/PixelGrid.h b/yoga/algorithm/PixelGrid.h new file mode 100644 index 0000000000..4a1bb65f2c --- /dev/null +++ b/yoga/algorithm/PixelGrid.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +// Round a point value to the nearest physical pixel based on DPI +// (pointScaleFactor) +double roundValueToPixelGrid( + double value, + double pointScaleFactor, + bool forceCeil, + bool forceFloor); + +// Round the layout results of a node and its subtree to the pixel grid. +void roundLayoutResultsToPixelGrid( + yoga::Node* node, + double absoluteLeft, + double absoluteTop); + +} // namespace facebook::yoga diff --git a/yoga/algorithm/SizingMode.h b/yoga/algorithm/SizingMode.h new file mode 100644 index 0000000000..bd725df13a --- /dev/null +++ b/yoga/algorithm/SizingMode.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +/** + * Corresponds to a CSS auto box sizes. Missing "min-content", as Yoga does not + * current support automatic minimum sizes. + * https://www.w3.org/TR/css-sizing-3/#auto-box-sizes + * https://www.w3.org/TR/css-flexbox-1/#min-size-auto + */ +enum class SizingMode { + /** + * The size a box would take if its outer size filled the available space in + * the given axis; in other words, the stretch fit into the available space, + * if that is definite. Undefined if the available space is indefinite. + */ + StretchFit, + + /** + * A box’s “ideal” size in a given axis when given infinite available space. + * Usually this is the smallest size the box could take in that axis while + * still fitting around its contents, i.e. minimizing unfilled space while + * avoiding overflow. + */ + MaxContent, + + /** + * If the available space in a given axis is definite, equal to + * clamp(min-content size, stretch-fit size, max-content size) (i.e. + * max(min-content size, min(max-content size, stretch-fit size))). When + * sizing under a min-content constraint, equal to the min-content size. + * Otherwise, equal to the max-content size in that axis. + */ + FitContent, +}; + +inline MeasureMode measureMode(SizingMode mode) { + switch (mode) { + case SizingMode::StretchFit: + return MeasureMode::Exactly; + case SizingMode::MaxContent: + return MeasureMode::Undefined; + case SizingMode::FitContent: + return MeasureMode::AtMost; + } + + fatalWithMessage("Invalid SizingMode"); +} + +inline SizingMode sizingMode(MeasureMode mode) { + switch (mode) { + case MeasureMode::Exactly: + return SizingMode::StretchFit; + case MeasureMode::Undefined: + return SizingMode::MaxContent; + case MeasureMode::AtMost: + return SizingMode::FitContent; + } + + fatalWithMessage("Invalid MeasureMode"); +} + +} // namespace facebook::yoga diff --git a/yoga/algorithm/TrailingPosition.h b/yoga/algorithm/TrailingPosition.h new file mode 100644 index 0000000000..02d4e3b7da --- /dev/null +++ b/yoga/algorithm/TrailingPosition.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +// Given an offset to an edge, returns the offset to the opposite edge on the +// same axis. This assumes that the width/height of both nodes is determined at +// this point. +inline double getPositionOfOppositeEdge( + double position, + FlexDirection axis, + const yoga::Node* const containingNode, + const yoga::Node* const node) { + return containingNode->getLayout().measuredDimension(dimension(axis)) - + node->getLayout().measuredDimension(dimension(axis)) - position; +} + +inline void setChildTrailingPosition( + const yoga::Node* const node, + yoga::Node* const child, + const FlexDirection axis) { + child->setLayoutPosition( + getPositionOfOppositeEdge( + child->getLayout().position(flexStartEdge(axis)), axis, node, child), + flexEndEdge(axis)); +} + +inline bool needsTrailingPosition(const FlexDirection axis) { + return axis == FlexDirection::RowReverse || + axis == FlexDirection::ColumnReverse; +} + +} // namespace facebook::yoga diff --git a/yoga/config/Config.cpp b/yoga/config/Config.cpp new file mode 100644 index 0000000000..63cbac432b --- /dev/null +++ b/yoga/config/Config.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 facebook::yoga { + +bool configUpdateInvalidatesLayout( + const Config& oldConfig, + const Config& newConfig) { + return oldConfig.getErrata() != newConfig.getErrata() || + oldConfig.getEnabledExperiments() != newConfig.getEnabledExperiments() || + oldConfig.getPointScaleFactor() != newConfig.getPointScaleFactor() || + oldConfig.useWebDefaults() != newConfig.useWebDefaults(); +} + +void Config::setUseWebDefaults(bool useWebDefaults) { + useWebDefaults_ = useWebDefaults; +} + +bool Config::useWebDefaults() const { + return useWebDefaults_; +} + +void Config::setExperimentalFeatureEnabled( + ExperimentalFeature feature, + bool enabled) { + if (isExperimentalFeatureEnabled(feature) != enabled) { + experimentalFeatures_.set(static_cast(feature), enabled); + version_++; + } +} + +bool Config::isExperimentalFeatureEnabled(ExperimentalFeature feature) const { + return experimentalFeatures_.test(static_cast(feature)); +} + +ExperimentalFeatureSet Config::getEnabledExperiments() const { + return experimentalFeatures_; +} + +void Config::setErrata(Errata errata) { + if (errata_ != errata) { + errata_ = errata; + version_++; + } +} + +void Config::addErrata(Errata errata) { + if (!hasErrata(errata)) { + errata_ |= errata; + version_++; + } +} + +void Config::removeErrata(Errata errata) { + if (hasErrata(errata)) { + errata_ &= (~errata); + version_++; + } +} + +Errata Config::getErrata() const { + return errata_; +} + +bool Config::hasErrata(Errata errata) const { + return (errata_ & errata) != Errata::None; +} + +void Config::setPointScaleFactor(double pointScaleFactor) { + if (pointScaleFactor_ != pointScaleFactor) { + pointScaleFactor_ = pointScaleFactor; + version_++; + } +} + +double Config::getPointScaleFactor() const { + return pointScaleFactor_; +} + +void Config::setContext(void* context) { + context_ = context; +} + +void* Config::getContext() const { + return context_; +} + +uint32_t Config::getVersion() const noexcept { + return version_; +} + +void Config::setLogger(YGLogger logger) { + logger_ = logger; +} + +void Config::log( + const yoga::Node* node, + LogLevel logLevel, + const char* format, + va_list args) const { + logger_(this, node, unscopedEnum(logLevel), format, args); +} + +void Config::setCloneNodeCallback(YGCloneNodeFunc cloneNode) { + cloneNodeCallback_ = cloneNode; +} + +YGNodeRef Config::cloneNode( + YGNodeConstRef node, + YGNodeConstRef owner, + size_t childIndex) const { + YGNodeRef clone = nullptr; + if (cloneNodeCallback_ != nullptr) { + clone = cloneNodeCallback_(node, owner, childIndex); + } + if (clone == nullptr) { + clone = YGNodeClone(node); + } + return clone; +} + +/*static*/ const Config& Config::getDefault() { + static Config config{getDefaultLogger()}; + return config; +} + +} // namespace facebook::yoga diff --git a/yoga/config/Config.h b/yoga/config/Config.h new file mode 100644 index 0000000000..1626866f00 --- /dev/null +++ b/yoga/config/Config.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +// Tag struct used to form the opaque YGConfigRef for the public C API +struct YGConfig {}; + +namespace facebook::yoga { + +class Config; +class Node; + +using ExperimentalFeatureSet = std::bitset()>; + +// Whether moving a node from an old to new config should dirty previously +// calculated layout results. +bool configUpdateInvalidatesLayout( + const Config& oldConfig, + const Config& newConfig); + +class YG_EXPORT Config : public ::YGConfig { + public: + explicit Config(YGLogger logger) : logger_{logger} {} + + void setUseWebDefaults(bool useWebDefaults); + bool useWebDefaults() const; + + void setExperimentalFeatureEnabled(ExperimentalFeature feature, bool enabled); + bool isExperimentalFeatureEnabled(ExperimentalFeature feature) const; + ExperimentalFeatureSet getEnabledExperiments() const; + + void setErrata(Errata errata); + void addErrata(Errata errata); + void removeErrata(Errata errata); + Errata getErrata() const; + bool hasErrata(Errata errata) const; + + void setPointScaleFactor(double pointScaleFactor); + double getPointScaleFactor() const; + + void setContext(void* context); + void* getContext() const; + + uint32_t getVersion() const noexcept; + + void setLogger(YGLogger logger); + void log( + const yoga::Node* node, + LogLevel logLevel, + const char* format, + va_list args) const; + + void setCloneNodeCallback(YGCloneNodeFunc cloneNode); + YGNodeRef + cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; + + static const Config& getDefault(); + + private: + YGCloneNodeFunc cloneNodeCallback_{nullptr}; + YGLogger logger_{}; + + bool useWebDefaults_ : 1 = false; + + uint32_t version_ = 0; + ExperimentalFeatureSet experimentalFeatures_{}; + Errata errata_ = Errata::None; + double pointScaleFactor_ = 1.0; + void* context_ = nullptr; +}; + +inline Config* resolveRef(const YGConfigRef ref) { + return static_cast(ref); +} + +inline const Config* resolveRef(const YGConfigConstRef ref) { + return static_cast(ref); +} + +} // namespace facebook::yoga diff --git a/yoga/debug/AssertFatal.cpp b/yoga/debug/AssertFatal.cpp new file mode 100644 index 0000000000..5016053b1f --- /dev/null +++ b/yoga/debug/AssertFatal.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include +#include + +namespace facebook::yoga { + +[[noreturn]] void fatalWithMessage(const char* message) { +#if defined(__cpp_exceptions) + throw std::logic_error(message); +#else + std::terminate(); +#endif +} + +void assertFatal(const bool condition, const char* message) { + if (!condition) { + yoga::log(LogLevel::Fatal, "%s\n", message); + fatalWithMessage(message); + } +} + +void assertFatalWithNode( + const yoga::Node* const node, + const bool condition, + const char* message) { + if (!condition) { + yoga::log(node, LogLevel::Fatal, "%s\n", message); + fatalWithMessage(message); + } +} + +void assertFatalWithConfig( + const yoga::Config* const config, + const bool condition, + const char* message) { + if (!condition) { + yoga::log(config, LogLevel::Fatal, "%s\n", message); + fatalWithMessage(message); + } +} + +} // namespace facebook::yoga diff --git a/yoga/debug/AssertFatal.h b/yoga/debug/AssertFatal.h new file mode 100644 index 0000000000..bbd8ad19ea --- /dev/null +++ b/yoga/debug/AssertFatal.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +class Node; +class Config; + +[[noreturn]] void fatalWithMessage(const char* message); + +void assertFatal(bool condition, const char* message); +void assertFatalWithNode( + const yoga::Node* node, + bool condition, + const char* message); +void assertFatalWithConfig( + const yoga::Config* config, + bool condition, + const char* message); + +} // namespace facebook::yoga diff --git a/yoga/debug/Log.cpp b/yoga/debug/Log.cpp new file mode 100644 index 0000000000..9b525d8a8e --- /dev/null +++ b/yoga/debug/Log.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#ifdef ANDROID +#include +#endif + +namespace facebook::yoga { + +namespace { + +void vlog( + const yoga::Config* config, + const yoga::Node* node, + LogLevel level, + const char* format, + va_list args) { + if (config == nullptr) { + getDefaultLogger()(nullptr, node, unscopedEnum(level), format, args); + } else { + config->log(node, level, format, args); + } +} +} // namespace + +void log(LogLevel level, const char* format, ...) noexcept { + va_list args; + va_start(args, format); + vlog(nullptr, nullptr, level, format, args); + va_end(args); +} + +void log( + const yoga::Node* node, + LogLevel level, + const char* format, + ...) noexcept { + va_list args; + va_start(args, format); + vlog( + node == nullptr ? nullptr : node->getConfig(), node, level, format, args); + va_end(args); +} + +void log( + const yoga::Config* config, + LogLevel level, + const char* format, + ...) noexcept { + va_list args; + va_start(args, format); + vlog(config, nullptr, level, format, args); + va_end(args); +} + +YGLogger getDefaultLogger() { + return [](const YGConfigConstRef /*config*/, + const YGNodeConstRef /*node*/, + YGLogLevel level, + const char* format, + va_list args) -> int { +#ifdef ANDROID + 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; + } + return __android_log_vprint(androidLevel, "yoga", format, args); +#else + switch (level) { + case YGLogLevelError: + case YGLogLevelFatal: + return vfprintf(stderr, format, args); + case YGLogLevelWarn: + case YGLogLevelInfo: + case YGLogLevelDebug: + case YGLogLevelVerbose: + default: + return vprintf(format, args); + } +#endif + }; +} + +} // namespace facebook::yoga diff --git a/yoga/debug/Log.h b/yoga/debug/Log.h new file mode 100644 index 0000000000..0a932d80eb --- /dev/null +++ b/yoga/debug/Log.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +void log(LogLevel level, const char* format, ...) noexcept; + +void log( + const yoga::Node* node, + LogLevel level, + const char* format, + ...) noexcept; + +void log( + const yoga::Config* config, + LogLevel level, + const char* format, + ...) noexcept; + +YGLogger getDefaultLogger(); + +} // namespace facebook::yoga diff --git a/yoga/enums/Align.h b/yoga/enums/Align.h new file mode 100644 index 0000000000..3896fe2b8b --- /dev/null +++ b/yoga/enums/Align.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Align : uint8_t { + Auto = YGAlignAuto, + FlexStart = YGAlignFlexStart, + Center = YGAlignCenter, + FlexEnd = YGAlignFlexEnd, + Stretch = YGAlignStretch, + Baseline = YGAlignBaseline, + SpaceBetween = YGAlignSpaceBetween, + SpaceAround = YGAlignSpaceAround, + SpaceEvenly = YGAlignSpaceEvenly, +}; + +template <> +constexpr int32_t ordinalCount() { + return 9; +} + +constexpr Align scopedEnum(YGAlign unscoped) { + return static_cast(unscoped); +} + +constexpr YGAlign unscopedEnum(Align scoped) { + return static_cast(scoped); +} + +inline const char* toString(Align e) { + return YGAlignToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/BoxSizing.h b/yoga/enums/BoxSizing.h new file mode 100644 index 0000000000..eb18b99a0d --- /dev/null +++ b/yoga/enums/BoxSizing.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class BoxSizing : uint8_t { + BorderBox = YGBoxSizingBorderBox, + ContentBox = YGBoxSizingContentBox, +}; + +template <> +constexpr int32_t ordinalCount() { + return 2; +} + +constexpr BoxSizing scopedEnum(YGBoxSizing unscoped) { + return static_cast(unscoped); +} + +constexpr YGBoxSizing unscopedEnum(BoxSizing scoped) { + return static_cast(scoped); +} + +inline const char* toString(BoxSizing e) { + return YGBoxSizingToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Dimension.h b/yoga/enums/Dimension.h new file mode 100644 index 0000000000..965901525b --- /dev/null +++ b/yoga/enums/Dimension.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Dimension : uint8_t { + Width = YGDimensionWidth, + Height = YGDimensionHeight, +}; + +template <> +constexpr int32_t ordinalCount() { + return 2; +} + +constexpr Dimension scopedEnum(YGDimension unscoped) { + return static_cast(unscoped); +} + +constexpr YGDimension unscopedEnum(Dimension scoped) { + return static_cast(scoped); +} + +inline const char* toString(Dimension e) { + return YGDimensionToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Direction.h b/yoga/enums/Direction.h new file mode 100644 index 0000000000..5bbabaecde --- /dev/null +++ b/yoga/enums/Direction.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Direction : uint8_t { + Inherit = YGDirectionInherit, + LTR = YGDirectionLTR, + RTL = YGDirectionRTL, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr Direction scopedEnum(YGDirection unscoped) { + return static_cast(unscoped); +} + +constexpr YGDirection unscopedEnum(Direction scoped) { + return static_cast(scoped); +} + +inline const char* toString(Direction e) { + return YGDirectionToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Display.h b/yoga/enums/Display.h new file mode 100644 index 0000000000..9bf23c0ac7 --- /dev/null +++ b/yoga/enums/Display.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Display : uint8_t { + Flex = YGDisplayFlex, + None = YGDisplayNone, + Contents = YGDisplayContents, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr Display scopedEnum(YGDisplay unscoped) { + return static_cast(unscoped); +} + +constexpr YGDisplay unscopedEnum(Display scoped) { + return static_cast(scoped); +} + +inline const char* toString(Display e) { + return YGDisplayToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Edge.h b/yoga/enums/Edge.h new file mode 100644 index 0000000000..3ab6a33faf --- /dev/null +++ b/yoga/enums/Edge.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Edge : uint8_t { + Left = YGEdgeLeft, + Top = YGEdgeTop, + Right = YGEdgeRight, + Bottom = YGEdgeBottom, + Start = YGEdgeStart, + End = YGEdgeEnd, + Horizontal = YGEdgeHorizontal, + Vertical = YGEdgeVertical, + All = YGEdgeAll, +}; + +template <> +constexpr int32_t ordinalCount() { + return 9; +} + +constexpr Edge scopedEnum(YGEdge unscoped) { + return static_cast(unscoped); +} + +constexpr YGEdge unscopedEnum(Edge scoped) { + return static_cast(scoped); +} + +inline const char* toString(Edge e) { + return YGEdgeToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Errata.h b/yoga/enums/Errata.h new file mode 100644 index 0000000000..2f47a94175 --- /dev/null +++ b/yoga/enums/Errata.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Errata : uint32_t { + None = YGErrataNone, + StretchFlexBasis = YGErrataStretchFlexBasis, + AbsolutePositionWithoutInsetsExcludesPadding = YGErrataAbsolutePositionWithoutInsetsExcludesPadding, + AbsolutePercentAgainstInnerSize = YGErrataAbsolutePercentAgainstInnerSize, + All = YGErrataAll, + Classic = YGErrataClassic, +}; + +YG_DEFINE_ENUM_FLAG_OPERATORS(Errata) + +constexpr Errata scopedEnum(YGErrata unscoped) { + return static_cast(unscoped); +} + +constexpr YGErrata unscopedEnum(Errata scoped) { + return static_cast(scoped); +} + +inline const char* toString(Errata e) { + return YGErrataToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/ExperimentalFeature.h b/yoga/enums/ExperimentalFeature.h new file mode 100644 index 0000000000..bbbf9cda43 --- /dev/null +++ b/yoga/enums/ExperimentalFeature.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class ExperimentalFeature : uint8_t { + WebFlexBasis = YGExperimentalFeatureWebFlexBasis, +}; + +template <> +constexpr int32_t ordinalCount() { + return 1; +} + +constexpr ExperimentalFeature scopedEnum(YGExperimentalFeature unscoped) { + return static_cast(unscoped); +} + +constexpr YGExperimentalFeature unscopedEnum(ExperimentalFeature scoped) { + return static_cast(scoped); +} + +inline const char* toString(ExperimentalFeature e) { + return YGExperimentalFeatureToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/FlexDirection.h b/yoga/enums/FlexDirection.h new file mode 100644 index 0000000000..d2d3f6105d --- /dev/null +++ b/yoga/enums/FlexDirection.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class FlexDirection : uint8_t { + Column = YGFlexDirectionColumn, + ColumnReverse = YGFlexDirectionColumnReverse, + Row = YGFlexDirectionRow, + RowReverse = YGFlexDirectionRowReverse, +}; + +template <> +constexpr int32_t ordinalCount() { + return 4; +} + +constexpr FlexDirection scopedEnum(YGFlexDirection unscoped) { + return static_cast(unscoped); +} + +constexpr YGFlexDirection unscopedEnum(FlexDirection scoped) { + return static_cast(scoped); +} + +inline const char* toString(FlexDirection e) { + return YGFlexDirectionToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Gutter.h b/yoga/enums/Gutter.h new file mode 100644 index 0000000000..f16bbbcdf4 --- /dev/null +++ b/yoga/enums/Gutter.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Gutter : uint8_t { + Column = YGGutterColumn, + Row = YGGutterRow, + All = YGGutterAll, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr Gutter scopedEnum(YGGutter unscoped) { + return static_cast(unscoped); +} + +constexpr YGGutter unscopedEnum(Gutter scoped) { + return static_cast(scoped); +} + +inline const char* toString(Gutter e) { + return YGGutterToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Justify.h b/yoga/enums/Justify.h new file mode 100644 index 0000000000..255baa6e27 --- /dev/null +++ b/yoga/enums/Justify.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Justify : uint8_t { + FlexStart = YGJustifyFlexStart, + Center = YGJustifyCenter, + FlexEnd = YGJustifyFlexEnd, + SpaceBetween = YGJustifySpaceBetween, + SpaceAround = YGJustifySpaceAround, + SpaceEvenly = YGJustifySpaceEvenly, +}; + +template <> +constexpr int32_t ordinalCount() { + return 6; +} + +constexpr Justify scopedEnum(YGJustify unscoped) { + return static_cast(unscoped); +} + +constexpr YGJustify unscopedEnum(Justify scoped) { + return static_cast(scoped); +} + +inline const char* toString(Justify e) { + return YGJustifyToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/LogLevel.h b/yoga/enums/LogLevel.h new file mode 100644 index 0000000000..d4b2c36019 --- /dev/null +++ b/yoga/enums/LogLevel.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class LogLevel : uint8_t { + Error = YGLogLevelError, + Warn = YGLogLevelWarn, + Info = YGLogLevelInfo, + Debug = YGLogLevelDebug, + Verbose = YGLogLevelVerbose, + Fatal = YGLogLevelFatal, +}; + +template <> +constexpr int32_t ordinalCount() { + return 6; +} + +constexpr LogLevel scopedEnum(YGLogLevel unscoped) { + return static_cast(unscoped); +} + +constexpr YGLogLevel unscopedEnum(LogLevel scoped) { + return static_cast(scoped); +} + +inline const char* toString(LogLevel e) { + return YGLogLevelToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/MeasureMode.h b/yoga/enums/MeasureMode.h new file mode 100644 index 0000000000..39e2102fff --- /dev/null +++ b/yoga/enums/MeasureMode.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class MeasureMode : uint8_t { + Undefined = YGMeasureModeUndefined, + Exactly = YGMeasureModeExactly, + AtMost = YGMeasureModeAtMost, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr MeasureMode scopedEnum(YGMeasureMode unscoped) { + return static_cast(unscoped); +} + +constexpr YGMeasureMode unscopedEnum(MeasureMode scoped) { + return static_cast(scoped); +} + +inline const char* toString(MeasureMode e) { + return YGMeasureModeToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/NodeType.h b/yoga/enums/NodeType.h new file mode 100644 index 0000000000..dc881be831 --- /dev/null +++ b/yoga/enums/NodeType.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class NodeType : uint8_t { + Default = YGNodeTypeDefault, + Text = YGNodeTypeText, +}; + +template <> +constexpr int32_t ordinalCount() { + return 2; +} + +constexpr NodeType scopedEnum(YGNodeType unscoped) { + return static_cast(unscoped); +} + +constexpr YGNodeType unscopedEnum(NodeType scoped) { + return static_cast(scoped); +} + +inline const char* toString(NodeType e) { + return YGNodeTypeToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Overflow.h b/yoga/enums/Overflow.h new file mode 100644 index 0000000000..20901b02c0 --- /dev/null +++ b/yoga/enums/Overflow.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Overflow : uint8_t { + Visible = YGOverflowVisible, + Hidden = YGOverflowHidden, + Scroll = YGOverflowScroll, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr Overflow scopedEnum(YGOverflow unscoped) { + return static_cast(unscoped); +} + +constexpr YGOverflow unscopedEnum(Overflow scoped) { + return static_cast(scoped); +} + +inline const char* toString(Overflow e) { + return YGOverflowToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/PhysicalEdge.h b/yoga/enums/PhysicalEdge.h new file mode 100644 index 0000000000..21e37d2c2f --- /dev/null +++ b/yoga/enums/PhysicalEdge.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +enum class PhysicalEdge : uint32_t { + Left = yoga::to_underlying(Edge::Left), + Top = yoga::to_underlying(Edge::Top), + Right = yoga::to_underlying(Edge::Right), + Bottom = yoga::to_underlying(Edge::Bottom), +}; + +} // namespace facebook::yoga diff --git a/yoga/enums/PositionType.h b/yoga/enums/PositionType.h new file mode 100644 index 0000000000..8a552aacba --- /dev/null +++ b/yoga/enums/PositionType.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class PositionType : uint8_t { + Static = YGPositionTypeStatic, + Relative = YGPositionTypeRelative, + Absolute = YGPositionTypeAbsolute, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr PositionType scopedEnum(YGPositionType unscoped) { + return static_cast(unscoped); +} + +constexpr YGPositionType unscopedEnum(PositionType scoped) { + return static_cast(scoped); +} + +inline const char* toString(PositionType e) { + return YGPositionTypeToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Unit.h b/yoga/enums/Unit.h new file mode 100644 index 0000000000..685b1caece --- /dev/null +++ b/yoga/enums/Unit.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Unit : uint8_t { + Undefined = YGUnitUndefined, + Point = YGUnitPoint, + Percent = YGUnitPercent, + Auto = YGUnitAuto, + MaxContent = YGUnitMaxContent, + FitContent = YGUnitFitContent, + Stretch = YGUnitStretch, +}; + +template <> +constexpr int32_t ordinalCount() { + return 7; +} + +constexpr Unit scopedEnum(YGUnit unscoped) { + return static_cast(unscoped); +} + +constexpr YGUnit unscopedEnum(Unit scoped) { + return static_cast(scoped); +} + +inline const char* toString(Unit e) { + return YGUnitToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/Wrap.h b/yoga/enums/Wrap.h new file mode 100644 index 0000000000..96552b7b2a --- /dev/null +++ b/yoga/enums/Wrap.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// @generated by enums.py +// clang-format off +#pragma once + +#include +#include +#include + +namespace facebook::yoga { + +enum class Wrap : uint8_t { + NoWrap = YGWrapNoWrap, + Wrap = YGWrapWrap, + WrapReverse = YGWrapWrapReverse, +}; + +template <> +constexpr int32_t ordinalCount() { + return 3; +} + +constexpr Wrap scopedEnum(YGWrap unscoped) { + return static_cast(unscoped); +} + +constexpr YGWrap unscopedEnum(Wrap scoped) { + return static_cast(scoped); +} + +inline const char* toString(Wrap e) { + return YGWrapToString(unscopedEnum(e)); +} + +} // namespace facebook::yoga diff --git a/yoga/enums/YogaEnums.h b/yoga/enums/YogaEnums.h new file mode 100644 index 0000000000..de446621d5 --- /dev/null +++ b/yoga/enums/YogaEnums.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +/** + * Concept for any enum/enum class + */ +template +concept Enumeration = std::is_enum_v; + +/** + * Count of ordinals in a Yoga enum which is sequential + */ +template +constexpr int32_t ordinalCount(); + +/** + * Concept for a yoga enum which is sequential + */ +template +concept HasOrdinality = (ordinalCount() > 0); + +/** + * Count of bits needed to represent every ordinal + */ +template +constexpr int32_t bitCount() { + return std::bit_width( + static_cast>(ordinalCount() - 1)); +} + +/** + * Polyfill of C++ 23 to_underlying() + * https://en.cppreference.com/w/cpp/utility/to_underlying + */ +constexpr auto to_underlying(Enumeration auto e) noexcept { + return static_cast>(e); +} + +/** + * Convenience function to iterate through every value in a Yoga enum as part of + * a range-based for loop. + */ +template +auto ordinals() { + struct Iterator { + EnumT e{}; + + EnumT operator*() const { + return e; + } + + Iterator& operator++() { + e = static_cast(to_underlying(e) + 1); + return *this; + } + + bool operator==(const Iterator& other) const = default; + bool operator!=(const Iterator& other) const = default; + }; + + struct Range { + Iterator begin() const { + return Iterator{}; + } + Iterator end() const { + return Iterator{static_cast(ordinalCount())}; + } + }; + + return Range{}; +} + +} // namespace facebook::yoga diff --git a/yoga/event/event.cpp b/yoga/event/event.cpp index 3af3e83a06..e286ded055 100644 --- a/yoga/event/event.cpp +++ b/yoga/event/event.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -9,8 +9,7 @@ #include #include -namespace facebook { -namespace yoga { +namespace facebook::yoga { const char* LayoutPassReasonToString(const LayoutPassReason value) { switch (value) { @@ -41,14 +40,14 @@ struct Node { std::function subscriber = nullptr; Node* next = nullptr; - Node(std::function&& subscriber) + explicit Node(std::function&& subscriber) : subscriber{std::move(subscriber)} {} }; std::atomic subscribers{nullptr}; Node* push(Node* newHead) { - Node* oldHead; + Node* oldHead = nullptr; do { oldHead = subscribers.load(std::memory_order_relaxed); if (newHead != nullptr) { @@ -74,7 +73,10 @@ void Event::subscribe(std::function&& subscriber) { push(new Node{std::move(subscriber)}); } -void Event::publish(const YGNode& node, Type eventType, const Data& eventData) { +void Event::publish( + YGNodeConstRef node, + Type eventType, + const Data& eventData) { for (auto subscriber = subscribers.load(std::memory_order_relaxed); subscriber != nullptr; subscriber = subscriber->next) { @@ -82,5 +84,4 @@ void Event::publish(const YGNode& node, Type eventType, const Data& eventData) { } } -} // namespace yoga -} // namespace facebook +} // namespace facebook::yoga diff --git a/yoga/event/event.h b/yoga/event/event.h index d375846f99..ea5decabfd 100644 --- a/yoga/event/event.h +++ b/yoga/event/event.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Facebook, Inc. and its affiliates. + * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -7,17 +7,14 @@ #pragma once +#include + +#include +#include #include #include -#include -#include -#include -struct YGConfig; -struct YGNode; - -namespace facebook { -namespace yoga { +namespace facebook::yoga { enum struct LayoutType : int { kLayout = 0, @@ -41,7 +38,7 @@ enum struct LayoutPassReason : int { struct LayoutData { int layouts; int measures; - int maxMeasureCache; + uint32_t maxMeasureCache; int cachedLayouts; int cachedMeasures; int measureCallbacks; @@ -49,9 +46,9 @@ struct LayoutData { measureCallbackReasonsCount; }; -const char* LayoutPassReasonToString(const LayoutPassReason value); +const char* LayoutPassReasonToString(LayoutPassReason value); -struct YOGA_EXPORT Event { +struct YG_EXPORT Event { enum Type { NodeAllocation, NodeDeallocation, @@ -64,7 +61,7 @@ struct YOGA_EXPORT Event { NodeBaselineEnd, }; class Data; - using Subscriber = void(const YGNode&, Type, Data); + using Subscriber = void(YGNodeConstRef, Type, Data); using Subscribers = std::vector>; template @@ -73,14 +70,14 @@ struct YOGA_EXPORT Event { class Data { const void* data_; - public: + public: template - Data(const TypedData& data) : data_{&data} {} + explicit Data(const TypedData& data) : data_{&data} {} template const TypedData& get() const { return *static_cast*>(data_); - }; + } }; static void reset(); @@ -88,45 +85,34 @@ struct YOGA_EXPORT Event { static void subscribe(std::function&& subscriber); template - static void publish(const YGNode& node, const TypedData& eventData = {}) { -#ifdef YG_ENABLE_EVENTS + static void publish(YGNodeConstRef node, const TypedData& eventData = {}) { publish(node, E, Data{eventData}); -#endif - } - - template - static void publish(const YGNode* node, const TypedData& eventData = {}) { - publish(*node, eventData); } -private: - static void publish(const YGNode&, Type, const Data&); + private: + static void publish( + YGNodeConstRef /*node*/, + Type /*eventType*/, + const Data& /*eventData*/); }; template <> struct Event::TypedData { - YGConfig* config; + YGConfigConstRef config; }; template <> struct Event::TypedData { - YGConfig* config; -}; - -template <> -struct Event::TypedData { - void* layoutContext; + YGConfigConstRef config; }; template <> struct Event::TypedData { - void* layoutContext; LayoutData* layoutData; }; template <> struct Event::TypedData { - void* layoutContext; double width; YGMeasureMode widthMeasureMode; double height; @@ -139,8 +125,6 @@ struct Event::TypedData { template <> struct Event::TypedData { LayoutType layoutType; - void* layoutContext; }; -} // namespace yoga -} // namespace facebook +} // namespace facebook::yoga diff --git a/yoga/include/YGConfig.h b/yoga/include/YGConfig.h new file mode 120000 index 0000000000..41d118dbb0 --- /dev/null +++ b/yoga/include/YGConfig.h @@ -0,0 +1 @@ +../YGConfig.h \ No newline at end of file diff --git a/yoga/include/YGNode.h b/yoga/include/YGNode.h new file mode 120000 index 0000000000..39b51ee80b --- /dev/null +++ b/yoga/include/YGNode.h @@ -0,0 +1 @@ +../YGNode.h \ No newline at end of file diff --git a/yoga/include/YGNodeLayout.h b/yoga/include/YGNodeLayout.h new file mode 120000 index 0000000000..2c13f7caa1 --- /dev/null +++ b/yoga/include/YGNodeLayout.h @@ -0,0 +1 @@ +../YGNodeLayout.h \ No newline at end of file diff --git a/yoga/include/YGNodeStyle.h b/yoga/include/YGNodeStyle.h new file mode 120000 index 0000000000..2d19d6f65f --- /dev/null +++ b/yoga/include/YGNodeStyle.h @@ -0,0 +1 @@ +../YGNodeStyle.h \ No newline at end of file diff --git a/yoga/include/YGPixelGrid.h b/yoga/include/YGPixelGrid.h new file mode 120000 index 0000000000..ff8146d9f5 --- /dev/null +++ b/yoga/include/YGPixelGrid.h @@ -0,0 +1 @@ +../YGPixelGrid.h \ No newline at end of file diff --git a/yoga/include/Yoga-umbrella.h b/yoga/include/Yoga-umbrella.h index eb25659f63..03f22be5c4 100644 --- a/yoga/include/Yoga-umbrella.h +++ b/yoga/include/Yoga-umbrella.h @@ -2,7 +2,11 @@ #import #endif +#import "YGConfig.h" #import "YGEnums.h" #import "YGMacros.h" +#import "YGNode.h" +#import "YGNodeLayout.h" +#import "YGNodeStyle.h" +#import "YGPixelGrid.h" #import "YGValue.h" -#import "Yoga.h" diff --git a/yoga/include/Yoga.h b/yoga/include/Yoga.h deleted file mode 120000 index a148821c32..0000000000 --- a/yoga/include/Yoga.h +++ /dev/null @@ -1 +0,0 @@ -../Yoga.h \ No newline at end of file diff --git a/yoga/internal/experiments-inl.h b/yoga/internal/experiments-inl.h deleted file mode 100644 index 959d9c3327..0000000000 --- a/yoga/internal/experiments-inl.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "experiments.h" - -#include - -namespace facebook { -namespace yoga { -namespace internal { - -namespace detail { -extern std::bitset enabledExperiments; -} // namespace detail - -inline bool isEnabled(Experiment experiment) { - return detail::enabledExperiments.test(static_cast(experiment)); -} - -inline void disableAllExperiments() { - detail::enabledExperiments = 0; -} - -} // namespace internal -} // namespace yoga -} // namespace facebook diff --git a/yoga/internal/experiments.cpp b/yoga/internal/experiments.cpp deleted file mode 100644 index 16f196d5ed..0000000000 --- a/yoga/internal/experiments.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "experiments.h" -#include "experiments-inl.h" - -namespace facebook { -namespace yoga { -namespace internal { - -namespace detail { - -std::bitset enabledExperiments = 0; - -} // namespace detail - -void enable(Experiment experiment) { - detail::enabledExperiments.set(static_cast(experiment)); -} - -void disable(Experiment experiment) { - detail::enabledExperiments.reset(static_cast(experiment)); -} - -bool toggle(Experiment experiment) { - auto bit = static_cast(experiment); - auto previousState = detail::enabledExperiments.test(bit); - detail::enabledExperiments.flip(bit); - return previousState; -} - -} // namespace internal -} // namespace yoga -} // namespace facebook diff --git a/yoga/internal/experiments.h b/yoga/internal/experiments.h deleted file mode 100644 index 1bdb7014b0..0000000000 --- a/yoga/internal/experiments.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 - -namespace facebook { -namespace yoga { -namespace internal { - -enum struct Experiment : size_t { - kDoubleMeasureCallbacks, -}; - -void enable(Experiment); -void disable(Experiment); -bool toggle(Experiment); - -} // namespace internal -} // namespace yoga -} // namespace facebook diff --git a/yoga/log.cpp b/yoga/log.cpp deleted file mode 100644 index eb3da039c3..0000000000 --- a/yoga/log.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "log.h" - -#include "Yoga.h" -#include "YGConfig.h" -#include "YGNode.h" - -namespace facebook { -namespace yoga { -namespace detail { - -namespace { - -void vlog( - YGConfig* config, - YGNode* node, - YGLogLevel level, - void* context, - const char* format, - va_list args) { - YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault(); - logConfig->log(logConfig, node, level, context, format, args); -} -} // namespace - -YOGA_EXPORT void Log::log( - YGNode* node, - YGLogLevel level, - void* context, - const char* format, - ...) noexcept { - va_list args; - va_start(args, format); - vlog( - node == nullptr ? nullptr : node->getConfig(), - node, - level, - context, - format, - args); - va_end(args); -} - -void Log::log( - YGConfig* config, - YGLogLevel level, - void* context, - const char* format, - ...) noexcept { - va_list args; - va_start(args, format); - vlog(config, nullptr, level, context, format, args); - va_end(args); -} - -} // namespace detail -} // namespace yoga -} // namespace facebook diff --git a/yoga/log.h b/yoga/log.h deleted file mode 100644 index ae33744c58..0000000000 --- a/yoga/log.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * 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 "YGEnums.h" - -struct YGNode; -struct YGConfig; - -namespace facebook { -namespace yoga { - -namespace detail { - -struct Log { - static void log( - YGNode* node, - YGLogLevel level, - void*, - const char* message, - ...) noexcept; - - static void log( - YGConfig* config, - YGLogLevel level, - void*, - const char* format, - ...) noexcept; -}; - -} // namespace detail -} // namespace yoga -} // namespace facebook diff --git a/yoga/node/CachedMeasurement.h b/yoga/node/CachedMeasurement.h new file mode 100644 index 0000000000..507171863c --- /dev/null +++ b/yoga/node/CachedMeasurement.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +struct CachedMeasurement { + double availableWidth{-1}; + double availableHeight{-1}; + SizingMode widthSizingMode{SizingMode::MaxContent}; + SizingMode heightSizingMode{SizingMode::MaxContent}; + + double computedWidth{-1}; + double computedHeight{-1}; + + bool operator==(CachedMeasurement measurement) const { + bool isEqual = widthSizingMode == measurement.widthSizingMode && + heightSizingMode == measurement.heightSizingMode; + + if (!yoga::isUndefined(availableWidth) || + !yoga::isUndefined(measurement.availableWidth)) { + isEqual = isEqual && availableWidth == measurement.availableWidth; + } + if (!yoga::isUndefined(availableHeight) || + !yoga::isUndefined(measurement.availableHeight)) { + isEqual = isEqual && availableHeight == measurement.availableHeight; + } + if (!yoga::isUndefined(computedWidth) || + !yoga::isUndefined(measurement.computedWidth)) { + isEqual = isEqual && computedWidth == measurement.computedWidth; + } + if (!yoga::isUndefined(computedHeight) || + !yoga::isUndefined(measurement.computedHeight)) { + isEqual = isEqual && computedHeight == measurement.computedHeight; + } + + return isEqual; + } +}; + +} // namespace facebook::yoga diff --git a/yoga/node/LayoutResults.cpp b/yoga/node/LayoutResults.cpp new file mode 100644 index 0000000000..acc37a1b4a --- /dev/null +++ b/yoga/node/LayoutResults.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 facebook::yoga { + +bool LayoutResults::operator==(LayoutResults layout) const { + bool isEqual = yoga::inexactEquals(position_, layout.position_) && + yoga::inexactEquals(dimensions_, layout.dimensions_) && + yoga::inexactEquals(margin_, layout.margin_) && + yoga::inexactEquals(border_, layout.border_) && + yoga::inexactEquals(padding_, layout.padding_) && + direction() == layout.direction() && + hadOverflow() == layout.hadOverflow() && + lastOwnerDirection == layout.lastOwnerDirection && + configVersion == layout.configVersion && + nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex && + cachedLayout == layout.cachedLayout && + computedFlexBasis == layout.computedFlexBasis; + + for (uint32_t i = 0; i < LayoutResults::MaxCachedMeasurements && isEqual; + ++i) { + isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i]; + } + + if (!yoga::isUndefined(measuredDimensions_[0]) || + !yoga::isUndefined(layout.measuredDimensions_[0])) { + isEqual = + isEqual && (measuredDimensions_[0] == layout.measuredDimensions_[0]); + } + if (!yoga::isUndefined(measuredDimensions_[1]) || + !yoga::isUndefined(layout.measuredDimensions_[1])) { + isEqual = + isEqual && (measuredDimensions_[1] == layout.measuredDimensions_[1]); + } + + return isEqual; +} + +} // namespace facebook::yoga diff --git a/yoga/node/LayoutResults.h b/yoga/node/LayoutResults.h new file mode 100644 index 0000000000..a21cd1c95e --- /dev/null +++ b/yoga/node/LayoutResults.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include + +namespace facebook::yoga { + +struct LayoutResults { + // This value was chosen based on empirical data: + // 98% of analyzed layouts require less than 8 entries. + static constexpr int32_t MaxCachedMeasurements = 8; + + uint32_t computedFlexBasisGeneration = 0; + FloatOptional computedFlexBasis = {}; + + // Instead of recomputing the entire layout every single time, we cache some + // information to break early when nothing changed + uint32_t generationCount = 0; + uint32_t configVersion = 0; + Direction lastOwnerDirection = Direction::Inherit; + + uint32_t nextCachedMeasurementsIndex = 0; + std::array cachedMeasurements = {}; + + CachedMeasurement cachedLayout{}; + + Direction direction() const { + return direction_; + } + + void setDirection(Direction direction) { + direction_ = direction; + } + + bool hadOverflow() const { + return hadOverflow_; + } + + void setHadOverflow(bool hadOverflow) { + hadOverflow_ = hadOverflow; + } + + double dimension(Dimension axis) const { + return dimensions_[yoga::to_underlying(axis)]; + } + + void setDimension(Dimension axis, double dimension) { + dimensions_[yoga::to_underlying(axis)] = dimension; + } + + double measuredDimension(Dimension axis) const { + return measuredDimensions_[yoga::to_underlying(axis)]; + } + + void setMeasuredDimension(Dimension axis, double dimension) { + measuredDimensions_[yoga::to_underlying(axis)] = dimension; + } + + double position(PhysicalEdge physicalEdge) const { + return position_[yoga::to_underlying(physicalEdge)]; + } + + void setPosition(PhysicalEdge physicalEdge, double dimension) { + position_[yoga::to_underlying(physicalEdge)] = dimension; + } + + double margin(PhysicalEdge physicalEdge) const { + return margin_[yoga::to_underlying(physicalEdge)]; + } + + void setMargin(PhysicalEdge physicalEdge, double dimension) { + margin_[yoga::to_underlying(physicalEdge)] = dimension; + } + + double border(PhysicalEdge physicalEdge) const { + return border_[yoga::to_underlying(physicalEdge)]; + } + + void setBorder(PhysicalEdge physicalEdge, double dimension) { + border_[yoga::to_underlying(physicalEdge)] = dimension; + } + + double padding(PhysicalEdge physicalEdge) const { + return padding_[yoga::to_underlying(physicalEdge)]; + } + + void setPadding(PhysicalEdge physicalEdge, double dimension) { + padding_[yoga::to_underlying(physicalEdge)] = dimension; + } + + bool operator==(LayoutResults layout) const; + bool operator!=(LayoutResults layout) const { + return !(*this == layout); + } + + private: + Direction direction_ : bitCount() = Direction::Inherit; + bool hadOverflow_ : 1 = false; + + std::array dimensions_ = {{YGUndefined, YGUndefined}}; + std::array measuredDimensions_ = {{YGUndefined, YGUndefined}}; + std::array position_ = {}; + std::array margin_ = {}; + std::array border_ = {}; + std::array padding_ = {}; +}; + +} // namespace facebook::yoga diff --git a/yoga/node/LayoutableChildren.h b/yoga/node/LayoutableChildren.h new file mode 100644 index 0000000000..b158a6a637 --- /dev/null +++ b/yoga/node/LayoutableChildren.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +class Node; + +template +class LayoutableChildren { + public: + struct Iterator { + using iterator_category = std::input_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = T*; + using pointer = T*; + using reference = T*; + + Iterator() = default; + + Iterator(const T* node, size_t childIndex) + : node_(node), childIndex_(childIndex) {} + + T* operator*() const { + return node_->getChild(childIndex_); + } + + Iterator& operator++() { + next(); + return *this; + } + + Iterator operator++(int) { + Iterator tmp = *this; + ++(*this); + return tmp; + } + + friend bool operator==(const Iterator& a, const Iterator& b) { + return a.node_ == b.node_ && a.childIndex_ == b.childIndex_; + } + + friend bool operator!=(const Iterator& a, const Iterator& b) { + return a.node_ != b.node_ || a.childIndex_ != b.childIndex_; + } + + private: + void next() { + if (childIndex_ + 1 >= node_->getChildCount()) { + // if the current node has no more children, try to backtrack and + // visit its successor + if (backtrack_.empty()) [[likely]] { + // if there are no nodes to backtrack to, the last node has been + // visited + *this = Iterator{}; + } else { + // pop and restore the latest backtrack entry + const auto& back = backtrack_.front(); + node_ = back.first; + childIndex_ = back.second; + backtrack_.pop_front(); + + // go to the next node + next(); + } + } else { + // current node has more children to visit, go to next + ++childIndex_; + // skip all display: contents nodes, possibly going deeper into the + // tree + if (node_->getChild(childIndex_)->style().display() == + Display::Contents) [[unlikely]] { + skipContentsNodes(); + } + } + } + + void skipContentsNodes() { + // get the node that would be returned from the iterator + auto currentNode = node_->getChild(childIndex_); + while (currentNode->style().display() == Display::Contents && + currentNode->getChildCount() > 0) { + // if it has display: contents set, it shouldn't be returned but its + // children should in its place push the current node and child index + // so that the current state can be restored when backtracking + backtrack_.push_front({node_, childIndex_}); + // traverse the child + node_ = currentNode; + childIndex_ = 0; + + // repeat until a node without display: contents is found in the + // subtree or a leaf is reached + currentNode = currentNode->getChild(childIndex_); + } + + // if no node without display: contents was found, try to backtrack + if (currentNode->style().display() == Display::Contents) { + next(); + } + } + + const T* node_{nullptr}; + size_t childIndex_{0}; + std::forward_list> backtrack_; + + friend LayoutableChildren; + }; + + explicit LayoutableChildren(const T* node) : node_(node) { + static_assert(std::input_iterator::Iterator>); + static_assert( + std::is_base_of::value, + "Type parameter of LayoutableChildren must derive from yoga::Node"); + } + + Iterator begin() const { + if (node_->getChildCount() > 0) { + auto result = Iterator(node_, 0); + if (node_->getChild(0)->style().display() == Display::Contents) + [[unlikely]] { + result.skipContentsNodes(); + } + return result; + } else { + return Iterator{}; + } + } + + Iterator end() const { + return Iterator{}; + } + + private: + const T* node_; +}; + +} // namespace facebook::yoga diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp new file mode 100644 index 0000000000..374b8d3e0d --- /dev/null +++ b/yoga/node/Node.cpp @@ -0,0 +1,443 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +#include +#include +#include +#include +#include + +namespace facebook::yoga { + +Node::Node() : Node{&Config::getDefault()} {} + +Node::Node(const yoga::Config* config) : config_{config} { + yoga::assertFatal( + config != nullptr, "Attempting to construct Node with null config"); + + if (config->useWebDefaults()) { + useWebDefaults(); + } +} + +Node::Node(Node&& node) noexcept + : hasNewLayout_(node.hasNewLayout_), + isReferenceBaseline_(node.isReferenceBaseline_), + isDirty_(node.isDirty_), + alwaysFormsContainingBlock_(node.alwaysFormsContainingBlock_), + nodeType_(node.nodeType_), + context_(node.context_), + measureFunc_(node.measureFunc_), + baselineFunc_(node.baselineFunc_), + dirtiedFunc_(node.dirtiedFunc_), + style_(std::move(node.style_)), + layout_(node.layout_), + lineIndex_(node.lineIndex_), + contentsChildrenCount_(node.contentsChildrenCount_), + owner_(node.owner_), + children_(std::move(node.children_)), + config_(node.config_), + processedDimensions_(node.processedDimensions_) { + for (auto c : children_) { + c->setOwner(this); + } +} + +YGSize Node::measure( + double availableWidth, + MeasureMode widthMode, + double availableHeight, + MeasureMode heightMode) { + const auto size = measureFunc_( + this, + availableWidth, + unscopedEnum(widthMode), + availableHeight, + unscopedEnum(heightMode)); + + if (yoga::isUndefined(size.height) || size.height < 0 || + yoga::isUndefined(size.width) || size.width < 0) { + yoga::log( + this, + LogLevel::Warn, + "Measure function returned an invalid dimension to Yoga: [width=%f, height=%f]", + size.width, + size.height); + return { + .width = maxOrDefined(0.0, size.width), + .height = maxOrDefined(0.0, size.height)}; + } + + return size; +} + +double Node::baseline(double width, double height) const { + return baselineFunc_(this, width, height); +} + +double Node::dimensionWithMargin( + const FlexDirection axis, + const double widthSize) { + return getLayout().measuredDimension(dimension(axis)) + + style_.computeMarginForAxis(axis, widthSize); +} + +bool Node::isLayoutDimensionDefined(const FlexDirection axis) { + const double value = getLayout().measuredDimension(dimension(axis)); + return yoga::isDefined(value) && value >= 0.0; +} + +// Setters + +void Node::setMeasureFunc(YGMeasureFunc measureFunc) { + if (measureFunc == nullptr) { + // TODO: t18095186 Move nodeType to opt-in function and mark appropriate + // places in Litho + setNodeType(NodeType::Default); + } else { + yoga::assertFatalWithNode( + this, + children_.empty(), + "Cannot set measure function: Nodes with measure functions cannot have " + "children."); + // TODO: t18095186 Move nodeType to opt-in function and mark appropriate + // places in Litho + setNodeType(NodeType::Text); + } + + measureFunc_ = measureFunc; +} + +void Node::replaceChild(Node* child, size_t index) { + auto previousChild = children_[index]; + if (previousChild->style().display() == Display::Contents && + child->style().display() != Display::Contents) { + contentsChildrenCount_--; + } else if ( + previousChild->style().display() != Display::Contents && + child->style().display() == Display::Contents) { + contentsChildrenCount_++; + } + + children_[index] = child; +} + +void Node::replaceChild(Node* oldChild, Node* newChild) { + if (oldChild->style().display() == Display::Contents && + newChild->style().display() != Display::Contents) { + contentsChildrenCount_--; + } else if ( + oldChild->style().display() != Display::Contents && + newChild->style().display() == Display::Contents) { + contentsChildrenCount_++; + } + + std::replace(children_.begin(), children_.end(), oldChild, newChild); +} + +void Node::insertChild(Node* child, size_t index) { + if (child->style().display() == Display::Contents) { + contentsChildrenCount_++; + } + + children_.insert(children_.begin() + static_cast(index), child); +} + +void Node::setConfig(yoga::Config* config) { + yoga::assertFatal( + config != nullptr, "Attempting to set a null config on a Node"); + yoga::assertFatalWithConfig( + config, + config->useWebDefaults() == config_->useWebDefaults(), + "UseWebDefaults may not be changed after constructing a Node"); + + if (yoga::configUpdateInvalidatesLayout(*config_, *config)) { + markDirtyAndPropagate(); + layout_.configVersion = 0; + } else { + // If the config is functionally the same, then align the configVersion so + // that we can reuse the layout cache + layout_.configVersion = config->getVersion(); + } + + config_ = config; +} + +void Node::setDirty(bool isDirty) { + if (static_cast(isDirty) == isDirty_) { + return; + } + isDirty_ = isDirty; + if (isDirty && (dirtiedFunc_ != nullptr)) { + dirtiedFunc_(this); + } +} + +bool Node::removeChild(Node* child) { + auto p = std::find(children_.begin(), children_.end(), child); + if (p != children_.end()) { + if (child->style().display() == Display::Contents) { + contentsChildrenCount_--; + } + + children_.erase(p); + return true; + } + return false; +} + +void Node::removeChild(size_t index) { + if (children_[index]->style().display() == Display::Contents) { + contentsChildrenCount_--; + } + + children_.erase(children_.begin() + static_cast(index)); +} + +void Node::setLayoutDirection(Direction direction) { + layout_.setDirection(direction); +} + +void Node::setLayoutMargin(double margin, PhysicalEdge edge) { + layout_.setMargin(edge, margin); +} + +void Node::setLayoutBorder(double border, PhysicalEdge edge) { + layout_.setBorder(edge, border); +} + +void Node::setLayoutPadding(double padding, PhysicalEdge edge) { + layout_.setPadding(edge, padding); +} + +void Node::setLayoutLastOwnerDirection(Direction direction) { + layout_.lastOwnerDirection = direction; +} + +void Node::setLayoutComputedFlexBasis(const FloatOptional computedFlexBasis) { + layout_.computedFlexBasis = computedFlexBasis; +} + +void Node::setLayoutPosition(double position, PhysicalEdge edge) { + layout_.setPosition(edge, position); +} + +void Node::setLayoutComputedFlexBasisGeneration( + uint32_t computedFlexBasisGeneration) { + layout_.computedFlexBasisGeneration = computedFlexBasisGeneration; +} + +void Node::setLayoutMeasuredDimension( + double measuredDimension, + Dimension dimension) { + layout_.setMeasuredDimension(dimension, measuredDimension); +} + +void Node::setLayoutHadOverflow(bool hadOverflow) { + layout_.setHadOverflow(hadOverflow); +} + +void Node::setLayoutDimension(double lengthValue, Dimension dimension) { + layout_.setDimension(dimension, lengthValue); +} + +// If both left and right are defined, then use left. Otherwise return +left or +// -right depending on which is defined. Ignore statically positioned nodes as +// insets do not apply to them. +double Node::relativePosition( + FlexDirection axis, + Direction direction, + double axisSize) const { + if (style_.positionType() == PositionType::Static) { + return 0; + } + if (style_.isInlineStartPositionDefined(axis, direction) && + !style_.isInlineStartPositionAuto(axis, direction)) { + return style_.computeInlineStartPosition(axis, direction, axisSize); + } + + return -1 * style_.computeInlineEndPosition(axis, direction, axisSize); +} + +void Node::setPosition( + const Direction direction, + const double ownerWidth, + const double ownerHeight) { + /* Root nodes should be always layouted as LTR, so we don't return negative + * values. */ + const Direction directionRespectingRoot = + owner_ != nullptr ? direction : Direction::LTR; + const FlexDirection mainAxis = + yoga::resolveDirection(style_.flexDirection(), directionRespectingRoot); + const FlexDirection crossAxis = + yoga::resolveCrossDirection(mainAxis, directionRespectingRoot); + + // In the case of position static these are just 0. See: + // https://www.w3.org/TR/css-position-3/#valdef-position-static + const double relativePositionMain = relativePosition( + mainAxis, + directionRespectingRoot, + isRow(mainAxis) ? ownerWidth : ownerHeight); + const double relativePositionCross = relativePosition( + crossAxis, + directionRespectingRoot, + isRow(mainAxis) ? ownerHeight : ownerWidth); + + const auto mainAxisLeadingEdge = inlineStartEdge(mainAxis, direction); + const auto mainAxisTrailingEdge = inlineEndEdge(mainAxis, direction); + const auto crossAxisLeadingEdge = inlineStartEdge(crossAxis, direction); + const auto crossAxisTrailingEdge = inlineEndEdge(crossAxis, direction); + + setLayoutPosition( + (style_.computeInlineStartMargin(mainAxis, direction, ownerWidth) + + relativePositionMain), + mainAxisLeadingEdge); + setLayoutPosition( + (style_.computeInlineEndMargin(mainAxis, direction, ownerWidth) + + relativePositionMain), + mainAxisTrailingEdge); + setLayoutPosition( + (style_.computeInlineStartMargin(crossAxis, direction, ownerWidth) + + relativePositionCross), + crossAxisLeadingEdge); + setLayoutPosition( + (style_.computeInlineEndMargin(crossAxis, direction, ownerWidth) + + relativePositionCross), + crossAxisTrailingEdge); +} + +Style::SizeLength Node::processFlexBasis() const { + Style::SizeLength flexBasis = style_.flexBasis(); + if (!flexBasis.isAuto() && !flexBasis.isUndefined()) { + return flexBasis; + } + if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0) { + return config_->useWebDefaults() ? StyleSizeLength::ofAuto() + : StyleSizeLength::points(0); + } + return StyleSizeLength::ofAuto(); +} + +FloatOptional Node::resolveFlexBasis( + Direction direction, + FlexDirection flexDirection, + double referenceLength, + double ownerWidth) const { + FloatOptional value = processFlexBasis().resolve(referenceLength); + if (style_.boxSizing() == BoxSizing::BorderBox) { + return value; + } + + Dimension dim = dimension(flexDirection); + FloatOptional dimensionPaddingAndBorder = FloatOptional{ + style_.computePaddingAndBorderForDimension(direction, dim, ownerWidth)}; + + return value + + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder + : FloatOptional{0.0}); +} + +void Node::processDimensions() { + for (auto dim : {Dimension::Width, Dimension::Height}) { + if (style_.maxDimension(dim).isDefined() && + yoga::inexactEquals( + style_.maxDimension(dim), style_.minDimension(dim))) { + processedDimensions_[yoga::to_underlying(dim)] = style_.maxDimension(dim); + } else { + processedDimensions_[yoga::to_underlying(dim)] = style_.dimension(dim); + } + } +} + +Direction Node::resolveDirection(const Direction ownerDirection) { + if (style_.direction() == Direction::Inherit) { + return ownerDirection != Direction::Inherit ? ownerDirection + : Direction::LTR; + } else { + return style_.direction(); + } +} + +void Node::clearChildren() { + children_.clear(); + children_.shrink_to_fit(); +} + +// Other Methods + +void Node::cloneChildrenIfNeeded() { + size_t i = 0; + for (Node*& child : children_) { + if (child->getOwner() != this) { + child = resolveRef(config_->cloneNode(child, this, i)); + child->setOwner(this); + } + i += 1; + } +} + +void Node::markDirtyAndPropagate() { + if (!isDirty_) { + setDirty(true); + setLayoutComputedFlexBasis(FloatOptional()); + if (owner_ != nullptr) { + owner_->markDirtyAndPropagate(); + } + } +} + +double Node::resolveFlexGrow() const { + // Root nodes flexGrow should always be 0 + if (owner_ == nullptr) { + return 0.0; + } + if (style_.flexGrow().isDefined()) { + return style_.flexGrow().unwrap(); + } + if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0) { + return style_.flex().unwrap(); + } + return Style::DefaultFlexGrow; +} + +double Node::resolveFlexShrink() const { + if (owner_ == nullptr) { + return 0.0; + } + if (style_.flexShrink().isDefined()) { + return style_.flexShrink().unwrap(); + } + if (!config_->useWebDefaults() && style_.flex().isDefined() && + style_.flex().unwrap() < 0.0) { + return -style_.flex().unwrap(); + } + return config_->useWebDefaults() ? Style::WebDefaultFlexShrink + : Style::DefaultFlexShrink; +} + +bool Node::isNodeFlexible() { + return ( + (style_.positionType() != PositionType::Absolute) && + (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); +} + +void Node::reset() { + yoga::assertFatalWithNode( + this, + children_.empty(), + "Cannot reset a node which still has children attached"); + yoga::assertFatalWithNode( + this, owner_ == nullptr, "Cannot reset a node still attached to a owner"); + + *this = Node{getConfig()}; +} + +} // namespace facebook::yoga diff --git a/yoga/node/Node.h b/yoga/node/Node.h new file mode 100644 index 0000000000..44c58bfcad --- /dev/null +++ b/yoga/node/Node.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Tag struct used to form the opaque YGNodeRef for the public C API +struct YGNode {}; + +namespace facebook::yoga { + +class YG_EXPORT Node : public ::YGNode { + public: + using LayoutableChildren = yoga::LayoutableChildren; + Node(); + explicit Node(const Config* config); + + Node(Node&& node) noexcept; + + // Does not expose true value semantics, as children are not cloned eagerly. + // Should we remove this? + Node(const Node& node) = default; + + // assignment means potential leaks of existing children, or alternatively + // freeing unowned memory, double free, or freeing stack memory. + Node& operator=(const Node&) = delete; + + // Getters + void* getContext() const { + return context_; + } + + bool alwaysFormsContainingBlock() const { + return alwaysFormsContainingBlock_; + } + + bool getHasNewLayout() const { + return hasNewLayout_; + } + + NodeType getNodeType() const { + return nodeType_; + } + + bool hasMeasureFunc() const noexcept { + return measureFunc_ != nullptr; + } + + YGSize measure( + double availableWidth, + MeasureMode widthMode, + double availableHeight, + MeasureMode heightMode); + + bool hasBaselineFunc() const noexcept { + return baselineFunc_ != nullptr; + } + + double baseline(double width, double height) const; + + double dimensionWithMargin(FlexDirection axis, double widthSize); + + bool isLayoutDimensionDefined(FlexDirection axis); + + /** + * Whether the node has a "definite length" along the given axis. + * https://www.w3.org/TR/css-sizing-3/#definite + */ + inline bool hasDefiniteLength(Dimension dimension, double ownerSize) { + auto usedValue = getProcessedDimension(dimension).resolve(ownerSize); + return usedValue.isDefined() && usedValue.unwrap() >= 0.0; + } + + bool hasErrata(Errata errata) const { + return config_->hasErrata(errata); + } + + YGDirtiedFunc getDirtiedFunc() const { + return dirtiedFunc_; + } + + // For Performance reasons passing as reference. + Style& style() { + return style_; + } + + const Style& style() const { + return style_; + } + + // For Performance reasons passing as reference. + LayoutResults& getLayout() { + return layout_; + } + + const LayoutResults& getLayout() const { + return layout_; + } + + size_t getLineIndex() const { + return lineIndex_; + } + + bool isReferenceBaseline() const { + return isReferenceBaseline_; + } + + // returns the Node that owns this Node. An owner is used to identify + // the YogaTree that a Node belongs to. This method will return the parent + // of the Node when a Node only belongs to one YogaTree or nullptr when + // the Node is shared between two or more YogaTrees. + Node* getOwner() const { + return owner_; + } + + const std::vector& getChildren() const { + return children_; + } + + Node* getChild(size_t index) const { + return children_.at(index); + } + + size_t getChildCount() const { + return children_.size(); + } + + LayoutableChildren getLayoutChildren() const { + return LayoutableChildren(this); + } + + size_t getLayoutChildCount() const { + if (contentsChildrenCount_ == 0) { + return children_.size(); + } else { + size_t count = 0; + for (auto iter = getLayoutChildren().begin(); + iter != getLayoutChildren().end(); + iter++) { + count++; + } + return count; + } + } + + const Config* getConfig() const { + return config_; + } + + bool isDirty() const { + return isDirty_; + } + + Style::SizeLength getProcessedDimension(Dimension dimension) const { + return processedDimensions_[static_cast(dimension)]; + } + + FloatOptional getResolvedDimension( + Direction direction, + Dimension dimension, + double referenceLength, + double ownerWidth) const { + FloatOptional value = + getProcessedDimension(dimension).resolve(referenceLength); + if (style_.boxSizing() == BoxSizing::BorderBox) { + return value; + } + + FloatOptional dimensionPaddingAndBorder = + FloatOptional{style_.computePaddingAndBorderForDimension( + direction, dimension, ownerWidth)}; + + return value + + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder + : FloatOptional{0.0}); + } + + // Setters + + void setContext(void* context) { + context_ = context; + } + + void setAlwaysFormsContainingBlock(bool alwaysFormsContainingBlock) { + alwaysFormsContainingBlock_ = alwaysFormsContainingBlock; + } + + void setHasNewLayout(bool hasNewLayout) { + hasNewLayout_ = hasNewLayout; + } + + void setNodeType(NodeType nodeType) { + nodeType_ = nodeType; + } + + void setMeasureFunc(YGMeasureFunc measureFunc); + + void setBaselineFunc(YGBaselineFunc baseLineFunc) { + baselineFunc_ = baseLineFunc; + } + + void setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { + dirtiedFunc_ = dirtiedFunc; + } + + void setStyle(const Style& style) { + style_ = style; + } + + void setLayout(const LayoutResults& layout) { + layout_ = layout; + } + + void setLineIndex(size_t lineIndex) { + lineIndex_ = lineIndex; + } + + void setIsReferenceBaseline(bool isReferenceBaseline) { + isReferenceBaseline_ = isReferenceBaseline; + } + + void setOwner(Node* owner) { + owner_ = owner; + } + + void setChildren(const std::vector& children) { + children_ = children; + } + + // TODO: rvalue override for setChildren + + void setConfig(Config* config); + + void setDirty(bool isDirty); + void setLayoutLastOwnerDirection(Direction direction); + void setLayoutComputedFlexBasis(FloatOptional computedFlexBasis); + void setLayoutComputedFlexBasisGeneration( + uint32_t computedFlexBasisGeneration); + void setLayoutMeasuredDimension(double measuredDimension, Dimension dimension); + void setLayoutHadOverflow(bool hadOverflow); + void setLayoutDimension(double lengthValue, Dimension dimension); + void setLayoutDirection(Direction direction); + void setLayoutMargin(double margin, PhysicalEdge edge); + void setLayoutBorder(double border, PhysicalEdge edge); + void setLayoutPadding(double padding, PhysicalEdge edge); + void setLayoutPosition(double position, PhysicalEdge edge); + void setPosition(Direction direction, double ownerWidth, double ownerHeight); + + // Other methods + Style::SizeLength processFlexBasis() const; + FloatOptional resolveFlexBasis( + Direction direction, + FlexDirection flexDirection, + double referenceLength, + double ownerWidth) const; + void processDimensions(); + Direction resolveDirection(Direction ownerDirection); + void clearChildren(); + /// Replaces the occurrences of oldChild with newChild + void replaceChild(Node* oldChild, Node* newChild); + void replaceChild(Node* child, size_t index); + void insertChild(Node* child, size_t index); + /// Removes the first occurrence of child + bool removeChild(Node* child); + void removeChild(size_t index); + + void cloneChildrenIfNeeded(); + void markDirtyAndPropagate(); + double resolveFlexGrow() const; + double resolveFlexShrink() const; + bool isNodeFlexible(); + void reset(); + + private: + // Used to allow resetting the node + Node& operator=(Node&&) noexcept = default; + + double relativePosition( + FlexDirection axis, + Direction direction, + double axisSize) const; + + void useWebDefaults() { + style_.setFlexDirection(FlexDirection::Row); + style_.setAlignContent(Align::Stretch); + } + + bool hasNewLayout_ : 1 = true; + bool isReferenceBaseline_ : 1 = false; + bool isDirty_ : 1 = true; + bool alwaysFormsContainingBlock_ : 1 = false; + NodeType nodeType_ : bitCount() = NodeType::Default; + void* context_ = nullptr; + YGMeasureFunc measureFunc_ = nullptr; + YGBaselineFunc baselineFunc_ = nullptr; + YGDirtiedFunc dirtiedFunc_ = nullptr; + Style style_; + LayoutResults layout_; + size_t lineIndex_ = 0; + size_t contentsChildrenCount_ = 0; + Node* owner_ = nullptr; + std::vector children_; + const Config* config_; + std::array processedDimensions_{ + {StyleSizeLength::undefined(), StyleSizeLength::undefined()}}; +}; + +inline Node* resolveRef(const YGNodeRef ref) { + return static_cast(ref); +} + +inline const Node* resolveRef(const YGNodeConstRef ref) { + return static_cast(ref); +} + +} // namespace facebook::yoga diff --git a/yoga/numeric/Comparison.h b/yoga/numeric/Comparison.h new file mode 100644 index 0000000000..ef15cf03ea --- /dev/null +++ b/yoga/numeric/Comparison.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +constexpr bool isUndefined(std::floating_point auto value) { + return value != value; +} + +constexpr bool isDefined(std::floating_point auto value) { + return !isUndefined(value); +} + +/** + * Constexpr version of `std::isinf` before C++ 23 + */ +constexpr bool isinf(auto value) { + return value == +std::numeric_limits::infinity() || + value == -std::numeric_limits::infinity(); +} + +constexpr auto maxOrDefined( + std::floating_point auto a, + std::floating_point auto b) { + if (yoga::isDefined(a) && yoga::isDefined(b)) { + return std::max(a, b); + } + return yoga::isUndefined(a) ? b : a; +} + +constexpr auto minOrDefined( + std::floating_point auto a, + std::floating_point auto b) { + if (yoga::isDefined(a) && yoga::isDefined(b)) { + return std::min(a, b); + } + + return yoga::isUndefined(a) ? b : a; +} + +// Custom equality functions using a hardcoded epsilon of 0.0001, or returning +// true if both floats are NaN. +inline bool inexactEquals(double a, double b) { + if (yoga::isDefined(a) && yoga::isDefined(b)) { + return std::abs(a - b) < 0.0001; + } + return yoga::isUndefined(a) && yoga::isUndefined(b); +} + +template +bool inexactEquals( + const std::array& val1, + const std::array& val2) { + bool areEqual = true; + for (std::size_t i = 0; i < Size && areEqual; ++i) { + areEqual = inexactEquals(val1[i], val2[i]); + } + return areEqual; +} + +} // namespace facebook::yoga diff --git a/yoga/numeric/FloatOptional.h b/yoga/numeric/FloatOptional.h new file mode 100644 index 0000000000..953da401fd --- /dev/null +++ b/yoga/numeric/FloatOptional.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +struct FloatOptional { + private: + double value_ = std::numeric_limits::quiet_NaN(); + + public: + explicit constexpr FloatOptional(double value) : value_(value) {} + constexpr FloatOptional() = default; + + // returns the wrapped value, or a value x with YGIsUndefined(x) == true + constexpr double unwrap() const { + return value_; + } + + constexpr double unwrapOrDefault(double defaultValue) const { + return isUndefined() ? defaultValue : value_; + } + + constexpr bool isUndefined() const { + return yoga::isUndefined(value_); + } + + constexpr bool isDefined() const { + return yoga::isDefined(value_); + } +}; + +// operators take FloatOptional by value, as it is a 32bit value + +constexpr bool operator==(FloatOptional lhs, FloatOptional rhs) { + return lhs.unwrap() == rhs.unwrap() || + (lhs.isUndefined() && rhs.isUndefined()); +} +constexpr bool operator!=(FloatOptional lhs, FloatOptional rhs) { + return !(lhs == rhs); +} + +constexpr bool operator==(FloatOptional lhs, double rhs) { + return lhs == FloatOptional{rhs}; +} +constexpr bool operator!=(FloatOptional lhs, double rhs) { + return !(lhs == rhs); +} + +constexpr bool operator==(double lhs, FloatOptional rhs) { + return rhs == lhs; +} +constexpr bool operator!=(double lhs, FloatOptional rhs) { + return !(lhs == rhs); +} + +constexpr FloatOptional operator+(FloatOptional lhs, FloatOptional rhs) { + return FloatOptional{lhs.unwrap() + rhs.unwrap()}; +} + +constexpr bool operator>(FloatOptional lhs, FloatOptional rhs) { + return lhs.unwrap() > rhs.unwrap(); +} + +constexpr bool operator<(FloatOptional lhs, FloatOptional rhs) { + return lhs.unwrap() < rhs.unwrap(); +} + +constexpr bool operator>=(FloatOptional lhs, FloatOptional rhs) { + return lhs > rhs || lhs == rhs; +} + +constexpr bool operator<=(FloatOptional lhs, FloatOptional rhs) { + return lhs < rhs || lhs == rhs; +} + +constexpr FloatOptional maxOrDefined(FloatOptional lhs, FloatOptional rhs) { + return FloatOptional{yoga::maxOrDefined(lhs.unwrap(), rhs.unwrap())}; +} + +inline bool inexactEquals(FloatOptional lhs, FloatOptional rhs) { + return yoga::inexactEquals(lhs.unwrap(), rhs.unwrap()); +} + +} // namespace facebook::yoga diff --git a/yoga/style/SmallValueBuffer.h b/yoga/style/SmallValueBuffer.h new file mode 100644 index 0000000000..8d78a54dc9 --- /dev/null +++ b/yoga/style/SmallValueBuffer.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +// Container which allows storing 32 or 64 bit integer values, whose index may +// never change. Values are first stored in a fixed buffer of `BufferSize` +// 32-bit chunks, before falling back to heap allocation. +template +class SmallValueBuffer { + public: + SmallValueBuffer() = default; + SmallValueBuffer(const SmallValueBuffer& other) { + *this = other; + } + SmallValueBuffer(SmallValueBuffer&& other) noexcept = default; + + // Add a new element to the buffer, returning the index of the element + uint16_t push(uint32_t value) { + const auto index = count_++; + assert(index < 4096 && "SmallValueBuffer can only hold up to 4096 chunks"); + if (index < buffer_.size()) { + buffer_[index] = value; + return index; + } + + if (overflow_ == nullptr) { + overflow_ = std::make_unique(); + } + + overflow_->buffer_.push_back(value); + overflow_->wideElements_.push_back(false); + return index; + } + + uint16_t push(uint64_t value) { + const auto lsb = static_cast(value & 0xFFFFFFFF); + const auto msb = static_cast(value >> 32); + + const auto lsbIndex = push(lsb); + [[maybe_unused]] const auto msbIndex = push(msb); + assert( + msbIndex < 4096 && "SmallValueBuffer can only hold up to 4096 chunks"); + + if (lsbIndex < buffer_.size()) { + wideElements_[lsbIndex] = true; + } else { + overflow_->wideElements_[lsbIndex - buffer_.size()] = true; + } + return lsbIndex; + } + + // Replace an existing element in the buffer with a new value. A new index + // may be returned, e.g. if a new value is wider than the previous. + [[nodiscard]] uint16_t replace(uint16_t index, uint32_t value) { + if (index < buffer_.size()) { + buffer_[index] = value; + } else { + overflow_->buffer_.at(index - buffer_.size()) = value; + } + + return index; + } + + [[nodiscard]] uint16_t replace(uint16_t index, uint64_t value) { + const bool isWide = index < wideElements_.size() + ? wideElements_[index] + : overflow_->wideElements_.at(index - buffer_.size()); + + if (isWide) { + const auto lsb = static_cast(value & 0xFFFFFFFF); + const auto msb = static_cast(value >> 32); + + [[maybe_unused]] auto lsbIndex = replace(index, lsb); + [[maybe_unused]] auto msbIndex = replace(index + 1, msb); + return index; + } else { + return push(value); + } + } + + // Get a value of a given width + uint32_t get32(uint16_t index) const { + if (index < buffer_.size()) { + return buffer_[index]; + } else { + return overflow_->buffer_.at(index - buffer_.size()); + } + } + + uint64_t get64(uint16_t index) const { + const auto lsb = get32(index); + const auto msb = get32(index + 1); + return (static_cast(msb) << 32) | lsb; + } + + SmallValueBuffer& operator=(const SmallValueBuffer& other) { + count_ = other.count_; + buffer_ = other.buffer_; + wideElements_ = other.wideElements_; + overflow_ = other.overflow_ ? std::make_unique(*other.overflow_) + : nullptr; + return *this; + } + + SmallValueBuffer& operator=(SmallValueBuffer&& other) noexcept = default; + + private: + struct Overflow { + std::vector buffer_; + std::vector wideElements_; + }; + + uint16_t count_{0}; + std::array buffer_{}; + std::bitset wideElements_; + std::unique_ptr overflow_; +}; + +} // namespace facebook::yoga diff --git a/yoga/style/Style.h b/yoga/style/Style.h new file mode 100644 index 0000000000..0fe3b0041c --- /dev/null +++ b/yoga/style/Style.h @@ -0,0 +1,759 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook::yoga { + +class YG_EXPORT Style { + public: + using Length = StyleLength; + using SizeLength = StyleSizeLength; + + static constexpr double DefaultFlexGrow = 0.0; + static constexpr double DefaultFlexShrink = 0.0; + static constexpr double WebDefaultFlexShrink = 1.0; + + Direction direction() const { + return direction_; + } + void setDirection(Direction value) { + direction_ = value; + } + + FlexDirection flexDirection() const { + return flexDirection_; + } + void setFlexDirection(FlexDirection value) { + flexDirection_ = value; + } + + Justify justifyContent() const { + return justifyContent_; + } + void setJustifyContent(Justify value) { + justifyContent_ = value; + } + + Align alignContent() const { + return alignContent_; + } + void setAlignContent(Align value) { + alignContent_ = value; + } + + Align alignItems() const { + return alignItems_; + } + void setAlignItems(Align value) { + alignItems_ = value; + } + + Align alignSelf() const { + return alignSelf_; + } + void setAlignSelf(Align value) { + alignSelf_ = value; + } + + PositionType positionType() const { + return positionType_; + } + void setPositionType(PositionType value) { + positionType_ = value; + } + + Wrap flexWrap() const { + return flexWrap_; + } + void setFlexWrap(Wrap value) { + flexWrap_ = value; + } + + Overflow overflow() const { + return overflow_; + } + void setOverflow(Overflow value) { + overflow_ = value; + } + + Display display() const { + return display_; + } + void setDisplay(Display value) { + display_ = value; + } + + FloatOptional flex() const { + return pool_.getNumber(flex_); + } + void setFlex(FloatOptional value) { + pool_.store(flex_, value); + } + + FloatOptional flexGrow() const { + return pool_.getNumber(flexGrow_); + } + void setFlexGrow(FloatOptional value) { + pool_.store(flexGrow_, value); + } + + FloatOptional flexShrink() const { + return pool_.getNumber(flexShrink_); + } + void setFlexShrink(FloatOptional value) { + pool_.store(flexShrink_, value); + } + + Style::SizeLength flexBasis() const { + return pool_.getSize(flexBasis_); + } + void setFlexBasis(Style::SizeLength value) { + pool_.store(flexBasis_, value); + } + + Style::Length margin(Edge edge) const { + return pool_.getLength(margin_[yoga::to_underlying(edge)]); + } + void setMargin(Edge edge, Style::Length value) { + pool_.store(margin_[yoga::to_underlying(edge)], value); + } + + Style::Length position(Edge edge) const { + return pool_.getLength(position_[yoga::to_underlying(edge)]); + } + void setPosition(Edge edge, Style::Length value) { + pool_.store(position_[yoga::to_underlying(edge)], value); + } + + Style::Length padding(Edge edge) const { + return pool_.getLength(padding_[yoga::to_underlying(edge)]); + } + void setPadding(Edge edge, Style::Length value) { + pool_.store(padding_[yoga::to_underlying(edge)], value); + } + + Style::Length border(Edge edge) const { + return pool_.getLength(border_[yoga::to_underlying(edge)]); + } + void setBorder(Edge edge, Style::Length value) { + pool_.store(border_[yoga::to_underlying(edge)], value); + } + + Style::Length gap(Gutter gutter) const { + return pool_.getLength(gap_[yoga::to_underlying(gutter)]); + } + void setGap(Gutter gutter, Style::Length value) { + pool_.store(gap_[yoga::to_underlying(gutter)], value); + } + + Style::SizeLength dimension(Dimension axis) const { + return pool_.getSize(dimensions_[yoga::to_underlying(axis)]); + } + void setDimension(Dimension axis, Style::SizeLength value) { + pool_.store(dimensions_[yoga::to_underlying(axis)], value); + } + + Style::SizeLength minDimension(Dimension axis) const { + return pool_.getSize(minDimensions_[yoga::to_underlying(axis)]); + } + void setMinDimension(Dimension axis, Style::SizeLength value) { + pool_.store(minDimensions_[yoga::to_underlying(axis)], value); + } + + FloatOptional resolvedMinDimension( + Direction direction, + Dimension axis, + double referenceLength, + double ownerWidth) const { + FloatOptional value = minDimension(axis).resolve(referenceLength); + if (boxSizing() == BoxSizing::BorderBox) { + return value; + } + + FloatOptional dimensionPaddingAndBorder = FloatOptional{ + computePaddingAndBorderForDimension(direction, axis, ownerWidth)}; + + return value + + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder + : FloatOptional{0.0}); + } + + Style::SizeLength maxDimension(Dimension axis) const { + return pool_.getSize(maxDimensions_[yoga::to_underlying(axis)]); + } + void setMaxDimension(Dimension axis, Style::SizeLength value) { + pool_.store(maxDimensions_[yoga::to_underlying(axis)], value); + } + + FloatOptional resolvedMaxDimension( + Direction direction, + Dimension axis, + double referenceLength, + double ownerWidth) const { + FloatOptional value = maxDimension(axis).resolve(referenceLength); + if (boxSizing() == BoxSizing::BorderBox) { + return value; + } + + FloatOptional dimensionPaddingAndBorder = FloatOptional{ + computePaddingAndBorderForDimension(direction, axis, ownerWidth)}; + + return value + + (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder + : FloatOptional{0.0}); + } + + FloatOptional aspectRatio() const { + return pool_.getNumber(aspectRatio_); + } + void setAspectRatio(FloatOptional value) { + // degenerate aspect ratios act as auto. + // see https://drafts.csswg.org/css-sizing-4/#valdef-aspect-ratio-ratio + pool_.store( + aspectRatio_, + value == 0.0 || std::isinf(value.unwrap()) ? FloatOptional{} : value); + } + + BoxSizing boxSizing() const { + return boxSizing_; + } + void setBoxSizing(BoxSizing value) { + boxSizing_ = value; + } + + bool horizontalInsetsDefined() const { + return position_[yoga::to_underlying(Edge::Left)].isDefined() || + position_[yoga::to_underlying(Edge::Right)].isDefined() || + position_[yoga::to_underlying(Edge::All)].isDefined() || + position_[yoga::to_underlying(Edge::Horizontal)].isDefined() || + position_[yoga::to_underlying(Edge::Start)].isDefined() || + position_[yoga::to_underlying(Edge::End)].isDefined(); + } + + bool verticalInsetsDefined() const { + return position_[yoga::to_underlying(Edge::Top)].isDefined() || + position_[yoga::to_underlying(Edge::Bottom)].isDefined() || + position_[yoga::to_underlying(Edge::All)].isDefined() || + position_[yoga::to_underlying(Edge::Vertical)].isDefined(); + } + + bool isFlexStartPositionDefined(FlexDirection axis, Direction direction) + const { + return computePosition(flexStartEdge(axis), direction).isDefined(); + } + + bool isFlexStartPositionAuto(FlexDirection axis, Direction direction) const { + return computePosition(flexStartEdge(axis), direction).isAuto(); + } + + bool isInlineStartPositionDefined(FlexDirection axis, Direction direction) + const { + return computePosition(inlineStartEdge(axis, direction), direction) + .isDefined(); + } + + bool isInlineStartPositionAuto(FlexDirection axis, Direction direction) + const { + return computePosition(inlineStartEdge(axis, direction), direction) + .isAuto(); + } + + bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const { + return computePosition(flexEndEdge(axis), direction).isDefined(); + } + + bool isFlexEndPositionAuto(FlexDirection axis, Direction direction) const { + return computePosition(flexEndEdge(axis), direction).isAuto(); + } + + bool isInlineEndPositionDefined(FlexDirection axis, Direction direction) + const { + return computePosition(inlineEndEdge(axis, direction), direction) + .isDefined(); + } + + bool isInlineEndPositionAuto(FlexDirection axis, Direction direction) const { + return computePosition(inlineEndEdge(axis, direction), direction).isAuto(); + } + + double computeFlexStartPosition( + FlexDirection axis, + Direction direction, + double axisSize) const { + return computePosition(flexStartEdge(axis), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0); + } + + double computeInlineStartPosition( + FlexDirection axis, + Direction direction, + double axisSize) const { + return computePosition(inlineStartEdge(axis, direction), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0); + } + + double computeFlexEndPosition( + FlexDirection axis, + Direction direction, + double axisSize) const { + return computePosition(flexEndEdge(axis), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0); + } + + double computeInlineEndPosition( + FlexDirection axis, + Direction direction, + double axisSize) const { + return computePosition(inlineEndEdge(axis, direction), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0); + } + + double computeFlexStartMargin( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeMargin(flexStartEdge(axis), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0); + } + + double computeInlineStartMargin( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeMargin(inlineStartEdge(axis, direction), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0); + } + + double computeFlexEndMargin( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeMargin(flexEndEdge(axis), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0); + } + + double computeInlineEndMargin( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeMargin(inlineEndEdge(axis, direction), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0); + } + + double computeFlexStartBorder(FlexDirection axis, Direction direction) const { + return maxOrDefined( + computeBorder(flexStartEdge(axis), direction).resolve(0.0).unwrap(), + 0.0); + } + + double computeInlineStartBorder(FlexDirection axis, Direction direction) + const { + return maxOrDefined( + computeBorder(inlineStartEdge(axis, direction), direction) + .resolve(0.0) + .unwrap(), + 0.0); + } + + double computeFlexEndBorder(FlexDirection axis, Direction direction) const { + return maxOrDefined( + computeBorder(flexEndEdge(axis), direction).resolve(0.0).unwrap(), + 0.0); + } + + double computeInlineEndBorder(FlexDirection axis, Direction direction) const { + return maxOrDefined( + computeBorder(inlineEndEdge(axis, direction), direction) + .resolve(0.0) + .unwrap(), + 0.0); + } + + double computeFlexStartPadding( + FlexDirection axis, + Direction direction, + double widthSize) const { + return maxOrDefined( + computePadding(flexStartEdge(axis), direction) + .resolve(widthSize) + .unwrap(), + 0.0); + } + + double computeInlineStartPadding( + FlexDirection axis, + Direction direction, + double widthSize) const { + return maxOrDefined( + computePadding(inlineStartEdge(axis, direction), direction) + .resolve(widthSize) + .unwrap(), + 0.0); + } + + double computeFlexEndPadding( + FlexDirection axis, + Direction direction, + double widthSize) const { + return maxOrDefined( + computePadding(flexEndEdge(axis), direction) + .resolve(widthSize) + .unwrap(), + 0.0); + } + + double computeInlineEndPadding( + FlexDirection axis, + Direction direction, + double widthSize) const { + return maxOrDefined( + computePadding(inlineEndEdge(axis, direction), direction) + .resolve(widthSize) + .unwrap(), + 0.0); + } + + double computeInlineStartPaddingAndBorder( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeInlineStartPadding(axis, direction, widthSize) + + computeInlineStartBorder(axis, direction); + } + + double computeFlexStartPaddingAndBorder( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeFlexStartPadding(axis, direction, widthSize) + + computeFlexStartBorder(axis, direction); + } + + double computeInlineEndPaddingAndBorder( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeInlineEndPadding(axis, direction, widthSize) + + computeInlineEndBorder(axis, direction); + } + + double computeFlexEndPaddingAndBorder( + FlexDirection axis, + Direction direction, + double widthSize) const { + return computeFlexEndPadding(axis, direction, widthSize) + + computeFlexEndBorder(axis, direction); + } + + double computePaddingAndBorderForDimension( + Direction direction, + Dimension dimension, + double widthSize) const { + FlexDirection flexDirectionForDimension = dimension == Dimension::Width + ? FlexDirection::Row + : FlexDirection::Column; + + return computeFlexStartPaddingAndBorder( + flexDirectionForDimension, direction, widthSize) + + computeFlexEndPaddingAndBorder( + flexDirectionForDimension, direction, widthSize); + } + + double computeBorderForAxis(FlexDirection axis) const { + return computeInlineStartBorder(axis, Direction::LTR) + + computeInlineEndBorder(axis, Direction::LTR); + } + + double computeMarginForAxis(FlexDirection axis, double widthSize) const { + // The total margin for a given axis does not depend on the direction + // so hardcoding LTR here to avoid piping direction to this function + return computeInlineStartMargin(axis, Direction::LTR, widthSize) + + computeInlineEndMargin(axis, Direction::LTR, widthSize); + } + + double computeGapForAxis(FlexDirection axis, double ownerSize) const { + auto gap = isRow(axis) ? computeColumnGap() : computeRowGap(); + return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0); + } + + bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const { + return computeMargin(flexStartEdge(axis), direction).isAuto(); + } + + bool flexEndMarginIsAuto(FlexDirection axis, Direction direction) const { + return computeMargin(flexEndEdge(axis), direction).isAuto(); + } + + bool operator==(const Style& other) const { + return direction_ == other.direction_ && + flexDirection_ == other.flexDirection_ && + justifyContent_ == other.justifyContent_ && + alignContent_ == other.alignContent_ && + alignItems_ == other.alignItems_ && alignSelf_ == other.alignSelf_ && + positionType_ == other.positionType_ && flexWrap_ == other.flexWrap_ && + overflow_ == other.overflow_ && display_ == other.display_ && + numbersEqual(flex_, pool_, other.flex_, other.pool_) && + numbersEqual(flexGrow_, pool_, other.flexGrow_, other.pool_) && + numbersEqual(flexShrink_, pool_, other.flexShrink_, other.pool_) && + lengthsEqual(flexBasis_, pool_, other.flexBasis_, other.pool_) && + lengthsEqual(margin_, pool_, other.margin_, other.pool_) && + lengthsEqual(position_, pool_, other.position_, other.pool_) && + lengthsEqual(padding_, pool_, other.padding_, other.pool_) && + lengthsEqual(border_, pool_, other.border_, other.pool_) && + lengthsEqual(gap_, pool_, other.gap_, other.pool_) && + lengthsEqual(dimensions_, pool_, other.dimensions_, other.pool_) && + lengthsEqual( + minDimensions_, pool_, other.minDimensions_, other.pool_) && + lengthsEqual( + maxDimensions_, pool_, other.maxDimensions_, other.pool_) && + numbersEqual(aspectRatio_, pool_, other.aspectRatio_, other.pool_); + } + + bool operator!=(const Style& other) const { + return !(*this == other); + } + + private: + using Dimensions = std::array()>; + using Edges = std::array()>; + using Gutters = std::array()>; + + static inline bool numbersEqual( + const StyleValueHandle& lhsHandle, + const StyleValuePool& lhsPool, + const StyleValueHandle& rhsHandle, + const StyleValuePool& rhsPool) { + return (lhsHandle.isUndefined() && rhsHandle.isUndefined()) || + (lhsPool.getNumber(lhsHandle) == rhsPool.getNumber(rhsHandle)); + } + + static inline bool lengthsEqual( + const StyleValueHandle& lhsHandle, + const StyleValuePool& lhsPool, + const StyleValueHandle& rhsHandle, + const StyleValuePool& rhsPool) { + return (lhsHandle.isUndefined() && rhsHandle.isUndefined()) || + (lhsPool.getLength(lhsHandle) == rhsPool.getLength(rhsHandle)); + } + + template + static inline bool lengthsEqual( + const std::array& lhs, + const StyleValuePool& lhsPool, + const std::array& rhs, + const StyleValuePool& rhsPool) { + return std::equal( + lhs.begin(), + lhs.end(), + rhs.begin(), + rhs.end(), + [&](const auto& lhs, const auto& rhs) { + return lengthsEqual(lhs, lhsPool, rhs, rhsPool); + }); + } + + Style::Length computeColumnGap() const { + if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { + return pool_.getLength(gap_[yoga::to_underlying(Gutter::Column)]); + } else { + return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]); + } + } + + Style::Length computeRowGap() const { + if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { + return pool_.getLength(gap_[yoga::to_underlying(Gutter::Row)]); + } else { + return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]); + } + } + + Style::Length computeLeftEdge(const Edges& edges, Direction layoutDirection) + const { + if (layoutDirection == Direction::LTR && + edges[yoga::to_underlying(Edge::Start)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]); + } else if ( + layoutDirection == Direction::RTL && + edges[yoga::to_underlying(Edge::End)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::End)]); + } else if (edges[yoga::to_underlying(Edge::Left)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Left)]); + } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]); + } else { + return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + } + } + + Style::Length computeTopEdge(const Edges& edges) const { + if (edges[yoga::to_underlying(Edge::Top)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Top)]); + } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]); + } else { + return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + } + } + + Style::Length computeRightEdge(const Edges& edges, Direction layoutDirection) + const { + if (layoutDirection == Direction::LTR && + edges[yoga::to_underlying(Edge::End)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::End)]); + } else if ( + layoutDirection == Direction::RTL && + edges[yoga::to_underlying(Edge::Start)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]); + } else if (edges[yoga::to_underlying(Edge::Right)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Right)]); + } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]); + } else { + return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + } + } + + Style::Length computeBottomEdge(const Edges& edges) const { + if (edges[yoga::to_underlying(Edge::Bottom)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Bottom)]); + } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { + return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]); + } else { + return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + } + } + + Style::Length computePosition(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(position_, direction); + case PhysicalEdge::Top: + return computeTopEdge(position_); + case PhysicalEdge::Right: + return computeRightEdge(position_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(position_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Style::Length computeMargin(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(margin_, direction); + case PhysicalEdge::Top: + return computeTopEdge(margin_); + case PhysicalEdge::Right: + return computeRightEdge(margin_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(margin_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Style::Length computePadding(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(padding_, direction); + case PhysicalEdge::Top: + return computeTopEdge(padding_); + case PhysicalEdge::Right: + return computeRightEdge(padding_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(padding_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Style::Length computeBorder(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(border_, direction); + case PhysicalEdge::Top: + return computeTopEdge(border_); + case PhysicalEdge::Right: + return computeRightEdge(border_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(border_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Direction direction_ : bitCount() = Direction::Inherit; + FlexDirection flexDirection_ + : bitCount() = FlexDirection::Column; + Justify justifyContent_ : bitCount() = Justify::FlexStart; + Align alignContent_ : bitCount() = Align::FlexStart; + Align alignItems_ : bitCount() = Align::Stretch; + Align alignSelf_ : bitCount() = Align::Auto; + PositionType positionType_ + : bitCount() = PositionType::Relative; + Wrap flexWrap_ : bitCount() = Wrap::NoWrap; + Overflow overflow_ : bitCount() = Overflow::Visible; + Display display_ : bitCount() = Display::Flex; + BoxSizing boxSizing_ : bitCount() = BoxSizing::BorderBox; + + StyleValueHandle flex_{}; + StyleValueHandle flexGrow_{}; + StyleValueHandle flexShrink_{}; + StyleValueHandle flexBasis_{StyleValueHandle::ofAuto()}; + Edges margin_{}; + Edges position_{}; + Edges padding_{}; + Edges border_{}; + Gutters gap_{}; + Dimensions dimensions_{ + StyleValueHandle::ofAuto(), + StyleValueHandle::ofAuto()}; + Dimensions minDimensions_{}; + Dimensions maxDimensions_{}; + StyleValueHandle aspectRatio_{}; + + StyleValuePool pool_; +}; + +} // namespace facebook::yoga diff --git a/yoga/style/StyleLength.h b/yoga/style/StyleLength.h new file mode 100644 index 0000000000..1d15afbf12 --- /dev/null +++ b/yoga/style/StyleLength.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +/** + * Style::Length represents a CSS Value which may be one of: + * 1. Undefined + * 2. A keyword (e.g. auto) + * 3. A CSS value: + * a. value (e.g. 10px) + * b. value of a reference + * + * References: + * 1. https://www.w3.org/TR/css-values-4/#lengths + * 2. https://www.w3.org/TR/css-values-4/#percentage-value + * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages + */ +class StyleLength { + public: + constexpr StyleLength() = default; + + constexpr static StyleLength points(double value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleLength{FloatOptional{value}, Unit::Point}; + } + + constexpr static StyleLength percent(double value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleLength{FloatOptional{value}, Unit::Percent}; + } + + constexpr static StyleLength ofAuto() { + return StyleLength{{}, Unit::Auto}; + } + + constexpr static StyleLength undefined() { + return StyleLength{{}, Unit::Undefined}; + } + + constexpr bool isAuto() const { + return unit_ == Unit::Auto; + } + + constexpr bool isUndefined() const { + return unit_ == Unit::Undefined; + } + + constexpr bool isPoints() const { + return unit_ == Unit::Point; + } + + constexpr bool isPercent() const { + return unit_ == Unit::Percent; + } + + constexpr bool isDefined() const { + return !isUndefined(); + } + + constexpr FloatOptional value() const { + return value_; + } + + constexpr FloatOptional resolve(double referenceLength) { + switch (unit_) { + case Unit::Point: + return value_; + case Unit::Percent: + return FloatOptional{value_.unwrap() * referenceLength * 0.01}; + default: + return FloatOptional{}; + } + } + + explicit constexpr operator YGValue() const { + return YGValue{value_.unwrap(), unscopedEnum(unit_)}; + } + + constexpr bool operator==(const StyleLength& rhs) const { + return value_ == rhs.value_ && unit_ == rhs.unit_; + } + + constexpr bool inexactEquals(const StyleLength& other) const { + return unit_ == other.unit_ && + facebook::yoga::inexactEquals(value_, other.value_); + } + + private: + // We intentionally do not allow direct construction using value and unit, to + // avoid invalid, or redundant combinations. + constexpr StyleLength(FloatOptional value, Unit unit) + : value_(value), unit_(unit) {} + + FloatOptional value_{}; + Unit unit_{Unit::Undefined}; +}; + +inline bool inexactEquals(const StyleLength& a, const StyleLength& b) { + return a.inexactEquals(b); +} + +} // namespace facebook::yoga diff --git a/yoga/style/StyleSizeLength.h b/yoga/style/StyleSizeLength.h new file mode 100644 index 0000000000..4a445b33f2 --- /dev/null +++ b/yoga/style/StyleSizeLength.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +/** + * This class represents a CSS Value for sizes (e.g. width, height, min-width, + * etc.). It may be one of: + * 1. Undefined + * 2. A keyword (e.g. auto, max-content, stretch, etc.) + * 3. A CSS value: + * a. value (e.g. 10px) + * b. value of a reference + * + * References: + * 1. https://www.w3.org/TR/css-values-4/#lengths + * 2. https://www.w3.org/TR/css-values-4/#percentage-value + * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages + */ +class StyleSizeLength { + public: + constexpr StyleSizeLength() = default; + + constexpr static StyleSizeLength points(double value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleSizeLength{FloatOptional{value}, Unit::Point}; + } + + constexpr static StyleSizeLength percent(double value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleSizeLength{FloatOptional{value}, Unit::Percent}; + } + + constexpr static StyleSizeLength ofAuto() { + return StyleSizeLength{{}, Unit::Auto}; + } + + constexpr static StyleSizeLength ofMaxContent() { + return StyleSizeLength{{}, Unit::MaxContent}; + } + + constexpr static StyleSizeLength ofFitContent() { + return StyleSizeLength{{}, Unit::FitContent}; + } + + constexpr static StyleSizeLength ofStretch() { + return StyleSizeLength{{}, Unit::Stretch}; + } + + constexpr static StyleSizeLength undefined() { + return StyleSizeLength{{}, Unit::Undefined}; + } + + constexpr bool isAuto() const { + return unit_ == Unit::Auto; + } + + constexpr bool isMaxContent() const { + return unit_ == Unit::MaxContent; + } + + constexpr bool isFitContent() const { + return unit_ == Unit::FitContent; + } + + constexpr bool isStretch() const { + return unit_ == Unit::Stretch; + } + + constexpr bool isUndefined() const { + return unit_ == Unit::Undefined; + } + + constexpr bool isDefined() const { + return !isUndefined(); + } + + constexpr bool isPoints() const { + return unit_ == Unit::Point; + } + + constexpr bool isPercent() const { + return unit_ == Unit::Percent; + } + + constexpr FloatOptional value() const { + return value_; + } + + constexpr FloatOptional resolve(double referenceLength) { + switch (unit_) { + case Unit::Point: + return value_; + case Unit::Percent: + return FloatOptional{value_.unwrap() * referenceLength * 0.01}; + default: + return FloatOptional{}; + } + } + + explicit constexpr operator YGValue() const { + return YGValue{value_.unwrap(), unscopedEnum(unit_)}; + } + + constexpr bool operator==(const StyleSizeLength& rhs) const { + return value_ == rhs.value_ && unit_ == rhs.unit_; + } + + constexpr bool inexactEquals(const StyleSizeLength& other) const { + return unit_ == other.unit_ && + facebook::yoga::inexactEquals(value_, other.value_); + } + + private: + // We intentionally do not allow direct construction using value and unit, to + // avoid invalid, or redundant combinations. + constexpr StyleSizeLength(FloatOptional value, Unit unit) + : value_(value), unit_(unit) {} + + FloatOptional value_{}; + Unit unit_{Unit::Undefined}; +}; + +inline bool inexactEquals(const StyleSizeLength& a, const StyleSizeLength& b) { + return a.inexactEquals(b); +} + +} // namespace facebook::yoga diff --git a/yoga/style/StyleValueHandle.h b/yoga/style/StyleValueHandle.h new file mode 100644 index 0000000000..d9c6ae0579 --- /dev/null +++ b/yoga/style/StyleValueHandle.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 + +namespace facebook::yoga { + +#pragma pack(push) +#pragma pack(1) + +/** + * StyleValueHandle is a small (16-bit) handle to a length or number in a style. + * The value may be embedded directly in the handle if simple, or the handle may + * instead point to an index within a StyleValuePool. + * + * To read or write a value from a StyleValueHandle, use + * `StyleValuePool::store()`, and `StyleValuePool::getLength()`/ + * `StyleValuePool::getNumber()`. + */ +class StyleValueHandle { + public: + static constexpr StyleValueHandle ofAuto() { + StyleValueHandle handle; + handle.setType(Type::Auto); + return handle; + } + + constexpr bool isUndefined() const { + return type() == Type::Undefined; + } + + constexpr bool isDefined() const { + return !isUndefined(); + } + + constexpr bool isAuto() const { + return type() == Type::Auto; + } + + private: + friend class StyleValuePool; + + static constexpr uint16_t kHandleTypeMask = 0b0000'0000'0000'0111; + static constexpr uint16_t kHandleIndexedMask = 0b0000'0000'0000'1000; + static constexpr uint16_t kHandleValueMask = 0b1111'1111'1111'0000; + + enum class Type : uint8_t { + Undefined, + Point, + Percent, + Number, + Auto, + Keyword + }; + + // Intentionally leaving out auto as a fast path + enum class Keyword : uint8_t { MaxContent, FitContent, Stretch }; + + constexpr bool isKeyword(Keyword keyword) const { + return type() == Type::Keyword && value() == static_cast(keyword); + } + + constexpr Type type() const { + return static_cast(repr_ & kHandleTypeMask); + } + + constexpr void setType(Type handleType) { + repr_ &= (~kHandleTypeMask); + repr_ |= static_cast(handleType); + } + + constexpr uint16_t value() const { + return repr_ >> 4; + } + + constexpr void setValue(uint16_t value) { + repr_ &= (~kHandleValueMask); + repr_ |= (value << 4); + } + + constexpr bool isValueIndexed() const { + return (repr_ & kHandleIndexedMask) != 0; + } + + constexpr void setValueIsIndexed() { + repr_ |= kHandleIndexedMask; + } + + uint16_t repr_{0}; +}; + +#pragma pack(pop) + +} // namespace facebook::yoga diff --git a/yoga/style/StyleValuePool.h b/yoga/style/StyleValuePool.h new file mode 100644 index 0000000000..3257a0a983 --- /dev/null +++ b/yoga/style/StyleValuePool.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * 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 +#include + +namespace facebook::yoga { + +/** + * StyleValuePool allows compact storage for a sparse collection of assigned + * lengths and numbers. Values are referred to using StyleValueHandle. In most + * cases StyleValueHandle can embed the value directly, but if not, the value is + * stored within a buffer provided by the pool. The pool contains a fixed number + * of inline slots before falling back to heap allocating additional slots. + */ +class StyleValuePool { + public: + void store(StyleValueHandle& handle, StyleLength length) { + if (length.isUndefined()) { + handle.setType(StyleValueHandle::Type::Undefined); + } else if (length.isAuto()) { + handle.setType(StyleValueHandle::Type::Auto); + } else { + auto type = length.isPoints() ? StyleValueHandle::Type::Point + : StyleValueHandle::Type::Percent; + storeValue(handle, length.value().unwrap(), type); + } + } + + void store(StyleValueHandle& handle, StyleSizeLength sizeValue) { + if (sizeValue.isUndefined()) { + handle.setType(StyleValueHandle::Type::Undefined); + } else if (sizeValue.isAuto()) { + handle.setType(StyleValueHandle::Type::Auto); + } else if (sizeValue.isMaxContent()) { + storeKeyword(handle, StyleValueHandle::Keyword::MaxContent); + } else if (sizeValue.isStretch()) { + storeKeyword(handle, StyleValueHandle::Keyword::Stretch); + } else if (sizeValue.isFitContent()) { + storeKeyword(handle, StyleValueHandle::Keyword::FitContent); + } else { + auto type = sizeValue.isPoints() ? StyleValueHandle::Type::Point + : StyleValueHandle::Type::Percent; + storeValue(handle, sizeValue.value().unwrap(), type); + } + } + + void store(StyleValueHandle& handle, FloatOptional number) { + if (number.isUndefined()) { + handle.setType(StyleValueHandle::Type::Undefined); + } else { + storeValue(handle, number.unwrap(), StyleValueHandle::Type::Number); + } + } + + StyleLength getLength(StyleValueHandle handle) const { + if (handle.isUndefined()) { + return StyleLength::undefined(); + } else if (handle.isAuto()) { + return StyleLength::ofAuto(); + } else { + assert( + handle.type() == StyleValueHandle::Type::Point || + handle.type() == StyleValueHandle::Type::Percent); + double value = (handle.isValueIndexed()) + ? std::bit_cast(buffer_.get32(handle.value())) + : unpackInlineInteger(handle.value()); + + return handle.type() == StyleValueHandle::Type::Point + ? StyleLength::points(value) + : StyleLength::percent(value); + } + } + + StyleSizeLength getSize(StyleValueHandle handle) const { + if (handle.isUndefined()) { + return StyleSizeLength::undefined(); + } else if (handle.isAuto()) { + return StyleSizeLength::ofAuto(); + } else if (handle.isKeyword(StyleValueHandle::Keyword::MaxContent)) { + return StyleSizeLength::ofMaxContent(); + } else if (handle.isKeyword(StyleValueHandle::Keyword::FitContent)) { + return StyleSizeLength::ofFitContent(); + } else if (handle.isKeyword(StyleValueHandle::Keyword::Stretch)) { + return StyleSizeLength::ofStretch(); + } else { + assert( + handle.type() == StyleValueHandle::Type::Point || + handle.type() == StyleValueHandle::Type::Percent); + double value = (handle.isValueIndexed()) + ? std::bit_cast(buffer_.get32(handle.value())) + : unpackInlineInteger(handle.value()); + + return handle.type() == StyleValueHandle::Type::Point + ? StyleSizeLength::points(value) + : StyleSizeLength::percent(value); + } + } + + FloatOptional getNumber(StyleValueHandle handle) const { + if (handle.isUndefined()) { + return FloatOptional{}; + } else { + assert(handle.type() == StyleValueHandle::Type::Number); + double value = (handle.isValueIndexed()) + ? std::bit_cast(buffer_.get32(handle.value())) + : unpackInlineInteger(handle.value()); + return FloatOptional{value}; + } + } + + private: + void storeValue( + StyleValueHandle& handle, + double value, + StyleValueHandle::Type type) { + handle.setType(type); + + if (handle.isValueIndexed()) { + auto newIndex = + buffer_.replace(handle.value(), std::bit_cast(static_cast(value))); + handle.setValue(newIndex); + } else if (isIntegerPackable(value)) { + handle.setValue(packInlineInteger(value)); + } else { + auto newIndex = buffer_.push(std::bit_cast(static_cast(value))); + handle.setValue(newIndex); + handle.setValueIsIndexed(); + } + } + + void storeKeyword( + StyleValueHandle& handle, + StyleValueHandle::Keyword keyword) { + handle.setType(StyleValueHandle::Type::Keyword); + + if (handle.isValueIndexed()) { + auto newIndex = + buffer_.replace(handle.value(), static_cast(keyword)); + handle.setValue(newIndex); + } else { + handle.setValue(static_cast(keyword)); + } + } + + static constexpr bool isIntegerPackable(double f) { + constexpr uint16_t kMaxInlineAbsValue = (1 << 11) - 1; + + auto i = static_cast(f); + return static_cast(i) == f && i >= -kMaxInlineAbsValue && + i <= +kMaxInlineAbsValue; + } + + static constexpr uint16_t packInlineInteger(double value) { + uint16_t isNegative = value < 0 ? 1 : 0; + return static_cast( + (isNegative << 11) | + (static_cast(value) * (isNegative != 0u ? -1 : 1))); + } + + static constexpr double unpackInlineInteger(uint16_t value) { + constexpr uint16_t kValueSignMask = 0b0000'1000'0000'0000; + constexpr uint16_t kValueMagnitudeMask = 0b0000'0111'1111'1111; + const bool isNegative = (value & kValueSignMask) != 0; + return static_cast( + (value & kValueMagnitudeMask) * (isNegative ? -1 : 1)); + } + + SmallValueBuffer<4> buffer_; +}; + +} // namespace facebook::yoga