diff --git a/.buckconfig b/.buckconfig index 74a40a76..095cc442 100644 --- a/.buckconfig +++ b/.buckconfig @@ -1,2 +1,9 @@ [cxx] gtest_dep = //lib/gtest:gtest +[android] + target = Google Inc.:Google APIs:19 +[ndk] + ndk_version = r10e + compiler = clang + app_platform = android-19 + cpu_abis = armv7, x86 diff --git a/.travis.yml b/.travis.yml index c91c67e5..20306c82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ env: - TARGET=net - TARGET=ios - TARGET=js + - TARGET=android before_install: - brew update @@ -39,7 +40,7 @@ before_install: # iOS - | if [[ $TARGET = "ios" ]]; then - brew upgrade xctool; + brew outdated xctool || brew upgrade xctool; fi # JavaScript @@ -49,13 +50,22 @@ before_install: npm install; fi + # Android + - | + if [[ $TARGET = "android" ]]; then + brew cask install java; + export JAVA_HOME=$(/usr/libexec/java_home -v 1.8); + export PATH=$JAVA_HOME/bin:$PATH; + brew install android-sdk; + fi + script: # C - | if [[ $TARGET = "c" ]]; then - buck test --verbose 0 //:yoga; - buck run --verbose 0 //benchmark:benchmark; - git checkout HEAD^; + buck test --verbose 0 //:yoga && + buck run --verbose 0 //benchmark:benchmark && + git checkout HEAD^ && buck run --verbose 0 //benchmark:benchmark; fi @@ -80,6 +90,12 @@ script: # JavaScript - | if [[ $TARGET = "js" ]]; then - npm run test:all; + npm run test:all && npm run bench; fi + + # Android + - | + if [[ $TARGET = "android" ]]; then + buck build --verbose 0 //android/sample:sample + fi diff --git a/YOGA_DEFS b/YOGA_DEFS index 8d17d58f..bb706632 100644 --- a/YOGA_DEFS +++ b/YOGA_DEFS @@ -1,5 +1,10 @@ +with allow_unsafe_import(): + import os.path +def isdir(filename): + return os.path.isdir(filename) YOGA_ROOT = '//...' +JAVA_TARGET = '//java:java' INFER_ANNOTATIONS_TARGET = '//lib/infer-annotations:infer-annotations' JSR_305_TARGET = '//lib/jsr-305:jsr-305' JUNIT_TARGET = '//lib/junit:junit' @@ -8,6 +13,13 @@ SOLOADER_TARGET = '//lib/soloader:soloader' GTEST_TARGET = '//lib/gtest:gtest' JNI_TARGET = '//lib/jni:jni' FBJNI_TARGET = '//lib/fb:fbjni' +APPCOMPAT_TARGET = '//lib/appcompat:appcompat' +ANDROID_SUPPORT_TARGET = '//lib/android-support:android-support' +ANDROID_TARGET = '//android:android' +ANDROID_JAVA_TARGET = '//android/src/main/java/com/facebook/yoga/android:android' +ANDROID_RES_TARGET = '//android:res' +ANDROID_SAMPLE_JAVA_TARGET = '//android/sample/java/com/facebook/samples/yoga:yoga' +ANDROID_SAMPLE_RES_TARGET = '//android/sample:res' THIS_IS_FBOBJC = False diff --git a/YogaKit/Podfile b/YogaKit/Podfile new file mode 100644 index 00000000..aa58da67 --- /dev/null +++ b/YogaKit/Podfile @@ -0,0 +1,10 @@ +use_frameworks! + +workspace 'YogaKit' + +target 'YogaKit' do + pod 'Yoga', :path => '../Yoga.podspec' +end + +target 'YogaKitTests' do +end diff --git a/YogaKit/Podfile.lock b/YogaKit/Podfile.lock new file mode 100644 index 00000000..334928c1 --- /dev/null +++ b/YogaKit/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - Yoga (1.1.0) + +DEPENDENCIES: + - Yoga (from `../Yoga.podspec`) + +EXTERNAL SOURCES: + Yoga: + :path: ../Yoga.podspec + +SPEC CHECKSUMS: + Yoga: 0bf083b7c485b20598020dbedcea869cbe53071e + +PODFILE CHECKSUM: 975217fee19235295816a081e809454b2ab831b5 + +COCOAPODS: 1.2.0 diff --git a/YogaKit/Source/Info.plist b/YogaKit/Source/Info.plist new file mode 100644 index 00000000..d63d2901 --- /dev/null +++ b/YogaKit/Source/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.1 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/YogaKit/Source/UIView+Yoga.h b/YogaKit/Source/UIView+Yoga.h index e75119c0..0dce4993 100644 --- a/YogaKit/Source/UIView+Yoga.h +++ b/YogaKit/Source/UIView+Yoga.h @@ -26,7 +26,8 @@ typedef void (^YGLayoutConfigurationBlock)(YGLayout *); to your code. If you plan on making multiple changes to YGLayout, it's more performant to use this method, which uses a single objc_msgSend call. */ -- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block NS_SWIFT_NAME(configureLayout(block:)); +- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block + NS_SWIFT_NAME(configureLayout(block:)); @end diff --git a/YogaKit/Source/YGLayout.h b/YogaKit/Source/YGLayout.h index 70a4b015..9d7768be 100644 --- a/YogaKit/Source/YGLayout.h +++ b/YogaKit/Source/YGLayout.h @@ -92,7 +92,8 @@ Perform a layout calculation and update the frames of the views in the hierarchy with the results. If the origin is not preserved, the root view's layout results will applied from {0,0}. */ -- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin NS_SWIFT_NAME(applyLayout(preservingOrigin:)); +- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin + NS_SWIFT_NAME(applyLayout(preservingOrigin:)); /** Returns the size of the view if no constraints were given. This could equivalent to calling [self diff --git a/YogaKit/Source/YGLayout.m b/YogaKit/Source/YGLayout.m index cd62f51a..01f3354f 100644 --- a/YogaKit/Source/YGLayout.m +++ b/YogaKit/Source/YGLayout.m @@ -25,7 +25,7 @@ - (CGFloat)lowercased_name \ { \ YGValue value = YGNodeStyleGet##capitalized_name(self.node); \ - if (value.unit == YGUnitPixel) { \ + if (value.unit == YGUnitPoint) { \ return value.value; \ } else { \ return YGUndefined; \ @@ -57,7 +57,7 @@ YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) - (CGFloat)objc_lowercased_name \ { \ YGValue value = YGNodeStyleGet##c_name(self.node, edge); \ - if (value.unit == YGUnitPixel) { \ + if (value.unit == YGUnitPoint) { \ return value.value; \ } else { \ return YGUndefined; \ diff --git a/YogaKit/Tests/YogaKitTests.m b/YogaKit/Tests/YogaKitTests.m index dca193c4..d3d8cd0f 100644 --- a/YogaKit/Tests/YogaKitTests.m +++ b/YogaKit/Tests/YogaKitTests.m @@ -479,32 +479,32 @@ view.yoga.left = 1; XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).value, 1); - XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint); XCTAssertEqual(view.yoga.left, 1); view.yoga.right = 2; XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).value, 2); - XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeRight).unit, YGUnitPoint); XCTAssertEqual(view.yoga.right, 2); view.yoga.top = 3; XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).value, 3); - XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeTop).unit, YGUnitPoint); XCTAssertEqual(view.yoga.top, 3); view.yoga.bottom = 4; XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).value, 4); - XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint); XCTAssertEqual(view.yoga.bottom, 4); view.yoga.start = 5; XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).value, 5); - XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeStart).unit, YGUnitPoint); XCTAssertEqual(view.yoga.start, 5); view.yoga.end = 6; XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).value, 6); - XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPosition(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint); XCTAssertEqual(view.yoga.end, 6); } @@ -537,32 +537,32 @@ view.yoga.marginLeft = 4; XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).value, 4); - XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint); XCTAssertEqual(view.yoga.marginLeft, 4); view.yoga.marginRight = 5; XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).value, 5); - XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeRight).unit, YGUnitPoint); XCTAssertEqual(view.yoga.marginRight, 5); view.yoga.marginTop = 6; XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).value, 6); - XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeTop).unit, YGUnitPoint); XCTAssertEqual(view.yoga.marginTop, 6); view.yoga.marginBottom = 7; XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).value, 7); - XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint); XCTAssertEqual(view.yoga.marginBottom, 7); view.yoga.marginStart = 8; XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).value, 8); - XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeStart).unit, YGUnitPoint); XCTAssertEqual(view.yoga.marginStart, 8); view.yoga.marginEnd = 9; XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).value, 9); - XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetMargin(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint); XCTAssertEqual(view.yoga.marginEnd, 9); } @@ -595,32 +595,32 @@ view.yoga.paddingLeft = 4; XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).value, 4); - XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeLeft).unit, YGUnitPoint); XCTAssertEqual(view.yoga.paddingLeft, 4); view.yoga.paddingRight = 5; XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).value, 5); - XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeRight).unit, YGUnitPoint); XCTAssertEqual(view.yoga.paddingRight, 5); view.yoga.paddingTop = 6; XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).value, 6); - XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeTop).unit, YGUnitPoint); XCTAssertEqual(view.yoga.paddingTop, 6); view.yoga.paddingBottom = 7; XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).value, 7); - XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeBottom).unit, YGUnitPoint); XCTAssertEqual(view.yoga.paddingBottom, 7); view.yoga.paddingStart = 8; XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).value, 8); - XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeStart).unit, YGUnitPoint); XCTAssertEqual(view.yoga.paddingStart, 8); view.yoga.paddingEnd = 9; XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).value, 9); - XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPixel); + XCTAssertEqual(YGNodeStyleGetPadding(view.yoga.node, YGEdgeEnd).unit, YGUnitPoint); XCTAssertEqual(view.yoga.paddingEnd, 9); } diff --git a/YogaKit/YogaKit.xcodeproj/project.pbxproj b/YogaKit/YogaKit.xcodeproj/project.pbxproj new file mode 100644 index 00000000..73ad1ec0 --- /dev/null +++ b/YogaKit/YogaKit.xcodeproj/project.pbxproj @@ -0,0 +1,545 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 40CA64DD1E52A44B00D4D561 /* YogaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CA64D31E52A44B00D4D561 /* YogaKit.framework */; }; + 40CA64F61E52A4D600D4D561 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 40CA64EF1E52A4D600D4D561 /* Info.plist */; }; + 40CA64F71E52A4D600D4D561 /* UIView+Yoga.h in Headers */ = {isa = PBXBuildFile; fileRef = 40CA64F01E52A4D600D4D561 /* UIView+Yoga.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 40CA64F81E52A4D600D4D561 /* UIView+Yoga.m in Sources */ = {isa = PBXBuildFile; fileRef = 40CA64F11E52A4D600D4D561 /* UIView+Yoga.m */; }; + 40CA64F91E52A4D600D4D561 /* YGLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 40CA64F21E52A4D600D4D561 /* YGLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 40CA64FA1E52A4D600D4D561 /* YGLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 40CA64F31E52A4D600D4D561 /* YGLayout.m */; }; + 40CA64FB1E52A4D700D4D561 /* YGLayout+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40CA64F41E52A4D600D4D561 /* YGLayout+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 40CA65061E52A7DE00D4D561 /* YogaKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 40CA65031E52A77A00D4D561 /* YogaKitTests.m */; }; + 40CA65081E52A7EC00D4D561 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CA65071E52A7EC00D4D561 /* XCTest.framework */; }; + A68EA845309FAAA9D97D9C67 /* Pods_YogaKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C744E7D07F17F21245D4032 /* Pods_YogaKitTests.framework */; }; + AD6227DE33ED68DB8AA0DC66 /* Pods_YogaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3128B1933190022D35CDF27 /* Pods_YogaKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 40CA64DE1E52A44B00D4D561 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 40CA64CA1E52A44B00D4D561 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 40CA64D21E52A44B00D4D561; + remoteInfo = YogaKit; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 40CA64D31E52A44B00D4D561 /* YogaKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = YogaKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 40CA64DC1E52A44B00D4D561 /* YogaKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = YogaKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 40CA64EF1E52A4D600D4D561 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Source/Info.plist; sourceTree = ""; }; + 40CA64F01E52A4D600D4D561 /* UIView+Yoga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+Yoga.h"; path = "Source/UIView+Yoga.h"; sourceTree = ""; }; + 40CA64F11E52A4D600D4D561 /* UIView+Yoga.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+Yoga.m"; path = "Source/UIView+Yoga.m"; sourceTree = ""; }; + 40CA64F21E52A4D600D4D561 /* YGLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YGLayout.h; path = Source/YGLayout.h; sourceTree = ""; }; + 40CA64F31E52A4D600D4D561 /* YGLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YGLayout.m; path = Source/YGLayout.m; sourceTree = ""; }; + 40CA64F41E52A4D600D4D561 /* YGLayout+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "YGLayout+Private.h"; path = "Source/YGLayout+Private.h"; sourceTree = ""; }; + 40CA65021E52A77A00D4D561 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Tests/Info.plist; sourceTree = ""; }; + 40CA65031E52A77A00D4D561 /* YogaKitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YogaKitTests.m; path = Tests/YogaKitTests.m; sourceTree = ""; }; + 40CA65071E52A7EC00D4D561 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 4A1C054B258A44DD6FCC2A0C /* Pods-YogaKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKit/Pods-YogaKit.release.xcconfig"; sourceTree = ""; }; + 88A03BE254575BA580440C33 /* Pods-YogaKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKit/Pods-YogaKit.debug.xcconfig"; sourceTree = ""; }; + 8C744E7D07F17F21245D4032 /* Pods_YogaKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YogaKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B3128B1933190022D35CDF27 /* Pods_YogaKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YogaKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BBC1269AE6773174B034240E /* Pods-YogaKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKitTests/Pods-YogaKitTests.release.xcconfig"; sourceTree = ""; }; + EC740EE390ABE29C24EA2C36 /* Pods-YogaKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-YogaKitTests/Pods-YogaKitTests.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 40CA64CF1E52A44B00D4D561 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AD6227DE33ED68DB8AA0DC66 /* Pods_YogaKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40CA64D91E52A44B00D4D561 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 40CA65081E52A7EC00D4D561 /* XCTest.framework in Frameworks */, + 40CA64DD1E52A44B00D4D561 /* YogaKit.framework in Frameworks */, + A68EA845309FAAA9D97D9C67 /* Pods_YogaKitTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1F50995265E7A8DB75D2FDAE /* Pods */ = { + isa = PBXGroup; + children = ( + 88A03BE254575BA580440C33 /* Pods-YogaKit.debug.xcconfig */, + 4A1C054B258A44DD6FCC2A0C /* Pods-YogaKit.release.xcconfig */, + EC740EE390ABE29C24EA2C36 /* Pods-YogaKitTests.debug.xcconfig */, + BBC1269AE6773174B034240E /* Pods-YogaKitTests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 20F24819CF52E3DDF16C73C2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 40CA65071E52A7EC00D4D561 /* XCTest.framework */, + B3128B1933190022D35CDF27 /* Pods_YogaKit.framework */, + 8C744E7D07F17F21245D4032 /* Pods_YogaKitTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 40CA64C91E52A44B00D4D561 = { + isa = PBXGroup; + children = ( + 40CA65011E52A76A00D4D561 /* Tests */, + 40CA64ED1E52A4C400D4D561 /* Source */, + 40CA64D41E52A44B00D4D561 /* Products */, + 1F50995265E7A8DB75D2FDAE /* Pods */, + 20F24819CF52E3DDF16C73C2 /* Frameworks */, + ); + sourceTree = ""; + }; + 40CA64D41E52A44B00D4D561 /* Products */ = { + isa = PBXGroup; + children = ( + 40CA64D31E52A44B00D4D561 /* YogaKit.framework */, + 40CA64DC1E52A44B00D4D561 /* YogaKitTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 40CA64ED1E52A4C400D4D561 /* Source */ = { + isa = PBXGroup; + children = ( + 40CA64EF1E52A4D600D4D561 /* Info.plist */, + 40CA64F01E52A4D600D4D561 /* UIView+Yoga.h */, + 40CA64F11E52A4D600D4D561 /* UIView+Yoga.m */, + 40CA64F21E52A4D600D4D561 /* YGLayout.h */, + 40CA64F31E52A4D600D4D561 /* YGLayout.m */, + 40CA64F41E52A4D600D4D561 /* YGLayout+Private.h */, + ); + name = Source; + sourceTree = ""; + }; + 40CA65011E52A76A00D4D561 /* Tests */ = { + isa = PBXGroup; + children = ( + 40CA65021E52A77A00D4D561 /* Info.plist */, + 40CA65031E52A77A00D4D561 /* YogaKitTests.m */, + ); + name = Tests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 40CA64D01E52A44B00D4D561 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 40CA64F91E52A4D600D4D561 /* YGLayout.h in Headers */, + 40CA64F71E52A4D600D4D561 /* UIView+Yoga.h in Headers */, + 40CA64FB1E52A4D700D4D561 /* YGLayout+Private.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 40CA64D21E52A44B00D4D561 /* YogaKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40CA64E71E52A44B00D4D561 /* Build configuration list for PBXNativeTarget "YogaKit" */; + buildPhases = ( + 774EA486C1FE628A02A37751 /* [CP] Check Pods Manifest.lock */, + 40CA64CE1E52A44B00D4D561 /* Sources */, + 40CA64CF1E52A44B00D4D561 /* Frameworks */, + 40CA64D01E52A44B00D4D561 /* Headers */, + 40CA64D11E52A44B00D4D561 /* Resources */, + 0CF84C4C17073518BAD7E7C9 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = YogaKit; + productName = YogaKit; + productReference = 40CA64D31E52A44B00D4D561 /* YogaKit.framework */; + productType = "com.apple.product-type.framework"; + }; + 40CA64DB1E52A44B00D4D561 /* YogaKitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 40CA64EA1E52A44B00D4D561 /* Build configuration list for PBXNativeTarget "YogaKitTests" */; + buildPhases = ( + 8AD9D4417D768DFCC0AC73C4 /* [CP] Check Pods Manifest.lock */, + 40CA64D81E52A44B00D4D561 /* Sources */, + 40CA64D91E52A44B00D4D561 /* Frameworks */, + 40CA64DA1E52A44B00D4D561 /* Resources */, + 1C8267EDF21A390122D5377F /* [CP] Embed Pods Frameworks */, + 4FBCFB313146694C1C2FB402 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 40CA64DF1E52A44B00D4D561 /* PBXTargetDependency */, + ); + name = YogaKitTests; + productName = YogaKitTests; + productReference = 40CA64DC1E52A44B00D4D561 /* YogaKitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 40CA64CA1E52A44B00D4D561 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0820; + TargetAttributes = { + 40CA64D21E52A44B00D4D561 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + 40CA64DB1E52A44B00D4D561 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 40CA64CD1E52A44B00D4D561 /* Build configuration list for PBXProject "YogaKit" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 40CA64C91E52A44B00D4D561; + productRefGroup = 40CA64D41E52A44B00D4D561 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 40CA64D21E52A44B00D4D561 /* YogaKit */, + 40CA64DB1E52A44B00D4D561 /* YogaKitTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 40CA64D11E52A44B00D4D561 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40CA64F61E52A4D600D4D561 /* Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40CA64DA1E52A44B00D4D561 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0CF84C4C17073518BAD7E7C9 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-YogaKit/Pods-YogaKit-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 1C8267EDF21A390122D5377F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-YogaKitTests/Pods-YogaKitTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4FBCFB313146694C1C2FB402 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-YogaKitTests/Pods-YogaKitTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 774EA486C1FE628A02A37751 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 8AD9D4417D768DFCC0AC73C4 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 40CA64CE1E52A44B00D4D561 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40CA64F81E52A4D600D4D561 /* UIView+Yoga.m in Sources */, + 40CA64FA1E52A4D600D4D561 /* YGLayout.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40CA64D81E52A44B00D4D561 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 40CA65061E52A7DE00D4D561 /* YogaKitTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 40CA64DF1E52A44B00D4D561 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 40CA64D21E52A44B00D4D561 /* YogaKit */; + targetProxy = 40CA64DE1E52A44B00D4D561 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 40CA64E51E52A44B00D4D561 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 40CA64E61E52A44B00D4D561 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 40CA64E81E52A44B00D4D561 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 88A03BE254575BA580440C33 /* Pods-YogaKit.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Source/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Facebook.YogaKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 40CA64E91E52A44B00D4D561 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4A1C054B258A44DD6FCC2A0C /* Pods-YogaKit.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Source/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Facebook.YogaKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + 40CA64EB1E52A44B00D4D561 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EC740EE390ABE29C24EA2C36 /* Pods-YogaKitTests.debug.xcconfig */; + buildSettings = { + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Facebook.YogaKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 40CA64EC1E52A44B00D4D561 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BBC1269AE6773174B034240E /* Pods-YogaKitTests.release.xcconfig */; + buildSettings = { + INFOPLIST_FILE = Tests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.Facebook.YogaKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 40CA64CD1E52A44B00D4D561 /* Build configuration list for PBXProject "YogaKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40CA64E51E52A44B00D4D561 /* Debug */, + 40CA64E61E52A44B00D4D561 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40CA64E71E52A44B00D4D561 /* Build configuration list for PBXNativeTarget "YogaKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40CA64E81E52A44B00D4D561 /* Debug */, + 40CA64E91E52A44B00D4D561 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 40CA64EA1E52A44B00D4D561 /* Build configuration list for PBXNativeTarget "YogaKitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 40CA64EB1E52A44B00D4D561 /* Debug */, + 40CA64EC1E52A44B00D4D561 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 40CA64CA1E52A44B00D4D561 /* Project object */; +} diff --git a/YogaKit/YogaKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/YogaKit/YogaKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..98dd3194 --- /dev/null +++ b/YogaKit/YogaKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/YogaKit/YogaKit.xcworkspace/contents.xcworkspacedata b/YogaKit/YogaKit.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..8845ada7 --- /dev/null +++ b/YogaKit/YogaKit.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml new file mode 100644 index 00000000..f471999a --- /dev/null +++ b/android/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/android/BUCK b/android/BUCK new file mode 100644 index 00000000..037f3be5 --- /dev/null +++ b/android/BUCK @@ -0,0 +1,36 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//YOGA_DEFS') + +android_aar( + name = 'android', + manifest_skeleton = 'AndroidManifest.xml', + deps = [ + ANDROID_JAVA_TARGET, + ANDROID_RES_TARGET, + INFER_ANNOTATIONS_TARGET, + JAVA_TARGET, + PROGRUARD_ANNOTATIONS_TARGET, + ], + visibility = [ + 'PUBLIC', + ], +) + +android_resource( + name = 'res', + res = 'src/main/res', + package = 'com.facebook.yoga.android', + visibility = [ + 'PUBLIC', + ], +) + +project_config( + src_target = ':android', +) diff --git a/android/sample/AndroidManifest.xml b/android/sample/AndroidManifest.xml new file mode 100644 index 00000000..7e3c5284 --- /dev/null +++ b/android/sample/AndroidManifest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/sample/BUCK b/android/sample/BUCK new file mode 100644 index 00000000..cd8b65cb --- /dev/null +++ b/android/sample/BUCK @@ -0,0 +1,39 @@ +# Copyright 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the license found in the +# LICENSE-examples file in the root directory of this source tree. + +include_defs('//YOGA_DEFS') + +android_binary( + name = 'sample', + manifest = 'AndroidManifest.xml', + keystore = ':debug_keystore', + deps = [ + ANDROID_SAMPLE_JAVA_TARGET, + ANDROID_SAMPLE_RES_TARGET, + ], +) + +android_resource( + name = 'res', + res = 'res', + package = 'com.facebook.samples.yoga', + deps = [ + ANDROID_RES_TARGET, + ], + visibility = [ + 'PUBLIC', + ], +) + +keystore( + name='debug_keystore', + store='debug.keystore', + properties='debug.keystore.properties', +) + +project_config( + src_target = ':sample', +) diff --git a/android/sample/debug.keystore b/android/sample/debug.keystore new file mode 100644 index 00000000..3df12b5d Binary files /dev/null and b/android/sample/debug.keystore differ diff --git a/android/sample/debug.keystore.properties b/android/sample/debug.keystore.properties new file mode 100644 index 00000000..3c06c8e4 --- /dev/null +++ b/android/sample/debug.keystore.properties @@ -0,0 +1,3 @@ +key.alias=androiddebugkey +key.store.password=android +key.alias.password=android diff --git a/android/sample/java/com/facebook/samples/yoga/BUCK b/android/sample/java/com/facebook/samples/yoga/BUCK new file mode 100644 index 00000000..a3f7c717 --- /dev/null +++ b/android/sample/java/com/facebook/samples/yoga/BUCK @@ -0,0 +1,23 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//YOGA_DEFS') + +android_library( + name = 'yoga', + srcs = glob(['**/*.java']), + deps = [ + ANDROID_JAVA_TARGET, + ANDROID_SAMPLE_RES_TARGET, + ANDROID_SUPPORT_TARGET, + APPCOMPAT_TARGET, + SOLOADER_TARGET, + ], + visibility = [ + 'PUBLIC', + ] +) diff --git a/android/sample/java/com/facebook/samples/yoga/MainActivity.java b/android/sample/java/com/facebook/samples/yoga/MainActivity.java new file mode 100644 index 00000000..2c61f3a4 --- /dev/null +++ b/android/sample/java/com/facebook/samples/yoga/MainActivity.java @@ -0,0 +1,32 @@ +/** + * Copyright 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE-examples file in the root directory of this source tree. + */ + +package com.facebook.samples.yoga; + +import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.view.LayoutInflater; + +import com.facebook.samples.yoga.R; +import com.facebook.yoga.android.YogaViewLayoutFactory; + +/** + * An activity to show off Yoga in Android. This activity shows a simple layout (defined in + * {@code main_layout.xml}) that shows off the awesome functionality of the Yoga layout engine + * as well as some optimisations on layout systems that it facilitates. + */ +public class MainActivity extends ActionBarActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance()); + super.onCreate(savedInstanceState); + + setContentView(R.layout.main_layout); + } +} diff --git a/android/sample/java/com/facebook/samples/yoga/SplashScreenActivity.java b/android/sample/java/com/facebook/samples/yoga/SplashScreenActivity.java new file mode 100644 index 00000000..6905d687 --- /dev/null +++ b/android/sample/java/com/facebook/samples/yoga/SplashScreenActivity.java @@ -0,0 +1,50 @@ +/** + * Copyright 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE-examples file in the root directory of this source tree. + */ + +package com.facebook.samples.yoga; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.support.v7.app.ActionBarActivity; +import android.view.LayoutInflater; + +import com.facebook.samples.yoga.R; +import com.facebook.soloader.SoLoader; +import com.facebook.yoga.android.YogaViewLayoutFactory; + +/** + * A (non-interactive) splash screen. Displays for two seconds before calling the main activity. + */ +public class SplashScreenActivity extends ActionBarActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + LayoutInflater.from(this).setFactory(YogaViewLayoutFactory.getInstance()); + super.onCreate(savedInstanceState); + SoLoader.init(this, false); + + setContentView(R.layout.splash_layout); + + new Handler(Looper.getMainLooper()).postDelayed( + new Runnable() { + @Override + public void run() { + startMainActivity(); + } + }, + 2000); + } + + private void startMainActivity() { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + this.finish(); + } +} diff --git a/android/sample/res/drawable/action_bar_background.xml b/android/sample/res/drawable/action_bar_background.xml new file mode 100644 index 00000000..6c70b26b --- /dev/null +++ b/android/sample/res/drawable/action_bar_background.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/android/sample/res/drawable/ic_launcher.png b/android/sample/res/drawable/ic_launcher.png new file mode 100644 index 00000000..c99f9812 Binary files /dev/null and b/android/sample/res/drawable/ic_launcher.png differ diff --git a/android/sample/res/drawable/sample_children_background.xml b/android/sample/res/drawable/sample_children_background.xml new file mode 100644 index 00000000..8d63336a --- /dev/null +++ b/android/sample/res/drawable/sample_children_background.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/android/sample/res/layout/main_layout.xml b/android/sample/res/layout/main_layout.xml new file mode 100644 index 00000000..295a3a68 --- /dev/null +++ b/android/sample/res/layout/main_layout.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/sample/res/layout/splash_layout.xml b/android/sample/res/layout/splash_layout.xml new file mode 100644 index 00000000..051276ca --- /dev/null +++ b/android/sample/res/layout/splash_layout.xml @@ -0,0 +1,27 @@ + + + + + + + diff --git a/android/sample/res/values/colors.xml b/android/sample/res/values/colors.xml new file mode 100644 index 00000000..e1a99a61 --- /dev/null +++ b/android/sample/res/values/colors.xml @@ -0,0 +1,20 @@ + + + + + + + #FF303846 + #FF97DCCF + + #FFFFFFFF + #665890ff + #FF23355b + + diff --git a/android/sample/res/values/strings.xml b/android/sample/res/values/strings.xml new file mode 100644 index 00000000..8b884c57 --- /dev/null +++ b/android/sample/res/values/strings.xml @@ -0,0 +1,33 @@ + + + + + + Yoga + Hello. I am Yoga! + I am a layout engine! + I run natively. + So I\'m fast. + Who are you? + diff --git a/android/sample/res/values/styles.xml b/android/sample/res/values/styles.xml new file mode 100644 index 00000000..0276b8df --- /dev/null +++ b/android/sample/res/values/styles.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/android/src/main/java/com/facebook/yoga/android/BUCK b/android/src/main/java/com/facebook/yoga/android/BUCK new file mode 100644 index 00000000..07cdd110 --- /dev/null +++ b/android/src/main/java/com/facebook/yoga/android/BUCK @@ -0,0 +1,23 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//YOGA_DEFS') + +android_library( + name = 'android', + srcs = glob(['**/*.java']), + deps = [ + ANDROID_RES_TARGET, + INFER_ANNOTATIONS_TARGET, + JAVA_TARGET, + JSR_305_TARGET, + SOLOADER_TARGET, + ], + visibility = [ + 'PUBLIC', + ] +) diff --git a/android/src/main/java/com/facebook/yoga/android/VirtualYogaLayout.java b/android/src/main/java/com/facebook/yoga/android/VirtualYogaLayout.java new file mode 100644 index 00000000..fe8d2cdf --- /dev/null +++ b/android/src/main/java/com/facebook/yoga/android/VirtualYogaLayout.java @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.yoga.android; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +import com.facebook.yoga.YogaNode; + +/** + * Much like a {@link YogaLayout}, except this class does not render itself (the container) to the + * screen. As a result, do not use this if you wish the container to have a background or + * foreground. However, all of its children will still render as expected. + * + *

+ * In practice, this class never added to the View tree, and all its children become children of its + * parent. As a result, all the layout (such as the traversal of the tree) is performed by Yoga + * (and so natively) increasing performance. + */ +public class VirtualYogaLayout extends ViewGroup { + + final private List mChildren = new LinkedList<>(); + final private Map mYogaNodes = new HashMap<>(); + final private YogaNode mYogaNode = new YogaNode(); + + public VirtualYogaLayout(Context context) { + super(context); + } + + public VirtualYogaLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public VirtualYogaLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(context, attrs); + YogaLayout.applyLayoutParams(lp, mYogaNode, this); + } + + public YogaNode getYogaNode() { + return mYogaNode; + } + + /** + * Called to add a view, creating a new yoga node for it and adding that yoga node to the parent. + * If the child is a {@link VirtualYogaLayout}, we simply transfer all its children to this one + * in a manner that maintains the tree, and add its root to the tree. + * + * @param child the View to add + * @param index the position at which to add it (ignored) + * @param params the layout parameters to apply + */ + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + if (child instanceof VirtualYogaLayout) { + ((VirtualYogaLayout) child).transferChildren(this); + + final YogaNode childNode = ((VirtualYogaLayout) child).getYogaNode(); + mYogaNode.addChildAt(childNode, mYogaNode.getChildCount()); + + return; + } + + YogaNode node = new YogaNode(); + YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(params); + YogaLayout.applyLayoutParams(lp, node, child); + node.setData(child); + node.setMeasureFunction(new YogaLayout.ViewMeasureFunction()); + + mYogaNode.addChildAt(node, mYogaNode.getChildCount()); + + addView(child, node); + } + + /** + * Called to add a view with a corresponding node, but not to change the Yoga tree in any way. + * + * @param child the View to add + * @param node the corresponding yoga node + */ + public void addView(View child, YogaNode node) { + mChildren.add(child); + mYogaNodes.put(child, node); + } + + /** + * Gives up children {@code View}s to the parent, maintaining the Yoga tree. This function calls + * {@link YogaLayout#addView(View, YogaNode)} or {@link VirtualYogaLayout#addView(View, YogaNode)} + * on the parent to add the {@code View} without generating new yoga nodes. + * + * @param parent the parent to pass children to (must be a YogaLayout or a VirtualYogaLayout) + */ + protected void transferChildren(ViewGroup parent) { + if (parent instanceof VirtualYogaLayout) { + for (View child : mChildren) { + ((VirtualYogaLayout) parent).addView(child, mYogaNodes.get(child)); + } + } else if (parent instanceof YogaLayout) { + for (View child : mChildren) { + ((YogaLayout) parent).addView(child, mYogaNodes.get(child)); + } + } else { + throw new RuntimeException("VirtualYogaLayout cannot transfer children to ViewGroup of type " + +parent.getClass().getCanonicalName()+". Must either be a VirtualYogaLayout or a " + + "YogaLayout."); + } + mChildren.clear(); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + throw new RuntimeException("Attempting to layout a VirtualYogaLayout"); + } + + @Override + public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new YogaLayout.LayoutParams(getContext(), attrs); + } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + return new YogaLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + } + + @Override + protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + return new YogaLayout.LayoutParams(p); + } + + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof YogaLayout.LayoutParams; + } +} diff --git a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java new file mode 100644 index 00000000..52607944 --- /dev/null +++ b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java @@ -0,0 +1,737 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.yoga.android; + +import java.util.HashMap; +import java.util.Map; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; + +import com.facebook.yoga.android.R; +import com.facebook.yoga.YogaAlign; +import com.facebook.yoga.YogaConstants; +import com.facebook.yoga.YogaDirection; +import com.facebook.yoga.YogaEdge; +import com.facebook.yoga.YogaFlexDirection; +import com.facebook.yoga.YogaJustify; +import com.facebook.yoga.YogaMeasureFunction; +import com.facebook.yoga.YogaMeasureMode; +import com.facebook.yoga.YogaMeasureOutput; +import com.facebook.yoga.YogaNode; +import com.facebook.yoga.YogaNodeAPI; +import com.facebook.yoga.YogaOverflow; +import com.facebook.yoga.YogaPositionType; +import com.facebook.yoga.YogaWrap; + +/** + * A {@code ViewGroup} based on the Yoga layout engine. + * + *

+ * This class is designed to be as "plug and play" as possible. That is, you can use it in XML + * like this (note: to use {@code YogaLayout} you need to use the {@link YogaViewLayoutFactory}): + *

+ *

{@code
+ * 
+ *     
+ * 
+ * }
+ * + * Under the hood, all views added to this {@code ViewGroup} are laid out using flexbox rules + * and the Yoga engine. + */ +public class YogaLayout extends ViewGroup { + private final Map mYogaNodes; + private final YogaNode mYogaNode; + + public YogaLayout(Context context) { + this(context, null, 0); + } + + public YogaLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public YogaLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + mYogaNode = new YogaNode(); + mYogaNodes = new HashMap<>(); + + mYogaNode.setData(this); + mYogaNode.setMeasureFunction(new ViewMeasureFunction()); + + final LayoutParams layoutParams = new LayoutParams(context, attrs); + applyLayoutParams(layoutParams, mYogaNode, this); + } + + YogaNode getYogaNode() { + return mYogaNode; + } + + YogaNode getYogaNodeForView(View view) { + return mYogaNodes.get(view); + } + + /** + * Adds a child view with the specified layout parameters. + * + * In the typical View is added, this constructs a {@code YogaNode} for this child and applies all + * the {@code yoga:*} attributes. The Toga node is added to the Yoga tree and the child is added + * to this ViewGroup. + * + * If the child is a {@link YogaLayout} itself, we do not construct a new Yoga node for that + * child, but use its root node instead. + * + * If the child is a {@link VirtualYogaLayout}, we also use its Yoga node, but we also instruct it + * to transfer all of its children to this {@link YogaLayout} while preserving the Yoga tree (so + * that the layout of its children is correct). The {@link VirtualYogaLayout} is then not added + * to the View hierarchy. + * + *

Note: do not invoke this method from + * {@code #draw(android.graphics.Canvas)}, {@code onDraw(android.graphics.Canvas)}, + * {@code #dispatchDraw(android.graphics.Canvas)} or any related method.

+ * + * @param child the child view to add + * @param index the position at which to add the child or -1 to add last + * @param params the layout parameters to set on the child + */ + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + // Internal nodes (which this is now) cannot have measure functions + mYogaNode.setMeasureFunction(null); + + if (child instanceof VirtualYogaLayout) { + ((VirtualYogaLayout) child).transferChildren(this); + final YogaNode childNode = ((VirtualYogaLayout) child).getYogaNode(); + + mYogaNode.addChildAt(childNode, mYogaNode.getChildCount()); + + return; + } + + super.addView(child, index, params); + + // It is possible that addView is being called as part of a transferal of children, in which + // case we already know about the YogaNode and only need the Android View tree to be aware + // that we now own this child. If so, we don't need to do anything further + if (mYogaNodes.containsKey(child)) { + return; + } + + YogaNode childNode; + + if (child instanceof YogaLayout) { + childNode = ((YogaLayout) child).getYogaNode(); + } else { + childNode = new YogaNode(); + + childNode.setData(child); + childNode.setMeasureFunction(new ViewMeasureFunction()); + } + + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + applyLayoutParams(lp, childNode, child); + + mYogaNodes.put(child, childNode); + mYogaNode.addChildAt(childNode, mYogaNode.getChildCount()); + } + + /** + * Adds a view to this {@code ViewGroup} with an already given {@code YogaNode}. Use + * this function if you already have a Yoga node (and perhaps tree) associated with the view you + * are adding, that you would like to preserve. + * + * @param child The view to add + * @param node The Yoga node belonging to the view + */ + public void addView(View child, YogaNode node) { + mYogaNodes.put(child, node); + addView(child); + } + + @Override + public void removeView(View view) { + removeViewFromYogaTree(view, false); + super.removeView(view); + } + + @Override + public void removeViewAt(int index) { + removeViewFromYogaTree(getChildAt(index), false); + super.removeViewAt(index); + } + + @Override + public void removeViewInLayout(View view) { + removeViewFromYogaTree(view, true); + super.removeViewInLayout(view); + } + + @Override + public void removeViews(int start, int count) { + for (int i = start; i < start + count; i++) { + removeViewFromYogaTree(getChildAt(i), false); + } + super.removeViews(start, count); + } + + @Override + public void removeViewsInLayout(int start, int count) { + for (int i = start; i < start + count; i++) { + removeViewFromYogaTree(getChildAt(i), true); + } + super.removeViewsInLayout(start, count); + } + + @Override + public void removeAllViews() { + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + removeViewFromYogaTree(getChildAt(i), false); + } + super.removeAllViews(); + } + + @Override + public void removeAllViewsInLayout() { + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + removeViewFromYogaTree(getChildAt(i), true); + } + super.removeAllViewsInLayout(); + } + + private void removeViewFromYogaTree(View view, boolean inLayout) { + final YogaNode node = mYogaNodes.get(view); + if (node == null) { + return; + } + + final YogaNode parent = node.getParent(); + + for (int i = 0; i < parent.getChildCount(); i++) { + if (parent.getChildAt(i).equals(node)) { + parent.removeChildAt(i); + break; + } + } + + node.setData(null); + mYogaNodes.remove(view); + + if (inLayout) { + mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + } + } + + private void applyLayoutRecursive(YogaNode node, float xOffset, float yOffset) { + View view = (View) node.getData(); + if (view != null && view != this) { + if (view.getVisibility() == GONE) { + return; + } + view.layout( + Math.round(xOffset + node.getLayoutX()), + Math.round(yOffset + node.getLayoutY()), + Math.round(xOffset + node.getLayoutX() + node.getLayoutWidth()), + Math.round(yOffset + node.getLayoutY() + node.getLayoutHeight())); + } + + final int childrenCount = node.getChildCount(); + for (int i = 0; i < childrenCount; i++) { + if (this.equals(view)) { + applyLayoutRecursive(node.getChildAt(i), xOffset, yOffset); + } else if (view instanceof YogaLayout) { + continue; + } else { + applyLayoutRecursive( + node.getChildAt(i), + xOffset + node.getLayoutX(), + yOffset + node.getLayoutY()); + } + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + // Either we are a root of a tree, or this function is called by our parent's onLayout, in which + // case our r-l and b-t are the size of our node. + if (!(getParent() instanceof YogaLayout)) { + createLayout( + MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(b - t, MeasureSpec.EXACTLY)); + } + + applyLayoutRecursive(mYogaNode, 0, 0); + } + + /** + * This function is mostly unneeded, because Yoga is doing the measuring. Hence we only need to + * return accurate results if we are the root. + * + * @param widthMeasureSpec the suggested specification for the width + * @param heightMeasureSpec the suggested specification for the height + */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (!(getParent() instanceof YogaLayout)) { + createLayout(widthMeasureSpec, heightMeasureSpec); + } + + setMeasuredDimension( + Math.round(mYogaNode.getLayoutWidth()), + Math.round(mYogaNode.getLayoutHeight())); + } + + private void createLayout(int widthMeasureSpec, int heightMeasureSpec) { + final int widthSize = MeasureSpec.getSize(widthMeasureSpec); + final int heightSize = MeasureSpec.getSize(heightMeasureSpec); + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + + if (heightMode == MeasureSpec.EXACTLY) { + mYogaNode.setHeight(heightSize); + } + if (widthMode == MeasureSpec.EXACTLY) { + mYogaNode.setWidth(widthSize); + } + if (heightMode == MeasureSpec.AT_MOST) { + mYogaNode.setMaxHeight(heightSize); + } + if (widthMode == MeasureSpec.AT_MOST) { + mYogaNode.setMaxWidth(widthSize); + } + + mYogaNode.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + } + + /** + * Applies the layout parameters to the YogaNode. That is, this function is a translator from + * {@code yoga:X="Y"} to {@code yogaNode.setX(Y);}, with some reasonable defaults. + * + *

+ * If the SDK version is high enough, and the {@code yoga:direction} is not set on + * the component, the direction (LTR or RTL) is set according to the locale. + * + *

+ * The attributes {@code padding_top}, {@code padding_right} etc. default to those of the view's + * drawable background, if it has one. + * + * @param layoutParameters The source set of params + * @param node The destination node + */ + protected static void applyLayoutParams(LayoutParams layoutParameters, YogaNode node, View view) { + // JELLY_BEAN_MR1 (17) is the first version supporting getLayoutDirection() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + Configuration configuration = view.getResources().getConfiguration(); + if (configuration.getLayoutDirection() == LAYOUT_DIRECTION_RTL) { + node.setDirection(YogaDirection.RTL); + } + } + + Drawable background = view.getBackground(); + if (background != null) { + final Rect backgroundPadding = new Rect(); + if (background.getPadding(backgroundPadding)) { + node.setPadding(YogaEdge.LEFT, backgroundPadding.left); + node.setPadding(YogaEdge.TOP, backgroundPadding.top); + node.setPadding(YogaEdge.RIGHT, backgroundPadding.right); + node.setPadding(YogaEdge.BOTTOM, backgroundPadding.bottom); + } + } + + for (int i = 0; i < layoutParameters.attributes.size(); i++) { + final int attribute = layoutParameters.attributes.keyAt(i); + final float value = layoutParameters.attributes.valueAt(i); + + if (attribute == R.styleable.yoga_align_content) { + node.setAlignContent(YogaAlign.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_align_items) { + node.setAlignItems(YogaAlign.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_align_self) { + node.setAlignSelf(YogaAlign.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_aspect_ratio) { + node.setAspectRatio(value); + } else if (attribute == R.styleable.yoga_border_left) { + node.setBorder(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_border_top) { + node.setBorder(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_border_right) { + node.setBorder(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_border_bottom) { + node.setBorder(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_border_start) { + node.setBorder(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_border_end) { + node.setBorder(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_border_horizontal) { + node.setBorder(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_border_vertical) { + node.setBorder(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_border_all) { + node.setBorder(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_direction) { + node.setDirection(YogaDirection.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_flex) { + node.setFlex(value); + } else if (attribute == R.styleable.yoga_flex_basis) { + node.setFlexBasis(value); + } else if (attribute == R.styleable.yoga_flex_basis_percent) { + node.setFlexBasisPercent(value); + } else if (attribute == R.styleable.yoga_flex_direction) { + node.setFlexDirection(YogaFlexDirection.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_flex_grow) { + node.setFlexGrow(value); + } else if (attribute == R.styleable.yoga_flex_shrink) { + node.setFlexShrink(value); + } else if (attribute == R.styleable.yoga_height) { + node.setHeight(value); + } else if (attribute == R.styleable.yoga_height_percent) { + node.setHeightPercent(value); + } else if (attribute == R.styleable.yoga_margin_left) { + node.setMargin(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_justify_content) { + node.setJustifyContent(YogaJustify.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_margin_top) { + node.setMargin(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_margin_right) { + node.setMargin(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_margin_bottom) { + node.setMargin(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_margin_start) { + node.setMargin(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_margin_end) { + node.setMargin(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_margin_horizontal) { + node.setMargin(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_margin_vertical) { + node.setMargin(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_margin_all) { + node.setMargin(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_margin_percent_left) { + node.setMarginPercent(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_margin_percent_top) { + node.setMarginPercent(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_margin_percent_right) { + node.setMarginPercent(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_margin_percent_bottom) { + node.setMarginPercent(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_margin_percent_start) { + node.setMarginPercent(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_margin_percent_end) { + node.setMarginPercent(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_margin_percent_horizontal) { + node.setMarginPercent(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_margin_percent_vertical) { + node.setMarginPercent(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_margin_percent_all) { + node.setMarginPercent(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_max_height) { + node.setMaxHeight(value); + } else if (attribute == R.styleable.yoga_max_height_percent) { + node.setMaxHeightPercent(value); + } else if (attribute == R.styleable.yoga_max_width) { + node.setMaxWidth(value); + } else if (attribute == R.styleable.yoga_max_width_percent) { + node.setMaxWidthPercent(value); + } else if (attribute == R.styleable.yoga_min_height) { + node.setMinHeight(value); + } else if (attribute == R.styleable.yoga_min_height_percent) { + node.setMinHeightPercent(value); + } else if (attribute == R.styleable.yoga_min_width) { + node.setMinWidth(value); + } else if (attribute == R.styleable.yoga_min_width_percent) { + node.setMinWidthPercent(value); + } else if (attribute == R.styleable.yoga_overflow) { + node.setOverflow(YogaOverflow.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_padding_left) { + node.setPadding(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_padding_top) { + node.setPadding(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_padding_right) { + node.setPadding(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_padding_bottom) { + node.setPadding(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_padding_start) { + node.setPadding(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_padding_end) { + node.setPadding(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_padding_horizontal) { + node.setPadding(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_padding_vertical) { + node.setPadding(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_padding_all) { + node.setPadding(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_padding_percent_left) { + node.setPaddingPercent(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_padding_percent_top) { + node.setPaddingPercent(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_padding_percent_right) { + node.setPaddingPercent(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_padding_percent_bottom) { + node.setPaddingPercent(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_padding_percent_start) { + node.setPaddingPercent(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_padding_percent_end) { + node.setPaddingPercent(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_padding_percent_horizontal) { + node.setPaddingPercent(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_padding_percent_vertical) { + node.setPaddingPercent(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_padding_percent_all) { + node.setPaddingPercent(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_position_left) { + node.setPosition(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_position_top) { + node.setPosition(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_position_right) { + node.setPosition(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_position_bottom) { + node.setPosition(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_position_start) { + node.setPosition(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_position_end) { + node.setPosition(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_position_horizontal) { + node.setPosition(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_position_vertical) { + node.setPosition(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_position_all) { + node.setPosition(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_position_percent_left) { + node.setPositionPercent(YogaEdge.LEFT, value); + } else if (attribute == R.styleable.yoga_position_percent_top) { + node.setPositionPercent(YogaEdge.TOP, value); + } else if (attribute == R.styleable.yoga_position_percent_right) { + node.setPositionPercent(YogaEdge.RIGHT, value); + } else if (attribute == R.styleable.yoga_position_percent_bottom) { + node.setPositionPercent(YogaEdge.BOTTOM, value); + } else if (attribute == R.styleable.yoga_position_percent_start) { + node.setPositionPercent(YogaEdge.START, value); + } else if (attribute == R.styleable.yoga_position_percent_end) { + node.setPositionPercent(YogaEdge.END, value); + } else if (attribute == R.styleable.yoga_position_percent_horizontal) { + node.setPositionPercent(YogaEdge.HORIZONTAL, value); + } else if (attribute == R.styleable.yoga_position_percent_vertical) { + node.setPositionPercent(YogaEdge.VERTICAL, value); + } else if (attribute == R.styleable.yoga_position_percent_all) { + node.setPositionPercent(YogaEdge.ALL, value); + } else if (attribute == R.styleable.yoga_position_type) { + node.setPositionType(YogaPositionType.fromInt(Math.round(value))); + } else if (attribute == R.styleable.yoga_width) { + node.setWidth(value); + } else if (attribute == R.styleable.yoga_width_percent) { + node.setWidthPercent(value); + } else if (attribute == R.styleable.yoga_wrap) { + node.setWrap(YogaWrap.fromInt(Math.round(value))); + } + } + } + + @Override + public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { + return new YogaLayout.LayoutParams(getContext(), attrs); + } + + @Override + protected ViewGroup.LayoutParams generateDefaultLayoutParams() { + return new YogaLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + } + + @Override + protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + return new YogaLayout.LayoutParams(p); + } + + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof LayoutParams; + } + + /** + * {@code YogaLayout.LayoutParams} are used by views to tell {@link YogaLayout} how they want to + * be laid out. More precisely, the specify the yoga parameters of the view. + * + *

+ * This is actually mostly a wrapper around a {@code SparseArray} that holds a mapping between + * styleable id's ({@code R.styleable.yoga_*}) and the float of their values. In cases where the + * value is an enum or an integer, they should first be cast to int (with rounding) before using. + */ + public static class LayoutParams extends ViewGroup.LayoutParams { + + /** + * A mapping from attribute keys ({@code R.styleable.yoga_*}) to the float of their values. + * For attributes like position_percent_left (float), this is the native type. For attributes + * like align_self (enums), the integer enum value is cast (rounding is used on the other side + * to prevent precision errors). Dimension attributes are stored as float pixels. + */ + SparseArray attributes; + + /** + * Constructs a set of layout params from a source set. In the case that the source set is + * actually a {@link YogaLayout.LayoutParams}, we can copy all the yoga attributes. Otherwise + * we start with a blank slate. + * + * @param source The layout params to copy from + */ + public LayoutParams(ViewGroup.LayoutParams source) { + super(source); + if (source instanceof LayoutParams) { + attributes = ((LayoutParams) source).attributes.clone(); + } else { + attributes = new SparseArray<>(); + + // Negative values include MATCH_PARENT and WRAP_CONTENT + if (source.width >= 0) { + attributes.put(R.styleable.yoga_width, (float) width); + } + if (source.height >= 0) { + attributes.put(R.styleable.yoga_height, (float) height); + } + } + } + + /** + * Constructs a set of layout params, given width and height specs. In this case, we can set + * the {@code yoga:width} and {@code yoga:height} if we are given them explicitly. If other + * options (such as {@code match_parent} or {@code wrap_content} are given, then the parent + * LayoutParams will store them, and we deal with them during layout. (see + * {@link YogaLayout#createLayout}) + * + * @param width the requested width, either a pixel size, {@code WRAP_CONTENT} or + * {@code MATCH_PARENT}. + * @param height the requested height, either a pixel size, {@code WRAP_CONTENT} or + * {@code MATCH_PARENT}. + */ + public LayoutParams(int width, int height) { + super(width, height); + attributes = new SparseArray<>(); + // Negative values include MATCH_PARENT and WRAP_CONTENT + if (width >= 0) { + attributes.put(R.styleable.yoga_width, (float) width); + } + if (height >= 0) { + attributes.put(R.styleable.yoga_height, (float) height); + } + } + + /** + * Constructs a set of layout params, given attributes. Grabs all the {@code yoga:*} + * defined in {@code ALL_YOGA_ATTRIBUTES} and collects the ones that are set in {@code attrs}. + * + * @param context the application environment + * @param attrs the set of attributes from which to extract the yoga specific attributes + */ + public LayoutParams(Context context, AttributeSet attrs) { + super(context, attrs); + attributes = new SparseArray<>(); + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.yoga); + + // Negative values include MATCH_PARENT and WRAP_CONTENT + if (width >= 0) { + attributes.put(R.styleable.yoga_width, (float) width); + } + if (height >= 0) { + attributes.put(R.styleable.yoga_height, (float) height); + } + + final int attributeCount = a.getIndexCount(); + for (int i = 0; i < attributeCount; i++) { + final int attribute = a.getIndex(i); + final TypedValue val = new TypedValue(); + a.getValue(attribute, val); + + if (val.type == TypedValue.TYPE_DIMENSION) { + attributes.put( + attribute, + (float) a.getDimensionPixelSize(attribute, 0)); + } else { + attributes.put(attribute, a.getFloat(attribute, 0)); + } + } + a.recycle(); + } + } + + /** + * Wrapper around measure function for yoga leaves. + */ + public static class ViewMeasureFunction implements YogaMeasureFunction { + + /** + * A function to measure leaves of the Yoga tree. Yoga needs some way to know how large + * elements want to be. This function passes that question directly through to the relevant + * {@code View}'s measure function. + * + * @param node The yoga node to measure + * @param width The suggested width from the parent + * @param widthMode The type of suggestion for the width + * @param height The suggested height from the parent + * @param heightMode The type of suggestion for the height + * @return A measurement output ({@code YogaMeasureOutput}) for the node + */ + public long measure( + YogaNodeAPI node, + float width, + YogaMeasureMode widthMode, + float height, + YogaMeasureMode heightMode) { + final View view = (View) node.getData(); + if (view == null || view instanceof YogaLayout) { + return YogaMeasureOutput.make(0, 0); + } + + final int widthMeasureSpec = MeasureSpec.makeMeasureSpec( + (int) width, + viewMeasureSpecFromYogaMeasureMode(widthMode)); + final int heightMeasureSpec = MeasureSpec.makeMeasureSpec( + (int) height, + viewMeasureSpecFromYogaMeasureMode(heightMode)); + + view.measure(widthMeasureSpec, heightMeasureSpec); + + return YogaMeasureOutput.make(view.getMeasuredWidth(), view.getMeasuredHeight()); + } + + private int viewMeasureSpecFromYogaMeasureMode(YogaMeasureMode mode) { + if (mode == YogaMeasureMode.AT_MOST) { + return MeasureSpec.AT_MOST; + } else if (mode == YogaMeasureMode.EXACTLY) { + return MeasureSpec.EXACTLY; + } else { + return MeasureSpec.UNSPECIFIED; + } + } + } +} diff --git a/android/src/main/java/com/facebook/yoga/android/YogaViewLayoutFactory.java b/android/src/main/java/com/facebook/yoga/android/YogaViewLayoutFactory.java new file mode 100644 index 00000000..e315ba78 --- /dev/null +++ b/android/src/main/java/com/facebook/yoga/android/YogaViewLayoutFactory.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.yoga.android; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; + +/** + * A layout inflater factory. This provides our custom {@link YogaViewLayoutFactory#onCreateView} + * to the XML inflation system, allowing us to replace XML tags. + */ +public class YogaViewLayoutFactory implements LayoutInflater.Factory { + private static YogaViewLayoutFactory sYogaViewLayoutFactory; + + /** + * Obtains (and initialises if necessary) the singleton {@link YogaViewLayoutFactory}. + * + * @return The singleton instance + */ + public static YogaViewLayoutFactory getInstance() { + if (sYogaViewLayoutFactory == null) { + sYogaViewLayoutFactory = new YogaViewLayoutFactory(); + } + return sYogaViewLayoutFactory; + } + + YogaViewLayoutFactory() {} + + /** + * Hook for inflating from a LayoutInflater. This hook replaces the cumbersome + * {@code com.facebook.etc.YogaLayout} with simply {@code YogaLayout} in your XML and the same + * with {@code VirtualYogaLayout}. + * + * @param name Tag name to be inflated. + * @param context The context the view is being created in. + * @param attrs Inflation attributes as specified in XML file. + * + * @return View Newly created view. Return null for the default behavior. + */ + @Override + public View onCreateView(String name, Context context, AttributeSet attrs) { + if (YogaLayout.class.getSimpleName().equals(name)) { + return new YogaLayout(context, attrs); + } + if (VirtualYogaLayout.class.getSimpleName().equals(name)) { + return new VirtualYogaLayout(context, attrs); + } + return null; + } +} diff --git a/android/src/main/res/values/attrs.xml b/android/src/main/res/values/attrs.xml new file mode 100644 index 00000000..61c8c643 --- /dev/null +++ b/android/src/main/res/values/attrs.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/csharp/BUCK b/csharp/BUCK index 29e2e6d2..de1e9a39 100644 --- a/csharp/BUCK +++ b/csharp/BUCK @@ -6,6 +6,7 @@ # of patent rights can be found in the PATENTS file in the same directory. include_defs('//YOGA_DEFS') +include_defs('xplat//configurations/buck/py_sdk') COMPILER_FLAGS = BASE_COMPILER_FLAGS + ['-std=c++11'] @@ -34,10 +35,7 @@ cxx_library( visibility = ['PUBLIC'], ) -with allow_unsafe_import(): - import os - -if os.path.isdir('/Applications/Xcode.app'): +if isdir('/Applications/Xcode.app'): yoganet_ios_srcs = [] for arch in [ 'iphonesimulator-x86_64', 'iphonesimulator-i386', 'iphoneos-arm64', 'iphoneos-armv7' diff --git a/csharp/Facebook.Yoga/Native.cs b/csharp/Facebook.Yoga/Native.cs index 2c0d25ac..2f98b960 100644 --- a/csharp/Facebook.Yoga/Native.cs +++ b/csharp/Facebook.Yoga/Native.cs @@ -196,6 +196,9 @@ namespace Facebook.Yoga [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetFlexBasisPercent(YGNodeHandle node, float flexBasis); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern void YGNodeStyleSetFlexBasisAuto(YGNodeHandle node); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern YogaValue YGNodeStyleGetFlexBasis(YGNodeHandle node); @@ -205,6 +208,9 @@ namespace Facebook.Yoga [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetWidthPercent(YGNodeHandle node, float width); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern void YGNodeStyleSetWidthAuto(YGNodeHandle node); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern YogaValue YGNodeStyleGetWidth(YGNodeHandle node); @@ -213,6 +219,9 @@ namespace Facebook.Yoga [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetHeightPercent(YGNodeHandle node, float height); + + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern void YGNodeStyleSetHeightAuto(YGNodeHandle node); [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern YogaValue YGNodeStyleGetHeight(YGNodeHandle node); @@ -278,6 +287,9 @@ namespace Facebook.Yoga [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void YGNodeStyleSetMarginPercent(YGNodeHandle node, YogaEdge edge, float margin); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + public static extern void YGNodeStyleSetMarginAuto(YGNodeHandle node, YogaEdge edge); + [DllImport(DllName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern YogaValue YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge); diff --git a/csharp/Facebook.Yoga/YogaNode.Spacing.cs b/csharp/Facebook.Yoga/YogaNode.Spacing.cs index e858a4f1..f078f0f0 100644 --- a/csharp/Facebook.Yoga/YogaNode.Spacing.cs +++ b/csharp/Facebook.Yoga/YogaNode.Spacing.cs @@ -226,6 +226,10 @@ namespace Facebook.Yoga { Native.YGNodeStyleSetMarginPercent(_ygNode, edge, value.Value); } + else if (value.Unit == YogaUnit.Auto) + { + Native.YGNodeStyleSetMarginAuto(_ygNode, edge); + } else { Native.YGNodeStyleSetMargin(_ygNode, edge, value.Value); diff --git a/csharp/Facebook.Yoga/YogaNode.cs b/csharp/Facebook.Yoga/YogaNode.cs index 59b6ae08..cb737c99 100644 --- a/csharp/Facebook.Yoga/YogaNode.cs +++ b/csharp/Facebook.Yoga/YogaNode.cs @@ -270,6 +270,10 @@ namespace Facebook.Yoga { Native.YGNodeStyleSetFlexBasisPercent(_ygNode, value.Value); } + else if (value.Unit == YogaUnit.Auto) + { + Native.YGNodeStyleSetFlexBasisAuto(_ygNode); + } else { Native.YGNodeStyleSetFlexBasis(_ygNode, value.Value); @@ -290,6 +294,10 @@ namespace Facebook.Yoga { Native.YGNodeStyleSetWidthPercent(_ygNode, value.Value); } + else if (value.Unit == YogaUnit.Auto) + { + Native.YGNodeStyleSetWidthAuto(_ygNode); + } else { Native.YGNodeStyleSetWidth(_ygNode, value.Value); @@ -310,6 +318,10 @@ namespace Facebook.Yoga { Native.YGNodeStyleSetHeightPercent(_ygNode, value.Value); } + else if (value.Unit == YogaUnit.Auto) + { + Native.YGNodeStyleSetHeightAuto(_ygNode); + } else { Native.YGNodeStyleSetHeight(_ygNode, value.Value); diff --git a/csharp/Facebook.Yoga/YogaUnit.cs b/csharp/Facebook.Yoga/YogaUnit.cs index 396c45da..8d370df8 100644 --- a/csharp/Facebook.Yoga/YogaUnit.cs +++ b/csharp/Facebook.Yoga/YogaUnit.cs @@ -12,7 +12,8 @@ namespace Facebook.Yoga public enum YogaUnit { Undefined, - Pixel, + Point, Percent, + Auto, } } diff --git a/csharp/Facebook.Yoga/YogaValue.cs b/csharp/Facebook.Yoga/YogaValue.cs index e86e16d3..b16a9707 100644 --- a/csharp/Facebook.Yoga/YogaValue.cs +++ b/csharp/Facebook.Yoga/YogaValue.cs @@ -33,12 +33,12 @@ namespace Facebook.Yoga } } - public static YogaValue Pixel(float value) + public static YogaValue Point(float value) { return new YogaValue { value = value, - unit = YogaConstants.IsUndefined(value) ? YogaUnit.Undefined : YogaUnit.Pixel + unit = YogaConstants.IsUndefined(value) ? YogaUnit.Undefined : YogaUnit.Point }; } @@ -70,6 +70,15 @@ namespace Facebook.Yoga }; } + public static YogaValue Auto() + { + return new YogaValue + { + value = 0f, + unit = YogaUnit.Auto + }; + } + public static YogaValue Percent(float value) { return new YogaValue @@ -79,9 +88,9 @@ namespace Facebook.Yoga }; } - public static implicit operator YogaValue(float pixelValue) + public static implicit operator YogaValue(float pointValue) { - return Pixel(pixelValue); + return Point(pointValue); } } } diff --git a/csharp/Facebook.Yoga/YogaValueExtensions.cs b/csharp/Facebook.Yoga/YogaValueExtensions.cs index 9ccee62a..73b98057 100644 --- a/csharp/Facebook.Yoga/YogaValueExtensions.cs +++ b/csharp/Facebook.Yoga/YogaValueExtensions.cs @@ -16,9 +16,9 @@ namespace Facebook.Yoga return YogaValue.Percent(value); } - public static YogaValue Px(this float value) + public static YogaValue Pt(this float value) { - return YogaValue.Pixel(value); + return YogaValue.Point(value); } public static YogaValue Percent(this int value) @@ -26,9 +26,9 @@ namespace Facebook.Yoga return YogaValue.Percent(value); } - public static YogaValue Px(this int value) + public static YogaValue Pt(this int value) { - return YogaValue.Pixel(value); + return YogaValue.Point(value); } } } \ No newline at end of file diff --git a/csharp/Facebook.YogaKit/YogaLayout.cs b/csharp/Facebook.YogaKit/YogaLayout.cs index f4cd4635..d59c1b17 100644 --- a/csharp/Facebook.YogaKit/YogaLayout.cs +++ b/csharp/Facebook.YogaKit/YogaLayout.cs @@ -854,9 +854,9 @@ namespace Facebook.YogaKit } } - static double RoundPixelValue(float value) + static double RoundPointValue(float value) { - float scale = NativePixelScale; + float scale = NativePointScale; return Math.Round(value * scale) / scale; } diff --git a/csharp/iOS/Facebook.YogaKit.iOS/YogaLayout.cs b/csharp/iOS/Facebook.YogaKit.iOS/YogaLayout.cs index 6aa052bf..aacd3377 100644 --- a/csharp/iOS/Facebook.YogaKit.iOS/YogaLayout.cs +++ b/csharp/iOS/Facebook.YogaKit.iOS/YogaLayout.cs @@ -30,7 +30,7 @@ namespace Facebook.YogaKit { var topLeft = new CGPoint(node.LayoutX, node.LayoutY); var bottomRight = new CGPoint(topLeft.X + node.LayoutWidth, topLeft.Y + node.LayoutHeight); - view.Frame = new CGRect(RoundPixelValue((float)topLeft.X), RoundPixelValue((float)topLeft.Y), RoundPixelValue((float)bottomRight.X) - RoundPixelValue((float)topLeft.X), RoundPixelValue((float)bottomRight.Y) - RoundPixelValue((float)topLeft.Y)); + view.Frame = new CGRect(RoundPointValue((float)topLeft.X), RoundPointValue((float)topLeft.Y), RoundPointValue((float)bottomRight.X) - RoundPointValue((float)topLeft.X), RoundPointValue((float)bottomRight.Y) - RoundPointValue((float)topLeft.Y)); } bool _disposed; diff --git a/csharp/tests/Facebook.Yoga/YGAlignContentTest.cs b/csharp/tests/Facebook.Yoga/YGAlignContentTest.cs index c73d6761..0d173c1c 100644 --- a/csharp/tests/Facebook.Yoga/YGAlignContentTest.cs +++ b/csharp/tests/Facebook.Yoga/YGAlignContentTest.cs @@ -118,18 +118,15 @@ namespace Facebook.Yoga } [Test] - public void Test_align_content_flex_end() + public void Test_align_content_flex_start_without_height_on_children() { YogaNode root = new YogaNode(); - root.FlexDirection = YogaFlexDirection.Row; - root.AlignContent = YogaAlign.FlexEnd; root.Wrap = YogaWrap.Wrap; - root.Width = 130; + root.Width = 100; root.Height = 100; YogaNode root_child0 = new YogaNode(); root_child0.Width = 50; - root_child0.Height = 10; root.Insert(0, root_child0); YogaNode root_child1 = new YogaNode(); @@ -139,7 +136,6 @@ namespace Facebook.Yoga YogaNode root_child2 = new YogaNode(); root_child2.Width = 50; - root_child2.Height = 10; root.Insert(2, root_child2); YogaNode root_child3 = new YogaNode(); @@ -149,83 +145,183 @@ namespace Facebook.Yoga YogaNode root_child4 = new YogaNode(); root_child4.Width = 50; - root_child4.Height = 10; root.Insert(4, root_child4); root.StyleDirection = YogaDirection.LTR; root.CalculateLayout(); Assert.AreEqual(0f, root.LayoutX); Assert.AreEqual(0f, root.LayoutY); - Assert.AreEqual(130f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutWidth); Assert.AreEqual(100f, root.LayoutHeight); Assert.AreEqual(0f, root_child0.LayoutX); - Assert.AreEqual(70f, root_child0.LayoutY); + Assert.AreEqual(0f, root_child0.LayoutY); Assert.AreEqual(50f, root_child0.LayoutWidth); - Assert.AreEqual(10f, root_child0.LayoutHeight); + Assert.AreEqual(0f, root_child0.LayoutHeight); - Assert.AreEqual(50f, root_child1.LayoutX); - Assert.AreEqual(70f, root_child1.LayoutY); + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); Assert.AreEqual(50f, root_child1.LayoutWidth); Assert.AreEqual(10f, root_child1.LayoutHeight); Assert.AreEqual(0f, root_child2.LayoutX); - Assert.AreEqual(80f, root_child2.LayoutY); + Assert.AreEqual(10f, root_child2.LayoutY); Assert.AreEqual(50f, root_child2.LayoutWidth); - Assert.AreEqual(10f, root_child2.LayoutHeight); + Assert.AreEqual(0f, root_child2.LayoutHeight); - Assert.AreEqual(50f, root_child3.LayoutX); - Assert.AreEqual(80f, root_child3.LayoutY); + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(10f, root_child3.LayoutY); Assert.AreEqual(50f, root_child3.LayoutWidth); Assert.AreEqual(10f, root_child3.LayoutHeight); Assert.AreEqual(0f, root_child4.LayoutX); - Assert.AreEqual(90f, root_child4.LayoutY); + Assert.AreEqual(20f, root_child4.LayoutY); Assert.AreEqual(50f, root_child4.LayoutWidth); - Assert.AreEqual(10f, root_child4.LayoutHeight); + Assert.AreEqual(0f, root_child4.LayoutHeight); root.StyleDirection = YogaDirection.RTL; root.CalculateLayout(); Assert.AreEqual(0f, root.LayoutX); Assert.AreEqual(0f, root.LayoutY); - Assert.AreEqual(130f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutWidth); Assert.AreEqual(100f, root.LayoutHeight); - Assert.AreEqual(80f, root_child0.LayoutX); - Assert.AreEqual(70f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); Assert.AreEqual(50f, root_child0.LayoutWidth); - Assert.AreEqual(10f, root_child0.LayoutHeight); + Assert.AreEqual(0f, root_child0.LayoutHeight); - Assert.AreEqual(30f, root_child1.LayoutX); - Assert.AreEqual(70f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); Assert.AreEqual(50f, root_child1.LayoutWidth); Assert.AreEqual(10f, root_child1.LayoutHeight); - Assert.AreEqual(80f, root_child2.LayoutX); - Assert.AreEqual(80f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(10f, root_child2.LayoutY); Assert.AreEqual(50f, root_child2.LayoutWidth); - Assert.AreEqual(10f, root_child2.LayoutHeight); + Assert.AreEqual(0f, root_child2.LayoutHeight); - Assert.AreEqual(30f, root_child3.LayoutX); - Assert.AreEqual(80f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(10f, root_child3.LayoutY); Assert.AreEqual(50f, root_child3.LayoutWidth); Assert.AreEqual(10f, root_child3.LayoutHeight); - Assert.AreEqual(80f, root_child4.LayoutX); - Assert.AreEqual(90f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(20f, root_child4.LayoutY); Assert.AreEqual(50f, root_child4.LayoutWidth); - Assert.AreEqual(10f, root_child4.LayoutHeight); + Assert.AreEqual(0f, root_child4.LayoutHeight); } [Test] - public void Test_align_content_center() + public void Test_align_content_flex_start_with_flex() { YogaNode root = new YogaNode(); - root.FlexDirection = YogaFlexDirection.Row; - root.AlignContent = YogaAlign.Center; root.Wrap = YogaWrap.Wrap; - root.Width = 130; + root.Width = 100; + root.Height = 120; + + YogaNode root_child0 = new YogaNode(); + root_child0.FlexGrow = 1; + root_child0.FlexBasis = 0.Percent(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexGrow = 1; + root_child1.FlexBasis = 0.Percent(); + root_child1.Width = 50; + root_child1.Height = 10; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.FlexGrow = 1; + root_child3.FlexShrink = 1; + root_child3.FlexBasis = 0.Percent(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(120f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(40f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(40f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(80f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(0f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(80f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(40f, root_child3.LayoutHeight); + + Assert.AreEqual(0f, root_child4.LayoutX); + Assert.AreEqual(120f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(0f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(120f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(40f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(40f, root_child1.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(80f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(0f, root_child2.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(80f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(40f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(120f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(0f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_flex_end() + { + YogaNode root = new YogaNode(); + root.AlignContent = YogaAlign.FlexEnd; + root.Wrap = YogaWrap.Wrap; + root.Width = 100; root.Height = 100; YogaNode root_child0 = new YogaNode(); @@ -257,31 +353,31 @@ namespace Facebook.Yoga Assert.AreEqual(0f, root.LayoutX); Assert.AreEqual(0f, root.LayoutY); - Assert.AreEqual(130f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutWidth); Assert.AreEqual(100f, root.LayoutHeight); Assert.AreEqual(0f, root_child0.LayoutX); - Assert.AreEqual(35f, root_child0.LayoutY); + Assert.AreEqual(0f, root_child0.LayoutY); Assert.AreEqual(50f, root_child0.LayoutWidth); Assert.AreEqual(10f, root_child0.LayoutHeight); - Assert.AreEqual(50f, root_child1.LayoutX); - Assert.AreEqual(35f, root_child1.LayoutY); + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(10f, root_child1.LayoutY); Assert.AreEqual(50f, root_child1.LayoutWidth); Assert.AreEqual(10f, root_child1.LayoutHeight); Assert.AreEqual(0f, root_child2.LayoutX); - Assert.AreEqual(45f, root_child2.LayoutY); + Assert.AreEqual(20f, root_child2.LayoutY); Assert.AreEqual(50f, root_child2.LayoutWidth); Assert.AreEqual(10f, root_child2.LayoutHeight); - Assert.AreEqual(50f, root_child3.LayoutX); - Assert.AreEqual(45f, root_child3.LayoutY); + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(30f, root_child3.LayoutY); Assert.AreEqual(50f, root_child3.LayoutWidth); Assert.AreEqual(10f, root_child3.LayoutHeight); Assert.AreEqual(0f, root_child4.LayoutX); - Assert.AreEqual(55f, root_child4.LayoutY); + Assert.AreEqual(40f, root_child4.LayoutY); Assert.AreEqual(50f, root_child4.LayoutWidth); Assert.AreEqual(10f, root_child4.LayoutHeight); @@ -290,31 +386,31 @@ namespace Facebook.Yoga Assert.AreEqual(0f, root.LayoutX); Assert.AreEqual(0f, root.LayoutY); - Assert.AreEqual(130f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutWidth); Assert.AreEqual(100f, root.LayoutHeight); - Assert.AreEqual(80f, root_child0.LayoutX); - Assert.AreEqual(35f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); Assert.AreEqual(50f, root_child0.LayoutWidth); Assert.AreEqual(10f, root_child0.LayoutHeight); - Assert.AreEqual(30f, root_child1.LayoutX); - Assert.AreEqual(35f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(10f, root_child1.LayoutY); Assert.AreEqual(50f, root_child1.LayoutWidth); Assert.AreEqual(10f, root_child1.LayoutHeight); - Assert.AreEqual(80f, root_child2.LayoutX); - Assert.AreEqual(45f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(20f, root_child2.LayoutY); Assert.AreEqual(50f, root_child2.LayoutWidth); Assert.AreEqual(10f, root_child2.LayoutHeight); - Assert.AreEqual(30f, root_child3.LayoutX); - Assert.AreEqual(45f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(30f, root_child3.LayoutY); Assert.AreEqual(50f, root_child3.LayoutWidth); Assert.AreEqual(10f, root_child3.LayoutHeight); - Assert.AreEqual(80f, root_child4.LayoutX); - Assert.AreEqual(55f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(40f, root_child4.LayoutY); Assert.AreEqual(50f, root_child4.LayoutWidth); Assert.AreEqual(10f, root_child4.LayoutHeight); } @@ -616,5 +712,1083 @@ namespace Facebook.Yoga Assert.AreEqual(10f, root_child4.LayoutHeight); } + [Test] + public void Test_align_content_stretch_row() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_children() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.FlexGrow = 1; + root_child0_child0.FlexShrink = 1; + root_child0_child0.FlexBasis = 0.Percent(); + root_child0.Insert(0, root_child0_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(50f, root_child0_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(50f, root_child0_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_flex() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexGrow = 1; + root_child1.FlexShrink = 1; + root_child1.FlexBasis = 0.Percent(); + root_child1.Width = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.FlexGrow = 1; + root_child3.FlexShrink = 1; + root_child3.FlexBasis = 0.Percent(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(0f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(100f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(0f, root_child3.LayoutY); + Assert.AreEqual(0f, root_child3.LayoutWidth); + Assert.AreEqual(100f, root_child3.LayoutHeight); + + Assert.AreEqual(100f, root_child4.LayoutX); + Assert.AreEqual(0f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(100f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(100f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(0f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(100f, root_child2.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(0f, root_child3.LayoutY); + Assert.AreEqual(0f, root_child3.LayoutWidth); + Assert.AreEqual(100f, root_child3.LayoutHeight); + + Assert.AreEqual(0f, root_child4.LayoutX); + Assert.AreEqual(0f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(100f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_flex_no_shrink() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexGrow = 1; + root_child1.FlexShrink = 1; + root_child1.FlexBasis = 0.Percent(); + root_child1.Width = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.FlexGrow = 1; + root_child3.FlexBasis = 0.Percent(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(0f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(100f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(0f, root_child3.LayoutY); + Assert.AreEqual(0f, root_child3.LayoutWidth); + Assert.AreEqual(100f, root_child3.LayoutHeight); + + Assert.AreEqual(100f, root_child4.LayoutX); + Assert.AreEqual(0f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(100f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(100f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(0f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(100f, root_child2.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(0f, root_child3.LayoutY); + Assert.AreEqual(0f, root_child3.LayoutWidth); + Assert.AreEqual(100f, root_child3.LayoutHeight); + + Assert.AreEqual(0f, root_child4.LayoutX); + Assert.AreEqual(0f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(100f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_margin() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.MarginLeft = 10; + root_child1.MarginTop = 10; + root_child1.MarginRight = 10; + root_child1.MarginBottom = 10; + root_child1.Width = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.MarginLeft = 10; + root_child3.MarginTop = 10; + root_child3.MarginRight = 10; + root_child3.MarginBottom = 10; + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(40f, root_child0.LayoutHeight); + + Assert.AreEqual(60f, root_child1.LayoutX); + Assert.AreEqual(10f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(40f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(40f, root_child2.LayoutHeight); + + Assert.AreEqual(60f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + Assert.AreEqual(0f, root_child4.LayoutX); + Assert.AreEqual(80f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(20f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(40f, root_child0.LayoutHeight); + + Assert.AreEqual(40f, root_child1.LayoutX); + Assert.AreEqual(10f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(40f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(40f, root_child2.LayoutHeight); + + Assert.AreEqual(40f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + Assert.AreEqual(100f, root_child4.LayoutX); + Assert.AreEqual(80f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(20f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_padding() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.PaddingLeft = 10; + root_child1.PaddingTop = 10; + root_child1.PaddingRight = 10; + root_child1.PaddingBottom = 10; + root_child1.Width = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.PaddingLeft = 10; + root_child3.PaddingTop = 10; + root_child3.PaddingRight = 10; + root_child3.PaddingBottom = 10; + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_single_row() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_fixed_height() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 60; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(80f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(60f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(80f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(80f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(80f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(20f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(80f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(60f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(80f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(80f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(80f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(20f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_max_height() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.MaxHeight = 20; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(50f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(50f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_row_with_min_height() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.MinHeight = 80; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Width = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(90f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(90f, root_child1.LayoutHeight); + + Assert.AreEqual(100f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(90f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(90f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(10f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(90f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(10f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(90f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(90f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(90f, root_child2.LayoutHeight); + + Assert.AreEqual(100f, root_child3.LayoutX); + Assert.AreEqual(90f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(10f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(90f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(10f, root_child4.LayoutHeight); + } + + [Test] + public void Test_align_content_stretch_column() + { + YogaNode root = new YogaNode(); + root.AlignContent = YogaAlign.Stretch; + root.Wrap = YogaWrap.Wrap; + root.Width = 100; + root.Height = 150; + + YogaNode root_child0 = new YogaNode(); + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.FlexGrow = 1; + root_child0_child0.FlexShrink = 1; + root_child0_child0.FlexBasis = 0.Percent(); + root_child0.Insert(0, root_child0_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexGrow = 1; + root_child1.FlexShrink = 1; + root_child1.FlexBasis = 0.Percent(); + root_child1.Height = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Height = 50; + root.Insert(2, root_child2); + + YogaNode root_child3 = new YogaNode(); + root_child3.Height = 50; + root.Insert(3, root_child3); + + YogaNode root_child4 = new YogaNode(); + root_child4.Height = 50; + root.Insert(4, root_child4); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(150f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(50f, root_child0_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(0f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(50f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(100f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(50f, root_child4.LayoutX); + Assert.AreEqual(0f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(150f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(50f, root_child0_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(0f, root_child1.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(50f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(100f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + Assert.AreEqual(0f, root_child4.LayoutX); + Assert.AreEqual(0f, root_child4.LayoutY); + Assert.AreEqual(50f, root_child4.LayoutWidth); + Assert.AreEqual(50f, root_child4.LayoutHeight); + } + } } diff --git a/csharp/tests/Facebook.Yoga/YGFlexWrapTest.cs b/csharp/tests/Facebook.Yoga/YGFlexWrapTest.cs index 7bb67921..3dbcf8f2 100644 --- a/csharp/tests/Facebook.Yoga/YGFlexWrapTest.cs +++ b/csharp/tests/Facebook.Yoga/YGFlexWrapTest.cs @@ -410,5 +410,139 @@ namespace Facebook.Yoga Assert.AreEqual(50f, root_child1.LayoutHeight); } + [Test] + public void Test_flex_wrap_wrap_to_child_height() + { + YogaNode root = new YogaNode(); + + YogaNode root_child0 = new YogaNode(); + root_child0.FlexDirection = YogaFlexDirection.Row; + root_child0.AlignItems = YogaAlign.FlexStart; + root_child0.Wrap = YogaWrap.Wrap; + root.Insert(0, root_child0); + + YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.Width = 100; + root_child0.Insert(0, root_child0_child0); + + YogaNode root_child0_child0_child0 = new YogaNode(); + root_child0_child0_child0.Width = 100; + root_child0_child0_child0.Height = 100; + root_child0_child0.Insert(0, root_child0_child0_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 100; + root_child1.Height = 100; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(100f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(100f, root_child0_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0_child0.LayoutY); + Assert.AreEqual(100f, root_child0_child0_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0_child0_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(100f, root_child1.LayoutY); + Assert.AreEqual(100f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(100f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(100f, root_child0_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0_child0.LayoutY); + Assert.AreEqual(100f, root_child0_child0_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0_child0_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(100f, root_child1.LayoutY); + Assert.AreEqual(100f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + } + + [Test] + public void Test_flex_wrap_align_stretch_fits_one_row() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.Wrap = YogaWrap.Wrap; + root.Width = 150; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(150f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(100f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(100f, root_child1.LayoutHeight); + } + } } diff --git a/csharp/tests/Facebook.Yoga/YGMarginTest.cs b/csharp/tests/Facebook.Yoga/YGMarginTest.cs index e5fb77de..13ff7fa1 100644 --- a/csharp/tests/Facebook.Yoga/YGMarginTest.cs +++ b/csharp/tests/Facebook.Yoga/YGMarginTest.cs @@ -436,5 +436,759 @@ namespace Facebook.Yoga Assert.AreEqual(45f, root_child1.LayoutHeight); } + [Test] + public void Test_margin_auto_bottom() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginBottom = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_top() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginTop = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(100f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(100f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_bottom_and_top() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginTop = YogaValue.Auto(); + root_child0.MarginBottom = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(50f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(50f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_bottom_and_top_justify_center() + { + YogaNode root = new YogaNode(); + root.JustifyContent = YogaJustify.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginTop = YogaValue.Auto(); + root_child0.MarginBottom = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(50f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(150f, root_child0.LayoutX); + Assert.AreEqual(50f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(150f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_mutiple_children_column() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginTop = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.MarginTop = YogaValue.Auto(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root_child2.Height = 50; + root.Insert(2, root_child2); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(25f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(100f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(75f, root_child2.LayoutX); + Assert.AreEqual(150f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(25f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(100f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(75f, root_child2.LayoutX); + Assert.AreEqual(150f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + } + + [Test] + public void Test_margin_auto_mutiple_children_row() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginRight = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.MarginRight = YogaValue.Auto(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root_child2.Height = 50; + root.Insert(2, root_child2); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(75f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(75f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(150f, root_child2.LayoutX); + Assert.AreEqual(75f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(125f, root_child0.LayoutX); + Assert.AreEqual(75f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(75f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(75f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(50f, root_child2.LayoutHeight); + } + + [Test] + public void Test_margin_auto_left_and_right_column() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginLeft = YogaValue.Auto(); + root_child0.MarginRight = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(75f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(150f, root_child1.LayoutX); + Assert.AreEqual(75f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(75f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(75f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_left_and_right() + { + YogaNode root = new YogaNode(); + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginLeft = YogaValue.Auto(); + root_child0.MarginRight = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(150f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_left_and_right_column_and_center() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginLeft = YogaValue.Auto(); + root_child0.MarginRight = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(75f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_left() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginLeft = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(150f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(150f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_right() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Center; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginRight = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(75f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_left_and_right_strech() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginLeft = YogaValue.Auto(); + root_child0.MarginRight = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(150f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(100f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(0f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + + [Test] + public void Test_margin_auto_top_and_bottom_strech() + { + YogaNode root = new YogaNode(); + root.Width = 200; + root.Height = 200; + + YogaNode root_child0 = new YogaNode(); + root_child0.MarginTop = YogaValue.Auto(); + root_child0.MarginBottom = YogaValue.Auto(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(50f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(200f, root.LayoutWidth); + Assert.AreEqual(200f, root.LayoutHeight); + + Assert.AreEqual(150f, root_child0.LayoutX); + Assert.AreEqual(50f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(150f, root_child1.LayoutX); + Assert.AreEqual(150f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + } + } } diff --git a/docs/_config.yml b/docs/_config.yml index 688e6a7b..97863fc4 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -4,7 +4,7 @@ title: YOGA tagline: A cross-platform layout engine fbappid: "1615782811974223" -gacode: "UA-12345-6" +gacode: "UA-44373548-24" # baseurl determines the subpath of your site. For example if you're using an # organisation.github.io/reponame/ basic site URL, then baseurl would be set diff --git a/docs/_data/nav_docs.yml b/docs/_data/nav_docs.yml index 63be4d0b..b7e3025a 100644 --- a/docs/_data/nav_docs.yml +++ b/docs/_data/nav_docs.yml @@ -21,5 +21,6 @@ - id: c - id: yogakit - id: java + - id: android - id: csharp - id: javascript diff --git a/docs/_docs/api/android.md b/docs/_docs/api/android.md new file mode 100644 index 00000000..28ab895c --- /dev/null +++ b/docs/_docs/api/android.md @@ -0,0 +1,28 @@ +--- +docid: android +title: Android +layout: docs +permalink: /docs/api/android/ +--- + +There is an easy interface to Yoga called `YogaLayout`. This is a view group that lays out its children using Yoga. We recommend looking at the sample app for details on its usage. However, as an overview you can simply define XML layouts such as + + + +Note that there are some caveats, such as requiring the custom `YogaLayoutViewFactory` in order to have tags `YogaLayout` instead of `com.facebook.samples.yoga.YogaLayout`. + +## layout\_width and layout\_height + +If either are set to an actual size (in px or dp etc) then this is taken as a default for `yoga:height` or `yoga:width`. Otherwise they are ignored. + +## VirtualYogaLayout + +Sometimes you will nest `YogaLayout`s within `YogaLayout`s in order to get your layout to be perfect, but some of the `YogaLayout`s are just there to control position: they don't render or anything. If so, then they are unnecessary (since Yoga stores the view hierarchy itself) and `VirtualYogaLayout` is a ViewGroup that fixes this. It will never get drawn, but all its children will be placed appropriately. + +## RTL locales + +RTL locales are supported by default. That is, unless you explicitly set the `yoga:direction="ltr|rtl|inherit"` attribute on a view, it will obtain the locale direction _at runtime_. This means that the layout will rearrange properly, even if the locale changes while your app is running! + +## Attributes + +The list of all attributes can be found in [attrs.xml](https://github.com/facebook/yoga/blob/master/android/sample/res/com/facebook/samples/yoga/res/values/attrs.xml), but logically map from the Yoga properties. diff --git a/docs/_docs/getting-started.md b/docs/_docs/getting-started.md index 6a8cde69..4b386c00 100644 --- a/docs/_docs/getting-started.md +++ b/docs/_docs/getting-started.md @@ -13,12 +13,22 @@ Installation of Yoga is currently a manual process. We have plans on bringing Yo For now we recommend including Yoga as a [git submodule](https://git-scm.com/docs/git-submodule) in your project. Once done, you can either build Yoga using Buck (detailed [below](#building-with-buck)) or integrate it into your existing build system by including the C library from the [root `yoga` directory](https://github.com/facebook/yoga/tree/master/yoga) as well as the [language bindings](https://github.com/facebook/yoga) (e.g., Java, C#) you wish to use. -### Running the Example +### Running the Examples + +#### iOS Yoga ships with an [iOS example](https://github.com/facebook/yoga/tree/master/YogaKit/YogaKitSample). To get it running: +#### Android + +Yoga ships with an [Android example too](https://github.com/facebook/yoga/tree/master/android/sample). To get it running on an attached device (or emulator): + + + +Actually, this is more than just an example, and more a layout system for Android using Yoga in general (see `YogaLayout`). For more information see the [Android API section](/yoga/docs/api/android). + ### Building with Buck Yoga uses [Buck](https://buckbuild.com/) as its build system. Buck is not required for using Yoga, but, if you already use Buck, then integrating Yoga is very simple. diff --git a/docs/index.md b/docs/index.md index 66037545..3faa5e21 100644 --- a/docs/index.md +++ b/docs/index.md @@ -63,3 +63,22 @@ id: home + +

+

Android

+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ diff --git a/enums.py b/enums.py index 83c582db..c29d5d35 100644 --- a/enums.py +++ b/enums.py @@ -19,8 +19,9 @@ ENUMS = { ], 'Unit': [ 'Undefined', - 'Pixel', + 'Point', 'Percent', + 'Auto', ], 'FlexDirection': [ 'Column', diff --git a/gentest/fixtures/YGAlignContentTest.html b/gentest/fixtures/YGAlignContentTest.html index b1f23050..de7938fb 100644 --- a/gentest/fixtures/YGAlignContentTest.html +++ b/gentest/fixtures/YGAlignContentTest.html @@ -6,15 +6,23 @@
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+ +
@@ -45,3 +53,92 @@
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
diff --git a/gentest/fixtures/YGFlexWrapTest.html b/gentest/fixtures/YGFlexWrapTest.html index 8f0de398..353805db 100644 --- a/gentest/fixtures/YGFlexWrapTest.html +++ b/gentest/fixtures/YGFlexWrapTest.html @@ -30,3 +30,17 @@
+ +
+
+
+
+
+
+
+
+ +
+
+
+
diff --git a/gentest/fixtures/YGMarginTest.html b/gentest/fixtures/YGMarginTest.html index e7a8fb69..a78374bd 100644 --- a/gentest/fixtures/YGMarginTest.html +++ b/gentest/fixtures/YGMarginTest.html @@ -39,3 +39,70 @@
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js index 4a4896f4..1c50de6e 100644 --- a/gentest/gentest-cpp.js +++ b/gentest/gentest-cpp.js @@ -13,8 +13,10 @@ function toValueCpp(value) { } function toFunctionName(value) { - if (value.indexOf('%') >= 0){ + if (value.indexOf('%') >= 0) { return 'Percent'; + } else if(value.indexOf('Auto') >= 0) { + return 'Auto'; } return ''; } @@ -121,6 +123,8 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { YGDisplayFlex:{value:'YGDisplayFlex'}, YGDisplayNone:{value:'YGDisplayNone'}, + YGAuto:{value:'YGAuto'}, + YGNodeCalculateLayout:{value:function(node, dir) { this.push('YGNodeCalculateLayout(' + node + ', YGUndefined, YGUndefined, ' + dir + ');'); @@ -199,7 +203,13 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { }}, YGNodeStyleSetMargin:{value:function(nodeName, edge, value) { - this.push('YGNodeStyleSetMargin' + toFunctionName(value) + '(' + nodeName + ', ' + edge + ', ' + toValueCpp(value) + ');'); + var valueStr = toValueCpp(value); + if (valueStr != 'YGAuto') { + valueStr = ', ' + valueStr; + } else { + valueStr = ''; + } + this.push('YGNodeStyleSetMargin' + toFunctionName(value) + '(' + nodeName + ', ' + edge + valueStr + ');'); }}, YGNodeStyleSetMaxHeight:{value:function(nodeName, value) { diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js index 06c0c3f3..42c6ff2c 100644 --- a/gentest/gentest-cs.js +++ b/gentest/gentest-cs.js @@ -17,6 +17,9 @@ function toCsUnitValue(value) { if (value.indexOf('%') >= 0){ methodName = '.Percent()'; } + if(value.indexOf('Auto') >= 0){ + return 'YogaValue.Auto()'; + } return toValueCs(value) + methodName; } @@ -130,6 +133,8 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { YGUndefined:{value:'YogaConstants.Undefined'}, + YGAuto:{value:'YogaConstants.Auto'}, + YGDisplayFlex:{value:'YogaDisplay.Flex'}, YGDisplayNone:{value:'YogaDisplay.None'}, diff --git a/gentest/gentest-java.js b/gentest/gentest-java.js index 6ca39952..3d39764b 100644 --- a/gentest/gentest-java.js +++ b/gentest/gentest-java.js @@ -15,6 +15,8 @@ function toValueJava(value) { function toMethodName(value) { if (value.indexOf('%') >= 0){ return 'Percent'; + } else if(value.indexOf('AUTO') >= 0) { + return 'Auto'; } return ''; } @@ -136,6 +138,8 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, { YGDisplayFlex:{value:'YogaDisplay.FLEX'}, YGDisplayNone:{value:'YogaDisplay.NONE'}, + YGAuto:{value:'YogaConstants.AUTO'}, + YGWrapNoWrap:{value:'YogaWrap.NO_WRAP'}, YGWrapWrap:{value:'YogaWrap.WRAP'}, @@ -218,7 +222,14 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, { }}, YGNodeStyleSetMargin:{value:function(nodeName, edge, value) { - this.push(nodeName + '.setMargin' + toMethodName(value) + '(' + edge + ', ' + toValueJava(value) + 'f);'); + var valueStr = toValueJava(value); + if (valueStr != 'YogaConstants.AUTO') { + valueStr = ', ' + valueStr + 'f'; + } else { + valueStr = ''; + } + + this.push(nodeName + '.setMargin' + toMethodName(value) + '(' + edge + valueStr + ');'); }}, YGNodeStyleSetMaxHeight:{value:function(nodeName, value) { diff --git a/gentest/gentest-javascript.js b/gentest/gentest-javascript.js index 803a5a3b..ea501722 100644 --- a/gentest/gentest-javascript.js +++ b/gentest/gentest-javascript.js @@ -14,6 +14,7 @@ var JavascriptEmitter = function() { function toValueJavascript(value) { if (value.match(/^[0-9.e+-]+px$/i)) return parseFloat(value); if (value.match(/^[0-9.e+-]+%/i)) return JSON.stringify(value); + if (value == 'Yoga.AUTO') return '"auto"'; return value; } @@ -122,6 +123,8 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, { YGPositionTypeAbsolute:{value:'Yoga.POSITION_TYPE_ABSOLUTE'}, YGPositionTypeRelative:{value:'Yoga.POSITION_TYPE_RELATIVE'}, + YGAuto:{value:'Yoga.AUTO'}, + YGWrapNoWrap:{value:'Yoga.WRAP_NO_WRAP'}, YGWrapWrap:{value:'Yoga.WRAP_WRAP'}, diff --git a/gentest/gentest.js b/gentest/gentest.js index 72c252f8..4649c00d 100755 --- a/gentest/gentest.js +++ b/gentest/gentest.js @@ -201,105 +201,105 @@ function setupTestTree(e, parent, node, genericNode, nodeName, parentName, index e.YGNodeStyleSetFlexShrink(nodeName, node.style[style]); break; case 'flex-basis': - e.YGNodeStyleSetFlexBasis(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetFlexBasis(nodeName, pointValue(e, node.style[style])); break; case 'left': if (genericNode.rawStyle.indexOf('start:') >= 0) { - e.YGNodeStyleSetPosition(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPosition(nodeName, e.YGEdgeStart, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetPosition(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPosition(nodeName, e.YGEdgeLeft, pointValue(e, node.style[style])); } break; case 'top': - e.YGNodeStyleSetPosition(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPosition(nodeName, e.YGEdgeTop, pointValue(e, node.style[style])); break; case 'right': if (genericNode.rawStyle.indexOf('end:') >= 0) { - e.YGNodeStyleSetPosition(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPosition(nodeName, e.YGEdgeEnd, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetPosition(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPosition(nodeName, e.YGEdgeRight, pointValue(e, node.style[style])); } break; case 'bottom': - e.YGNodeStyleSetPosition(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPosition(nodeName, e.YGEdgeBottom, pointValue(e, node.style[style])); break; case 'margin-left': if (genericNode.rawStyle.indexOf('margin-start:') >= 0) { - e.YGNodeStyleSetMargin(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMargin(nodeName, e.YGEdgeStart, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetMargin(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMargin(nodeName, e.YGEdgeLeft, pointValue(e, node.style[style])); } break; case 'margin-top': - e.YGNodeStyleSetMargin(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMargin(nodeName, e.YGEdgeTop, pointValue(e, node.style[style])); break; case 'margin-right': if (genericNode.rawStyle.indexOf('margin-end:') >= 0) { - e.YGNodeStyleSetMargin(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMargin(nodeName, e.YGEdgeEnd, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetMargin(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMargin(nodeName, e.YGEdgeRight, pointValue(e, node.style[style])); } break; case 'margin-bottom': - e.YGNodeStyleSetMargin(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMargin(nodeName, e.YGEdgeBottom, pointValue(e, node.style[style])); break; case 'padding-left': if (genericNode.rawStyle.indexOf('padding-start:') >= 0) { - e.YGNodeStyleSetPadding(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPadding(nodeName, e.YGEdgeStart, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetPadding(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPadding(nodeName, e.YGEdgeLeft, pointValue(e, node.style[style])); } break; case 'padding-top': - e.YGNodeStyleSetPadding(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPadding(nodeName, e.YGEdgeTop, pointValue(e, node.style[style])); break; case 'padding-right': if (genericNode.rawStyle.indexOf('padding-end:') >= 0) { - e.YGNodeStyleSetPadding(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPadding(nodeName, e.YGEdgeEnd, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetPadding(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPadding(nodeName, e.YGEdgeRight, pointValue(e, node.style[style])); } break; case 'padding-bottom': - e.YGNodeStyleSetPadding(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style])); + e.YGNodeStyleSetPadding(nodeName, e.YGEdgeBottom, pointValue(e, node.style[style])); break; case 'border-left-width': if (genericNode.rawStyle.indexOf('border-start-width:') >= 0) { - e.YGNodeStyleSetBorder(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style])); + e.YGNodeStyleSetBorder(nodeName, e.YGEdgeStart, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetBorder(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style])); + e.YGNodeStyleSetBorder(nodeName, e.YGEdgeLeft, pointValue(e, node.style[style])); } break; case 'border-top-width': - e.YGNodeStyleSetBorder(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style])); + e.YGNodeStyleSetBorder(nodeName, e.YGEdgeTop, pointValue(e, node.style[style])); break; case 'border-right-width': if (genericNode.rawStyle.indexOf('border-end-width:') >= 0) { - e.YGNodeStyleSetBorder(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style])); + e.YGNodeStyleSetBorder(nodeName, e.YGEdgeEnd, pointValue(e, node.style[style])); } else { - e.YGNodeStyleSetBorder(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style])); + e.YGNodeStyleSetBorder(nodeName, e.YGEdgeRight, pointValue(e, node.style[style])); } break; case 'border-bottom-width': - e.YGNodeStyleSetBorder(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style])); + e.YGNodeStyleSetBorder(nodeName, e.YGEdgeBottom, pointValue(e, node.style[style])); break; case 'width': - e.YGNodeStyleSetWidth(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetWidth(nodeName, pointValue(e, node.style[style])); break; case 'min-width': - e.YGNodeStyleSetMinWidth(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMinWidth(nodeName, pointValue(e, node.style[style])); break; case 'max-width': - e.YGNodeStyleSetMaxWidth(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMaxWidth(nodeName, pointValue(e, node.style[style])); break; case 'height': - e.YGNodeStyleSetHeight(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetHeight(nodeName, pointValue(e, node.style[style])); break; case 'min-height': - e.YGNodeStyleSetMinHeight(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMinHeight(nodeName, pointValue(e, node.style[style])); break; case 'max-height': - e.YGNodeStyleSetMaxHeight(nodeName, pixelValue(e, node.style[style])); + e.YGNodeStyleSetMaxHeight(nodeName, pointValue(e, node.style[style])); break; case 'display': e.YGNodeStyleSetDisplay(nodeName, displayValue(e, node.style[style])) @@ -387,9 +387,9 @@ function alignValue(e, value) { } } -function pixelValue(e, value) { +function pointValue(e, value) { switch (value) { - case 'auto': return e.YGUndefined; + case 'auto': return e.YGAuto; case 'undefined': return e.YGUndefined; default: return value; } diff --git a/java/com/facebook/yoga/YogaBaselineFunction.java b/java/com/facebook/yoga/YogaBaselineFunction.java index 1bfb52a7..60de81c5 100644 --- a/java/com/facebook/yoga/YogaBaselineFunction.java +++ b/java/com/facebook/yoga/YogaBaselineFunction.java @@ -14,7 +14,7 @@ import com.facebook.proguard.annotations.DoNotStrip; @DoNotStrip public interface YogaBaselineFunction { /** - * Return the baseline of the node in pixels. When no baseline function is set the baseline + * Return the baseline of the node in points. When no baseline function is set the baseline * default to the computed height of the node. */ @DoNotStrip diff --git a/java/com/facebook/yoga/YogaNode.java b/java/com/facebook/yoga/YogaNode.java index 08edbd46..94f16a99 100644 --- a/java/com/facebook/yoga/YogaNode.java +++ b/java/com/facebook/yoga/YogaNode.java @@ -378,6 +378,12 @@ public class YogaNode implements YogaNodeAPI { jni_YGNodeStyleSetFlexBasisPercent(mNativePointer, percent); } + private native void jni_YGNodeStyleSetFlexBasisAuto(long nativePointer); + @Override + public void setFlexBasisAuto() { + jni_YGNodeStyleSetFlexBasisAuto(mNativePointer); + } + private native Object jni_YGNodeStyleGetMargin(long nativePointer, int edge); @Override public YogaValue getMargin(YogaEdge edge) { @@ -401,6 +407,13 @@ public class YogaNode implements YogaNodeAPI { jni_YGNodeStyleSetMarginPercent(mNativePointer, edge.intValue(), percent); } + private native void jni_YGNodeStyleSetMarginAuto(long nativePointer, int edge); + @Override + public void setMarginAuto(YogaEdge edge) { + mHasSetMargin = true; + jni_YGNodeStyleSetMarginAuto(mNativePointer, edge.intValue()); + } + private native Object jni_YGNodeStyleGetPadding(long nativePointer, int edge); @Override public YogaValue getPadding(YogaEdge edge) { @@ -481,6 +494,12 @@ public class YogaNode implements YogaNodeAPI { jni_YGNodeStyleSetWidthPercent(mNativePointer, percent); } + private native void jni_YGNodeStyleSetWidthAuto(long nativePointer); + @Override + public void setWidthAuto() { + jni_YGNodeStyleSetWidthAuto(mNativePointer); + } + private native Object jni_YGNodeStyleGetHeight(long nativePointer); @Override public YogaValue getHeight() { @@ -499,6 +518,12 @@ public class YogaNode implements YogaNodeAPI { jni_YGNodeStyleSetHeightPercent(mNativePointer, percent); } + private native void jni_YGNodeStyleSetHeightAuto(long nativePointer); + @Override + public void setHeightAuto() { + jni_YGNodeStyleSetHeightAuto(mNativePointer); + } + private native Object jni_YGNodeStyleGetMinWidth(long nativePointer); @Override public YogaValue getMinWidth() { diff --git a/java/com/facebook/yoga/YogaNodeAPI.java b/java/com/facebook/yoga/YogaNodeAPI.java index 406ec587..1c4af327 100644 --- a/java/com/facebook/yoga/YogaNodeAPI.java +++ b/java/com/facebook/yoga/YogaNodeAPI.java @@ -49,9 +49,11 @@ public interface YogaNodeAPI { YogaValue getFlexBasis(); void setFlexBasis(float flexBasis); void setFlexBasisPercent(float percent); + void setFlexBasisAuto(); YogaValue getMargin(YogaEdge edge); void setMargin(YogaEdge edge, float margin); void setMarginPercent(YogaEdge edge, float percent); + void setMarginAuto(YogaEdge edge); YogaValue getPadding(YogaEdge edge); void setPadding(YogaEdge edge, float padding); void setPaddingPercent(YogaEdge edge, float percent); @@ -63,9 +65,11 @@ public interface YogaNodeAPI { YogaValue getWidth(); void setWidth(float width); void setWidthPercent(float percent); + void setWidthAuto(); YogaValue getHeight(); void setHeight(float height); void setHeightPercent(float percent); + void setHeightAuto(); YogaValue getMaxWidth(); void setMaxWidth(float maxWidth); void setMaxWidthPercent(float percent); diff --git a/java/com/facebook/yoga/YogaUnit.java b/java/com/facebook/yoga/YogaUnit.java index f14e5216..f7b34369 100644 --- a/java/com/facebook/yoga/YogaUnit.java +++ b/java/com/facebook/yoga/YogaUnit.java @@ -14,8 +14,9 @@ import com.facebook.proguard.annotations.DoNotStrip; @DoNotStrip public enum YogaUnit { UNDEFINED(0), - PIXEL(1), - PERCENT(2); + POINT(1), + PERCENT(2), + AUTO(3); private int mIntValue; @@ -30,8 +31,9 @@ public enum YogaUnit { public static YogaUnit fromInt(int value) { switch (value) { case 0: return UNDEFINED; - case 1: return PIXEL; + case 1: return POINT; case 2: return PERCENT; + case 3: return AUTO; default: throw new IllegalArgumentException("Unknown enum value: " + value); } } diff --git a/java/com/facebook/yoga/YogaValue.java b/java/com/facebook/yoga/YogaValue.java index f9c0ebfc..c1741a78 100644 --- a/java/com/facebook/yoga/YogaValue.java +++ b/java/com/facebook/yoga/YogaValue.java @@ -14,7 +14,7 @@ import com.facebook.proguard.annotations.DoNotStrip; @DoNotStrip public class YogaValue { static final YogaValue UNDEFINED = new YogaValue(YogaConstants.UNDEFINED, YogaUnit.UNDEFINED); - static final YogaValue ZERO = new YogaValue(0, YogaUnit.PIXEL); + static final YogaValue ZERO = new YogaValue(0, YogaUnit.POINT); public final float value; public final YogaUnit unit; diff --git a/java/jni/YGJNI.cpp b/java/jni/YGJNI.cpp index 92923543..15f6d46f 100644 --- a/java/jni/YGJNI.cpp +++ b/java/jni/YGJNI.cpp @@ -285,6 +285,12 @@ struct JYogaValue : public JavaClass { YGNodeStyleSet##name##Percent(_jlong2YGNodeRef(nativePointer), static_cast(value)); \ } +#define YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(name) \ + YG_NODE_JNI_STYLE_UNIT_PROP(name) \ + void jni_YGNodeStyleSet##name##Auto(alias_ref, jlong nativePointer) { \ + YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer)); \ + } + #define YG_NODE_JNI_STYLE_EDGE_PROP(javatype, type, name) \ javatype jni_YGNodeStyleGet##name(alias_ref, jlong nativePointer, jint edge) { \ return (javatype) YGNodeStyleGet##name(_jlong2YGNodeRef(nativePointer), \ @@ -323,6 +329,12 @@ struct JYogaValue : public JavaClass { static_cast(value)); \ } +#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(name) \ + YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \ + void jni_YGNodeStyleSet##name##Auto(alias_ref, jlong nativePointer, jint edge) { \ + YGNodeStyleSet##name##Auto(_jlong2YGNodeRef(nativePointer), static_cast(edge)); \ + } + YG_NODE_JNI_STYLE_PROP(jint, YGDirection, Direction); YG_NODE_JNI_STYLE_PROP(jint, YGFlexDirection, FlexDirection); YG_NODE_JNI_STYLE_PROP(jint, YGJustify, JustifyContent); @@ -339,17 +351,17 @@ void jni_YGNodeStyleSetFlex(alias_ref, jlong nativePointer, jfloat valu } YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexGrow); YG_NODE_JNI_STYLE_PROP(jfloat, float, FlexShrink); -YG_NODE_JNI_STYLE_UNIT_PROP(FlexBasis); +YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(FlexBasis); YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(Position); -YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(Margin); +YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(Margin); YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(Padding); YG_NODE_JNI_STYLE_EDGE_PROP(jfloat, float, Border); -YG_NODE_JNI_STYLE_UNIT_PROP(Width); +YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Width); YG_NODE_JNI_STYLE_UNIT_PROP(MinWidth); YG_NODE_JNI_STYLE_UNIT_PROP(MaxWidth); -YG_NODE_JNI_STYLE_UNIT_PROP(Height); +YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Height); YG_NODE_JNI_STYLE_UNIT_PROP(MinHeight); YG_NODE_JNI_STYLE_UNIT_PROP(MaxHeight); @@ -402,9 +414,11 @@ jint JNI_OnLoad(JavaVM *vm, void *) { YGMakeNativeMethod(jni_YGNodeStyleGetFlexBasis), YGMakeNativeMethod(jni_YGNodeStyleSetFlexBasis), YGMakeNativeMethod(jni_YGNodeStyleSetFlexBasisPercent), + YGMakeNativeMethod(jni_YGNodeStyleSetFlexBasisAuto), YGMakeNativeMethod(jni_YGNodeStyleGetMargin), YGMakeNativeMethod(jni_YGNodeStyleSetMargin), YGMakeNativeMethod(jni_YGNodeStyleSetMarginPercent), + YGMakeNativeMethod(jni_YGNodeStyleSetMarginAuto), YGMakeNativeMethod(jni_YGNodeStyleGetPadding), YGMakeNativeMethod(jni_YGNodeStyleSetPadding), YGMakeNativeMethod(jni_YGNodeStyleSetPaddingPercent), @@ -416,9 +430,11 @@ jint JNI_OnLoad(JavaVM *vm, void *) { YGMakeNativeMethod(jni_YGNodeStyleGetWidth), YGMakeNativeMethod(jni_YGNodeStyleSetWidth), YGMakeNativeMethod(jni_YGNodeStyleSetWidthPercent), + YGMakeNativeMethod(jni_YGNodeStyleSetWidthAuto), YGMakeNativeMethod(jni_YGNodeStyleGetHeight), YGMakeNativeMethod(jni_YGNodeStyleSetHeight), YGMakeNativeMethod(jni_YGNodeStyleSetHeightPercent), + YGMakeNativeMethod(jni_YGNodeStyleSetHeightAuto), YGMakeNativeMethod(jni_YGNodeStyleGetMinWidth), YGMakeNativeMethod(jni_YGNodeStyleSetMinWidth), YGMakeNativeMethod(jni_YGNodeStyleSetMinWidthPercent), diff --git a/java/tests/com/facebook/yoga/YGAlignContentTest.java b/java/tests/com/facebook/yoga/YGAlignContentTest.java index de9daa1b..122f26cc 100644 --- a/java/tests/com/facebook/yoga/YGAlignContentTest.java +++ b/java/tests/com/facebook/yoga/YGAlignContentTest.java @@ -116,17 +116,14 @@ public class YGAlignContentTest { } @Test - public void test_align_content_flex_end() { + public void test_align_content_flex_start_without_height_on_children() { final YogaNode root = new YogaNode(); - root.setFlexDirection(YogaFlexDirection.ROW); - root.setAlignContent(YogaAlign.FLEX_END); root.setWrap(YogaWrap.WRAP); - root.setWidth(130f); + root.setWidth(100f); root.setHeight(100f); final YogaNode root_child0 = new YogaNode(); root_child0.setWidth(50f); - root_child0.setHeight(10f); root.addChildAt(root_child0, 0); final YogaNode root_child1 = new YogaNode(); @@ -136,7 +133,6 @@ public class YGAlignContentTest { final YogaNode root_child2 = new YogaNode(); root_child2.setWidth(50f); - root_child2.setHeight(10f); root.addChildAt(root_child2, 2); final YogaNode root_child3 = new YogaNode(); @@ -146,82 +142,181 @@ public class YGAlignContentTest { final YogaNode root_child4 = new YogaNode(); root_child4.setWidth(50f); - root_child4.setHeight(10f); root.addChildAt(root_child4, 4); root.setDirection(YogaDirection.LTR); root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); assertEquals(0f, root.getLayoutX(), 0.0f); assertEquals(0f, root.getLayoutY(), 0.0f); - assertEquals(130f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); assertEquals(100f, root.getLayoutHeight(), 0.0f); assertEquals(0f, root_child0.getLayoutX(), 0.0f); - assertEquals(70f, root_child0.getLayoutY(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); - assertEquals(10f, root_child0.getLayoutHeight(), 0.0f); + assertEquals(0f, root_child0.getLayoutHeight(), 0.0f); - assertEquals(50f, root_child1.getLayoutX(), 0.0f); - assertEquals(70f, root_child1.getLayoutY(), 0.0f); + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); assertEquals(10f, root_child1.getLayoutHeight(), 0.0f); assertEquals(0f, root_child2.getLayoutX(), 0.0f); - assertEquals(80f, root_child2.getLayoutY(), 0.0f); + assertEquals(10f, root_child2.getLayoutY(), 0.0f); assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); - assertEquals(10f, root_child2.getLayoutHeight(), 0.0f); + assertEquals(0f, root_child2.getLayoutHeight(), 0.0f); - assertEquals(50f, root_child3.getLayoutX(), 0.0f); - assertEquals(80f, root_child3.getLayoutY(), 0.0f); + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(10f, root_child3.getLayoutY(), 0.0f); assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); assertEquals(10f, root_child3.getLayoutHeight(), 0.0f); assertEquals(0f, root_child4.getLayoutX(), 0.0f); - assertEquals(90f, root_child4.getLayoutY(), 0.0f); + assertEquals(20f, root_child4.getLayoutY(), 0.0f); assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); - assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); + assertEquals(0f, root_child4.getLayoutHeight(), 0.0f); root.setDirection(YogaDirection.RTL); root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); assertEquals(0f, root.getLayoutX(), 0.0f); assertEquals(0f, root.getLayoutY(), 0.0f); - assertEquals(130f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); assertEquals(100f, root.getLayoutHeight(), 0.0f); - assertEquals(80f, root_child0.getLayoutX(), 0.0f); - assertEquals(70f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); - assertEquals(10f, root_child0.getLayoutHeight(), 0.0f); + assertEquals(0f, root_child0.getLayoutHeight(), 0.0f); - assertEquals(30f, root_child1.getLayoutX(), 0.0f); - assertEquals(70f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); assertEquals(10f, root_child1.getLayoutHeight(), 0.0f); - assertEquals(80f, root_child2.getLayoutX(), 0.0f); - assertEquals(80f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(10f, root_child2.getLayoutY(), 0.0f); assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); - assertEquals(10f, root_child2.getLayoutHeight(), 0.0f); + assertEquals(0f, root_child2.getLayoutHeight(), 0.0f); - assertEquals(30f, root_child3.getLayoutX(), 0.0f); - assertEquals(80f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(10f, root_child3.getLayoutY(), 0.0f); assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); assertEquals(10f, root_child3.getLayoutHeight(), 0.0f); - assertEquals(80f, root_child4.getLayoutX(), 0.0f); - assertEquals(90f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(20f, root_child4.getLayoutY(), 0.0f); assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); - assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); + assertEquals(0f, root_child4.getLayoutHeight(), 0.0f); } @Test - public void test_align_content_center() { + public void test_align_content_flex_start_with_flex() { final YogaNode root = new YogaNode(); - root.setFlexDirection(YogaFlexDirection.ROW); - root.setAlignContent(YogaAlign.CENTER); root.setWrap(YogaWrap.WRAP); - root.setWidth(130f); + root.setWidth(100f); + root.setHeight(120f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setFlexGrow(1f); + root_child0.setFlexBasisPercent(0f); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexGrow(1f); + root_child1.setFlexBasisPercent(0f); + root_child1.setWidth(50f); + root_child1.setHeight(10f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setFlexGrow(1f); + root_child3.setFlexShrink(1f); + root_child3.setFlexBasisPercent(0f); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(120f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(80f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(80f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child4.getLayoutX(), 0.0f); + assertEquals(120f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(120f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(80f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(80f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(120f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_flex_end() { + final YogaNode root = new YogaNode(); + root.setAlignContent(YogaAlign.FLEX_END); + root.setWrap(YogaWrap.WRAP); + root.setWidth(100f); root.setHeight(100f); final YogaNode root_child0 = new YogaNode(); @@ -253,31 +348,31 @@ public class YGAlignContentTest { assertEquals(0f, root.getLayoutX(), 0.0f); assertEquals(0f, root.getLayoutY(), 0.0f); - assertEquals(130f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); assertEquals(100f, root.getLayoutHeight(), 0.0f); assertEquals(0f, root_child0.getLayoutX(), 0.0f); - assertEquals(35f, root_child0.getLayoutY(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); assertEquals(10f, root_child0.getLayoutHeight(), 0.0f); - assertEquals(50f, root_child1.getLayoutX(), 0.0f); - assertEquals(35f, root_child1.getLayoutY(), 0.0f); + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(10f, root_child1.getLayoutY(), 0.0f); assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); assertEquals(10f, root_child1.getLayoutHeight(), 0.0f); assertEquals(0f, root_child2.getLayoutX(), 0.0f); - assertEquals(45f, root_child2.getLayoutY(), 0.0f); + assertEquals(20f, root_child2.getLayoutY(), 0.0f); assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); assertEquals(10f, root_child2.getLayoutHeight(), 0.0f); - assertEquals(50f, root_child3.getLayoutX(), 0.0f); - assertEquals(45f, root_child3.getLayoutY(), 0.0f); + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(30f, root_child3.getLayoutY(), 0.0f); assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); assertEquals(10f, root_child3.getLayoutHeight(), 0.0f); assertEquals(0f, root_child4.getLayoutX(), 0.0f); - assertEquals(55f, root_child4.getLayoutY(), 0.0f); + assertEquals(40f, root_child4.getLayoutY(), 0.0f); assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); @@ -286,31 +381,31 @@ public class YGAlignContentTest { assertEquals(0f, root.getLayoutX(), 0.0f); assertEquals(0f, root.getLayoutY(), 0.0f); - assertEquals(130f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); assertEquals(100f, root.getLayoutHeight(), 0.0f); - assertEquals(80f, root_child0.getLayoutX(), 0.0f); - assertEquals(35f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); assertEquals(10f, root_child0.getLayoutHeight(), 0.0f); - assertEquals(30f, root_child1.getLayoutX(), 0.0f); - assertEquals(35f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(10f, root_child1.getLayoutY(), 0.0f); assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); assertEquals(10f, root_child1.getLayoutHeight(), 0.0f); - assertEquals(80f, root_child2.getLayoutX(), 0.0f); - assertEquals(45f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child2.getLayoutY(), 0.0f); assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); assertEquals(10f, root_child2.getLayoutHeight(), 0.0f); - assertEquals(30f, root_child3.getLayoutX(), 0.0f); - assertEquals(45f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(30f, root_child3.getLayoutY(), 0.0f); assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); assertEquals(10f, root_child3.getLayoutHeight(), 0.0f); - assertEquals(80f, root_child4.getLayoutX(), 0.0f); - assertEquals(55f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(40f, root_child4.getLayoutY(), 0.0f); assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); } @@ -609,4 +704,1071 @@ public class YGAlignContentTest { assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); } + @Test + public void test_align_content_stretch_row() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_children() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.setFlexGrow(1f); + root_child0_child0.setFlexShrink(1f); + root_child0_child0.setFlexBasisPercent(0f); + root_child0.addChildAt(root_child0_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_flex() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexGrow(1f); + root_child1.setFlexShrink(1f); + root_child1.setFlexBasisPercent(0f); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setFlexGrow(1f); + root_child3.setFlexShrink(1f); + root_child3.setFlexBasisPercent(0f); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(0f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(0f, root_child3.getLayoutY(), 0.0f); + assertEquals(0f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child4.getLayoutX(), 0.0f); + assertEquals(0f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(0f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(0f, root_child3.getLayoutY(), 0.0f); + assertEquals(0f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child4.getLayoutX(), 0.0f); + assertEquals(0f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_flex_no_shrink() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexGrow(1f); + root_child1.setFlexShrink(1f); + root_child1.setFlexBasisPercent(0f); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setFlexGrow(1f); + root_child3.setFlexBasisPercent(0f); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(0f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(0f, root_child3.getLayoutY(), 0.0f); + assertEquals(0f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child4.getLayoutX(), 0.0f); + assertEquals(0f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(0f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(0f, root_child3.getLayoutY(), 0.0f); + assertEquals(0f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child4.getLayoutX(), 0.0f); + assertEquals(0f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_margin() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setMargin(YogaEdge.LEFT, 10f); + root_child1.setMargin(YogaEdge.TOP, 10f); + root_child1.setMargin(YogaEdge.RIGHT, 10f); + root_child1.setMargin(YogaEdge.BOTTOM, 10f); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setMargin(YogaEdge.LEFT, 10f); + root_child3.setMargin(YogaEdge.TOP, 10f); + root_child3.setMargin(YogaEdge.RIGHT, 10f); + root_child3.setMargin(YogaEdge.BOTTOM, 10f); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(60f, root_child1.getLayoutX(), 0.0f); + assertEquals(10f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(40f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(60f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child4.getLayoutX(), 0.0f); + assertEquals(80f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(10f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(40f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(40f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child4.getLayoutX(), 0.0f); + assertEquals(80f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_padding() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setPadding(YogaEdge.LEFT, 10); + root_child1.setPadding(YogaEdge.TOP, 10); + root_child1.setPadding(YogaEdge.RIGHT, 10); + root_child1.setPadding(YogaEdge.BOTTOM, 10); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setPadding(YogaEdge.LEFT, 10); + root_child3.setPadding(YogaEdge.TOP, 10); + root_child3.setPadding(YogaEdge.RIGHT, 10); + root_child3.setPadding(YogaEdge.BOTTOM, 10); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_single_row() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_fixed_height() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(60f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(80f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(80f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(80f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(80f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(80f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(80f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(80f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(80f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_max_height() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setMaxHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(50f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(50f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_row_with_min_height() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setMinHeight(80f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setWidth(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(90f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(90f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(90f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(90f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(90f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(90f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(90f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(90f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child3.getLayoutX(), 0.0f); + assertEquals(90f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(90f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child4.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_column() { + final YogaNode root = new YogaNode(); + root.setAlignContent(YogaAlign.STRETCH); + root.setWrap(YogaWrap.WRAP); + root.setWidth(100f); + root.setHeight(150f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.setFlexGrow(1f); + root_child0_child0.setFlexShrink(1f); + root_child0_child0.setFlexBasisPercent(0f); + root_child0.addChildAt(root_child0_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexGrow(1f); + root_child1.setFlexShrink(1f); + root_child1.setFlexBasisPercent(0f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setHeight(50f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setHeight(50f); + root.addChildAt(root_child3, 3); + + final YogaNode root_child4 = new YogaNode(); + root_child4.setHeight(50f); + root.addChildAt(root_child4, 4); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(150f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(50f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(100f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child4.getLayoutX(), 0.0f); + assertEquals(0f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(150f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(0f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(50f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(100f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child4.getLayoutX(), 0.0f); + assertEquals(0f, root_child4.getLayoutY(), 0.0f); + assertEquals(50f, root_child4.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child4.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/yoga/YGFlexWrapTest.java b/java/tests/com/facebook/yoga/YGFlexWrapTest.java index 6ef0d1f2..5ab76b1e 100644 --- a/java/tests/com/facebook/yoga/YGFlexWrapTest.java +++ b/java/tests/com/facebook/yoga/YGFlexWrapTest.java @@ -404,4 +404,136 @@ public class YGFlexWrapTest { assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); } + @Test + public void test_flex_wrap_wrap_to_child_height() { + final YogaNode root = new YogaNode(); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setFlexDirection(YogaFlexDirection.ROW); + root_child0.setAlignItems(YogaAlign.FLEX_START); + root_child0.setWrap(YogaWrap.WRAP); + root.addChildAt(root_child0, 0); + + final YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.setWidth(100f); + root_child0.addChildAt(root_child0_child0, 0); + + final YogaNode root_child0_child0_child0 = new YogaNode(); + root_child0_child0_child0.setWidth(100f); + root_child0_child0_child0.setHeight(100f); + root_child0_child0.addChildAt(root_child0_child0_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(100f); + root_child1.setHeight(100f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(100f, root_child1.getLayoutY(), 0.0f); + assertEquals(100f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0_child0.getLayoutY(), 0.0f); + assertEquals(100f, root_child0_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(100f, root_child1.getLayoutY(), 0.0f); + assertEquals(100f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_flex_wrap_align_stretch_fits_one_row() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setWrap(YogaWrap.WRAP); + root.setWidth(150f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(150f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/yoga/YGMarginTest.java b/java/tests/com/facebook/yoga/YGMarginTest.java index 8b6a159c..db792587 100644 --- a/java/tests/com/facebook/yoga/YGMarginTest.java +++ b/java/tests/com/facebook/yoga/YGMarginTest.java @@ -425,4 +425,745 @@ public class YGMarginTest { assertEquals(45f, root_child1.getLayoutHeight(), 0.0f); } + @Test + public void test_margin_auto_bottom() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.BOTTOM); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_top() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.TOP); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(100f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(100f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_bottom_and_top() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.TOP); + root_child0.setMarginAuto(YogaEdge.BOTTOM); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(50f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(50f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_bottom_and_top_justify_center() { + final YogaNode root = new YogaNode(); + root.setJustifyContent(YogaJustify.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.TOP); + root_child0.setMarginAuto(YogaEdge.BOTTOM); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(50f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(50f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_mutiple_children_column() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.TOP); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setMarginAuto(YogaEdge.TOP); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root_child2.setHeight(50f); + root.addChildAt(root_child2, 2); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(25f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(100f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child2.getLayoutX(), 0.0f); + assertEquals(150f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(25f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(100f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child2.getLayoutX(), 0.0f); + assertEquals(150f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_mutiple_children_row() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setMarginAuto(YogaEdge.RIGHT); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root_child2.setHeight(50f); + root.addChildAt(root_child2, 2); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(75f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(75f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child2.getLayoutX(), 0.0f); + assertEquals(75f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(125f, root_child0.getLayoutX(), 0.0f); + assertEquals(75f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(75f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(75f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_left_and_right_column() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.LEFT); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(75f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(75f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(75f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(75f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_left_and_right() { + final YogaNode root = new YogaNode(); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.LEFT); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_left_and_right_column_and_center() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.LEFT); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_left() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.LEFT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_right() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.CENTER); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_left_and_right_strech() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.LEFT); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_margin_auto_top_and_bottom_strech() { + final YogaNode root = new YogaNode(); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMarginAuto(YogaEdge.TOP); + root_child0.setMarginAuto(YogaEdge.BOTTOM); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(50f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(50f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/yoga/YogaValueTest.java b/java/tests/com/facebook/yoga/YogaValueTest.java index e299ecbc..2d0d242b 100644 --- a/java/tests/com/facebook/yoga/YogaValueTest.java +++ b/java/tests/com/facebook/yoga/YogaValueTest.java @@ -18,9 +18,9 @@ public class YogaValueTest { @Test public void testEquals() { assertEquals(new YogaValue(0, YogaUnit.UNDEFINED), new YogaValue(0, YogaUnit.UNDEFINED)); - assertEquals(new YogaValue(0, YogaUnit.PIXEL), new YogaValue(0, YogaUnit.PIXEL)); + assertEquals(new YogaValue(0, YogaUnit.POINT), new YogaValue(0, YogaUnit.POINT)); assertEquals(new YogaValue(0, YogaUnit.PERCENT), new YogaValue(0, YogaUnit.PERCENT)); assertEquals(new YogaValue(0, YogaUnit.UNDEFINED), new YogaValue(1, YogaUnit.UNDEFINED)); - assertEquals(new YogaValue(Float.NaN, YogaUnit.PIXEL), new YogaValue(Float.NaN, YogaUnit.PIXEL)); + assertEquals(new YogaValue(Float.NaN, YogaUnit.POINT), new YogaValue(Float.NaN, YogaUnit.POINT)); } } diff --git a/javascript/sources/Node.cc b/javascript/sources/Node.cc index 65305218..d7e2ddd1 100644 --- a/javascript/sources/Node.cc +++ b/javascript/sources/Node.cc @@ -119,6 +119,11 @@ void Node::setMarginPercent(int edge, double margin) YGNodeStyleSetMarginPercent(m_node, static_cast(edge), margin); } +void Node::setMarginAuto(int edge) +{ + YGNodeStyleSetMarginAuto(m_node, static_cast(edge)); +} + void Node::setOverflow(int overflow) { YGNodeStyleSetOverflow(m_node, static_cast(overflow)); @@ -164,6 +169,11 @@ void Node::setWidthPercent(double width) YGNodeStyleSetWidthPercent(m_node, width); } +void Node::setWidthAuto() +{ + YGNodeStyleSetWidthAuto(m_node); +} + void Node::setHeight(double height) { YGNodeStyleSetHeight(m_node, height); @@ -174,6 +184,11 @@ void Node::setHeightPercent(double height) YGNodeStyleSetHeightPercent(m_node, height); } +void Node::setHeightAuto() +{ + YGNodeStyleSetHeightAuto(m_node); +} + void Node::setMinWidth(double minWidth) { YGNodeStyleSetMinWidth(m_node, minWidth); diff --git a/javascript/sources/Node.hh b/javascript/sources/Node.hh index e861d8b3..7ee3f76d 100644 --- a/javascript/sources/Node.hh +++ b/javascript/sources/Node.hh @@ -65,6 +65,7 @@ class Node { void setMargin(int edge, double margin); void setMarginPercent(int edge, double margin); + void setMarginAuto(int edge); void setOverflow(int overflow); void setDisplay(int display); @@ -72,13 +73,16 @@ class Node { void setFlex(double flex); void setFlexBasis(double flexBasis); void setFlexBasisPercent(double flexBasis); + void setFlexBasisAuto(); void setFlexGrow(double flexGrow); void setFlexShrink(double flexShrink); void setWidth(double width); void setWidthPercent(double width); + void setWidthAuto(); void setHeight(double height); void setHeightPercent(double height); + void setHeightAuto(); void setMinWidth(double minWidth); void setMinWidthPercent(double minWidth); diff --git a/javascript/sources/YGEnums.js b/javascript/sources/YGEnums.js index 929a968d..af39cf39 100644 --- a/javascript/sources/YGEnums.js +++ b/javascript/sources/YGEnums.js @@ -86,10 +86,11 @@ module.exports = { PRINT_OPTIONS_STYLE: 2, PRINT_OPTIONS_CHILDREN: 4, - UNIT_COUNT: 3, + UNIT_COUNT: 4, UNIT_UNDEFINED: 0, - UNIT_PIXEL: 1, + UNIT_POINT: 1, UNIT_PERCENT: 2, + UNIT_AUTO: 3, WRAP_COUNT: 2, WRAP_NO_WRAP: 0, diff --git a/javascript/sources/entry-common.js b/javascript/sources/entry-common.js index c4161663..103596cb 100644 --- a/javascript/sources/entry-common.js +++ b/javascript/sources/entry-common.js @@ -102,11 +102,14 @@ module.exports = function (bind, lib) { switch (this.unit) { - case constants.UNIT_PIXEL: + case constants.UNIT_POINT: return `${this.value}`; case constants.UNIT_PERCENT: return `${this.value}%`; + + case constants.UNIT_AUTO: + return `auto`; default: { return `${this.value}?`; @@ -126,7 +129,7 @@ module.exports = function (bind, lib) { for (let fnName of [ `setPosition`, `setMargin`, `setFlexBasis`, `setWidth`, `setHeight`, `setMinWidth`, `setMinHeight`, `setMaxWidth`, `setMaxHeight`, `setPadding` ]) { - let methods = { [constants.UNIT_PIXEL]: lib.Node.prototype[fnName], [constants.UNIT_PERCENT]: lib.Node.prototype[`${fnName}Percent`] }; + let methods = { [constants.UNIT_POINT]: lib.Node.prototype[fnName], [constants.UNIT_PERCENT]: lib.Node.prototype[`${fnName}Percent`] }; if (Object.keys(methods).some(method => methods[method] == null)) throw new Error(`Assertion failed; some unit derivates of ${fnName} seem missing`); @@ -146,7 +149,7 @@ module.exports = function (bind, lib) { } else { - unit = typeof value === `string` && value.endsWith(`%`) ? constants.UNIT_PERCENT : constants.UNIT_PIXEL; + unit = typeof value === `string` && value.endsWith(`%`) ? constants.UNIT_PERCENT : constants.UNIT_POINT; asNumber = parseFloat(value); } diff --git a/javascript/sources/nbind.cc b/javascript/sources/nbind.cc index 7e65c285..c15d0567 100644 --- a/javascript/sources/nbind.cc +++ b/javascript/sources/nbind.cc @@ -65,6 +65,7 @@ NBIND_CLASS(Node) method(setMargin); method(setMarginPercent); + method(setMarginAuto); method(setOverflow); method(setDisplay); @@ -77,8 +78,10 @@ NBIND_CLASS(Node) method(setWidth); method(setWidthPercent); + method(setWidthAuto); method(setHeight); method(setHeightPercent); + method(setHeightAuto); method(setMinWidth); method(setMinWidthPercent); diff --git a/javascript/tests/Facebook.Yoga/YGAlignContentTest.js b/javascript/tests/Facebook.Yoga/YGAlignContentTest.js index 14cf9820..d18fce9a 100644 --- a/javascript/tests/Facebook.Yoga/YGAlignContentTest.js +++ b/javascript/tests/Facebook.Yoga/YGAlignContentTest.js @@ -112,17 +112,14 @@ it("align_content_flex_start", function () { (typeof gc !== "undefined") && gc(); console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); }); -it("align_content_flex_end", function () { +it("align_content_flex_start_without_height_on_children", function () { var root = Yoga.Node.create(); - root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); - root.setAlignContent(Yoga.ALIGN_FLEX_END); root.setFlexWrap(Yoga.WRAP_WRAP); - root.setWidth(130); + root.setWidth(100); root.setHeight(100); var root_child0 = Yoga.Node.create(); root_child0.setWidth(50); - root_child0.setHeight(10); root.insertChild(root_child0, 0); var root_child1 = Yoga.Node.create(); @@ -132,7 +129,6 @@ it("align_content_flex_end", function () { var root_child2 = Yoga.Node.create(); root_child2.setWidth(50); - root_child2.setHeight(10); root.insertChild(root_child2, 2); var root_child3 = Yoga.Node.create(); @@ -142,71 +138,70 @@ it("align_content_flex_end", function () { var root_child4 = Yoga.Node.create(); root_child4.setWidth(50); - root_child4.setHeight(10); root.insertChild(root_child4, 4); root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); - console.assert(130 === root.getComputedWidth(), "130 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); - console.assert(70 === root_child0.getComputedTop(), "70 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); - console.assert(10 === root_child0.getComputedHeight(), "10 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); - console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); - console.assert(70 === root_child1.getComputedTop(), "70 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); console.assert(10 === root_child1.getComputedHeight(), "10 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); - console.assert(80 === root_child2.getComputedTop(), "80 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(10 === root_child2.getComputedTop(), "10 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); - console.assert(10 === root_child2.getComputedHeight(), "10 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + console.assert(0 === root_child2.getComputedHeight(), "0 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); - console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); - console.assert(80 === root_child3.getComputedTop(), "80 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(10 === root_child3.getComputedTop(), "10 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); console.assert(10 === root_child3.getComputedHeight(), "10 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); - console.assert(90 === root_child4.getComputedTop(), "90 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(20 === root_child4.getComputedTop(), "20 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); - console.assert(10 === root_child4.getComputedHeight(), "10 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + console.assert(0 === root_child4.getComputedHeight(), "0 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); - console.assert(130 === root.getComputedWidth(), "130 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); - console.assert(80 === root_child0.getComputedLeft(), "80 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); - console.assert(70 === root_child0.getComputedTop(), "70 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedLeft(), "50 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); - console.assert(10 === root_child0.getComputedHeight(), "10 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); - console.assert(30 === root_child1.getComputedLeft(), "30 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); - console.assert(70 === root_child1.getComputedTop(), "70 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); console.assert(10 === root_child1.getComputedHeight(), "10 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); - console.assert(80 === root_child2.getComputedLeft(), "80 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); - console.assert(80 === root_child2.getComputedTop(), "80 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(10 === root_child2.getComputedTop(), "10 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); - console.assert(10 === root_child2.getComputedHeight(), "10 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + console.assert(0 === root_child2.getComputedHeight(), "0 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); - console.assert(30 === root_child3.getComputedLeft(), "30 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); - console.assert(80 === root_child3.getComputedTop(), "80 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(10 === root_child3.getComputedTop(), "10 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); console.assert(10 === root_child3.getComputedHeight(), "10 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); - console.assert(80 === root_child4.getComputedLeft(), "80 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); - console.assert(90 === root_child4.getComputedTop(), "90 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(20 === root_child4.getComputedTop(), "20 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); - console.assert(10 === root_child4.getComputedHeight(), "10 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + console.assert(0 === root_child4.getComputedHeight(), "0 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); if (typeof root !== "undefined") root.freeRecursive(); @@ -214,12 +209,114 @@ it("align_content_flex_end", function () { (typeof gc !== "undefined") && gc(); console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); }); -it("align_content_center", function () { +it("align_content_flex_start_with_flex", function () { var root = Yoga.Node.create(); - root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); - root.setAlignContent(Yoga.ALIGN_CENTER); root.setFlexWrap(Yoga.WRAP_WRAP); - root.setWidth(130); + root.setWidth(100); + root.setHeight(120); + + var root_child0 = Yoga.Node.create(); + root_child0.setFlexGrow(1); + root_child0.setFlexBasis("0%"); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setFlexGrow(1); + root_child1.setFlexBasis("0%"); + root_child1.setWidth(50); + root_child1.setHeight(10); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setFlexGrow(1); + root_child3.setFlexShrink(1); + root_child3.setFlexBasis("0%"); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(120 === root.getComputedHeight(), "120 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(40 === root_child0.getComputedHeight(), "40 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(40 === root_child1.getComputedTop(), "40 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(40 === root_child1.getComputedHeight(), "40 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(80 === root_child2.getComputedTop(), "80 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(0 === root_child2.getComputedHeight(), "0 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(80 === root_child3.getComputedTop(), "80 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(40 === root_child3.getComputedHeight(), "40 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(120 === root_child4.getComputedTop(), "120 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(0 === root_child4.getComputedHeight(), "0 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(120 === root.getComputedHeight(), "120 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(50 === root_child0.getComputedLeft(), "50 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(40 === root_child0.getComputedHeight(), "40 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(40 === root_child1.getComputedTop(), "40 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(40 === root_child1.getComputedHeight(), "40 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(80 === root_child2.getComputedTop(), "80 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(0 === root_child2.getComputedHeight(), "0 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(80 === root_child3.getComputedTop(), "80 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(40 === root_child3.getComputedHeight(), "40 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(120 === root_child4.getComputedTop(), "120 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(0 === root_child4.getComputedHeight(), "0 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_flex_end", function () { + var root = Yoga.Node.create(); + root.setAlignContent(Yoga.ALIGN_FLEX_END); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(100); root.setHeight(100); var root_child0 = Yoga.Node.create(); @@ -250,31 +347,31 @@ it("align_content_center", function () { console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); - console.assert(130 === root.getComputedWidth(), "130 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); - console.assert(35 === root_child0.getComputedTop(), "35 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); console.assert(10 === root_child0.getComputedHeight(), "10 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); - console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); - console.assert(35 === root_child1.getComputedTop(), "35 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(10 === root_child1.getComputedTop(), "10 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); console.assert(10 === root_child1.getComputedHeight(), "10 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); - console.assert(45 === root_child2.getComputedTop(), "45 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(20 === root_child2.getComputedTop(), "20 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); console.assert(10 === root_child2.getComputedHeight(), "10 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); - console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); - console.assert(45 === root_child3.getComputedTop(), "45 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(30 === root_child3.getComputedTop(), "30 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); console.assert(10 === root_child3.getComputedHeight(), "10 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); - console.assert(55 === root_child4.getComputedTop(), "55 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(40 === root_child4.getComputedTop(), "40 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); console.assert(10 === root_child4.getComputedHeight(), "10 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); @@ -282,31 +379,31 @@ it("align_content_center", function () { console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); - console.assert(130 === root.getComputedWidth(), "130 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); - console.assert(80 === root_child0.getComputedLeft(), "80 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); - console.assert(35 === root_child0.getComputedTop(), "35 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedLeft(), "50 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); console.assert(10 === root_child0.getComputedHeight(), "10 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); - console.assert(30 === root_child1.getComputedLeft(), "30 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); - console.assert(35 === root_child1.getComputedTop(), "35 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(10 === root_child1.getComputedTop(), "10 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); console.assert(10 === root_child1.getComputedHeight(), "10 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); - console.assert(80 === root_child2.getComputedLeft(), "80 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); - console.assert(45 === root_child2.getComputedTop(), "45 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(20 === root_child2.getComputedTop(), "20 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); console.assert(10 === root_child2.getComputedHeight(), "10 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); - console.assert(30 === root_child3.getComputedLeft(), "30 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); - console.assert(45 === root_child3.getComputedTop(), "45 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(30 === root_child3.getComputedTop(), "30 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); console.assert(10 === root_child3.getComputedHeight(), "10 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); - console.assert(80 === root_child4.getComputedLeft(), "80 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); - console.assert(55 === root_child4.getComputedTop(), "55 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(40 === root_child4.getComputedTop(), "40 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); console.assert(10 === root_child4.getComputedHeight(), "10 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); @@ -616,3 +713,1092 @@ it("align_content_spacearound", function () { (typeof gc !== "undefined") && gc(); console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); }); +it("align_content_stretch_row", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_children", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child0_child0 = Yoga.Node.create(); + root_child0_child0.setFlexGrow(1); + root_child0_child0.setFlexShrink(1); + root_child0_child0.setFlexBasis("0%"); + root_child0.insertChild(root_child0_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")"); + console.assert(50 === root_child0_child0.getComputedWidth(), "50 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0_child0.getComputedHeight(), "50 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")"); + console.assert(50 === root_child0_child0.getComputedWidth(), "50 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0_child0.getComputedHeight(), "50 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_flex", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setFlexGrow(1); + root_child1.setFlexShrink(1); + root_child1.setFlexBasis("0%"); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setFlexGrow(1); + root_child3.setFlexShrink(1); + root_child3.setFlexBasis("0%"); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(0 === root_child1.getComputedWidth(), "0 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(100 === root_child2.getComputedHeight(), "100 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(0 === root_child3.getComputedTop(), "0 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(0 === root_child3.getComputedWidth(), "0 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(100 === root_child3.getComputedHeight(), "100 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(100 === root_child4.getComputedLeft(), "100 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(0 === root_child4.getComputedTop(), "0 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(100 === root_child4.getComputedHeight(), "100 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(100 === root_child1.getComputedLeft(), "100 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(0 === root_child1.getComputedWidth(), "0 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(100 === root_child2.getComputedHeight(), "100 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(0 === root_child3.getComputedTop(), "0 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(0 === root_child3.getComputedWidth(), "0 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(100 === root_child3.getComputedHeight(), "100 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(0 === root_child4.getComputedTop(), "0 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(100 === root_child4.getComputedHeight(), "100 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_flex_no_shrink", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setFlexGrow(1); + root_child1.setFlexShrink(1); + root_child1.setFlexBasis("0%"); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setFlexGrow(1); + root_child3.setFlexBasis("0%"); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(0 === root_child1.getComputedWidth(), "0 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(100 === root_child2.getComputedHeight(), "100 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(0 === root_child3.getComputedTop(), "0 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(0 === root_child3.getComputedWidth(), "0 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(100 === root_child3.getComputedHeight(), "100 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(100 === root_child4.getComputedLeft(), "100 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(0 === root_child4.getComputedTop(), "0 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(100 === root_child4.getComputedHeight(), "100 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(100 === root_child1.getComputedLeft(), "100 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(0 === root_child1.getComputedWidth(), "0 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(100 === root_child2.getComputedHeight(), "100 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(0 === root_child3.getComputedTop(), "0 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(0 === root_child3.getComputedWidth(), "0 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(100 === root_child3.getComputedHeight(), "100 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(0 === root_child4.getComputedTop(), "0 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(100 === root_child4.getComputedHeight(), "100 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_margin", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setMargin(Yoga.EDGE_LEFT, 10); + root_child1.setMargin(Yoga.EDGE_TOP, 10); + root_child1.setMargin(Yoga.EDGE_RIGHT, 10); + root_child1.setMargin(Yoga.EDGE_BOTTOM, 10); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setMargin(Yoga.EDGE_LEFT, 10); + root_child3.setMargin(Yoga.EDGE_TOP, 10); + root_child3.setMargin(Yoga.EDGE_RIGHT, 10); + root_child3.setMargin(Yoga.EDGE_BOTTOM, 10); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(40 === root_child0.getComputedHeight(), "40 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(60 === root_child1.getComputedLeft(), "60 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(10 === root_child1.getComputedTop(), "10 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(20 === root_child1.getComputedHeight(), "20 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(40 === root_child2.getComputedTop(), "40 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(40 === root_child2.getComputedHeight(), "40 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(60 === root_child3.getComputedLeft(), "60 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(20 === root_child3.getComputedHeight(), "20 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(80 === root_child4.getComputedTop(), "80 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(20 === root_child4.getComputedHeight(), "20 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(40 === root_child0.getComputedHeight(), "40 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(40 === root_child1.getComputedLeft(), "40 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(10 === root_child1.getComputedTop(), "10 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(20 === root_child1.getComputedHeight(), "20 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(40 === root_child2.getComputedTop(), "40 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(40 === root_child2.getComputedHeight(), "40 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(40 === root_child3.getComputedLeft(), "40 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(20 === root_child3.getComputedHeight(), "20 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(100 === root_child4.getComputedLeft(), "100 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(80 === root_child4.getComputedTop(), "80 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(20 === root_child4.getComputedHeight(), "20 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_padding", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setPadding(Yoga.EDGE_LEFT, 10); + root_child1.setPadding(Yoga.EDGE_TOP, 10); + root_child1.setPadding(Yoga.EDGE_RIGHT, 10); + root_child1.setPadding(Yoga.EDGE_BOTTOM, 10); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setPadding(Yoga.EDGE_LEFT, 10); + root_child3.setPadding(Yoga.EDGE_TOP, 10); + root_child3.setPadding(Yoga.EDGE_RIGHT, 10); + root_child3.setPadding(Yoga.EDGE_BOTTOM, 10); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_single_row", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_fixed_height", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(60); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(80 === root_child0.getComputedHeight(), "80 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(60 === root_child1.getComputedHeight(), "60 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(80 === root_child2.getComputedHeight(), "80 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(80 === root_child3.getComputedTop(), "80 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(20 === root_child3.getComputedHeight(), "20 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(80 === root_child4.getComputedTop(), "80 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(20 === root_child4.getComputedHeight(), "20 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(80 === root_child0.getComputedHeight(), "80 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(60 === root_child1.getComputedHeight(), "60 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(80 === root_child2.getComputedHeight(), "80 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(80 === root_child3.getComputedTop(), "80 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(20 === root_child3.getComputedHeight(), "20 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(80 === root_child4.getComputedTop(), "80 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(20 === root_child4.getComputedHeight(), "20 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_max_height", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setMaxHeight(20); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(20 === root_child1.getComputedHeight(), "20 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(20 === root_child1.getComputedHeight(), "20 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(50 === root_child3.getComputedTop(), "50 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(50 === root_child4.getComputedTop(), "50 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_row_with_min_height", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setMinHeight(80); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setWidth(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setWidth(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(90 === root_child0.getComputedHeight(), "90 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(90 === root_child1.getComputedHeight(), "90 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(100 === root_child2.getComputedLeft(), "100 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(90 === root_child2.getComputedHeight(), "90 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(90 === root_child3.getComputedTop(), "90 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(10 === root_child3.getComputedHeight(), "10 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(90 === root_child4.getComputedTop(), "90 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(10 === root_child4.getComputedHeight(), "10 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(90 === root_child0.getComputedHeight(), "90 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(90 === root_child1.getComputedHeight(), "90 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(0 === root_child2.getComputedTop(), "0 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(90 === root_child2.getComputedHeight(), "90 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(100 === root_child3.getComputedLeft(), "100 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(90 === root_child3.getComputedTop(), "90 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(10 === root_child3.getComputedHeight(), "10 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(90 === root_child4.getComputedTop(), "90 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(10 === root_child4.getComputedHeight(), "10 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("align_content_stretch_column", function () { + var root = Yoga.Node.create(); + root.setAlignContent(Yoga.ALIGN_STRETCH); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(100); + root.setHeight(150); + + var root_child0 = Yoga.Node.create(); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child0_child0 = Yoga.Node.create(); + root_child0_child0.setFlexGrow(1); + root_child0_child0.setFlexShrink(1); + root_child0_child0.setFlexBasis("0%"); + root_child0.insertChild(root_child0_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setFlexGrow(1); + root_child1.setFlexShrink(1); + root_child1.setFlexBasis("0%"); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setHeight(50); + root.insertChild(root_child2, 2); + + var root_child3 = Yoga.Node.create(); + root_child3.setHeight(50); + root.insertChild(root_child3, 3); + + var root_child4 = Yoga.Node.create(); + root_child4.setHeight(50); + root.insertChild(root_child4, 4); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(150 === root.getComputedHeight(), "150 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")"); + console.assert(50 === root_child0_child0.getComputedWidth(), "50 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0_child0.getComputedHeight(), "50 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(0 === root_child1.getComputedHeight(), "0 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(50 === root_child2.getComputedTop(), "50 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(0 === root_child3.getComputedLeft(), "0 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(100 === root_child3.getComputedTop(), "100 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(50 === root_child4.getComputedLeft(), "50 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(0 === root_child4.getComputedTop(), "0 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(150 === root.getComputedHeight(), "150 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(50 === root_child0.getComputedLeft(), "50 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")"); + console.assert(50 === root_child0_child0.getComputedWidth(), "50 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0_child0.getComputedHeight(), "50 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(0 === root_child1.getComputedHeight(), "0 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(50 === root_child2.getComputedLeft(), "50 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(50 === root_child2.getComputedTop(), "50 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + console.assert(50 === root_child3.getComputedLeft(), "50 === root_child3.getComputedLeft() (" + root_child3.getComputedLeft() + ")"); + console.assert(100 === root_child3.getComputedTop(), "100 === root_child3.getComputedTop() (" + root_child3.getComputedTop() + ")"); + console.assert(50 === root_child3.getComputedWidth(), "50 === root_child3.getComputedWidth() (" + root_child3.getComputedWidth() + ")"); + console.assert(50 === root_child3.getComputedHeight(), "50 === root_child3.getComputedHeight() (" + root_child3.getComputedHeight() + ")"); + + console.assert(0 === root_child4.getComputedLeft(), "0 === root_child4.getComputedLeft() (" + root_child4.getComputedLeft() + ")"); + console.assert(0 === root_child4.getComputedTop(), "0 === root_child4.getComputedTop() (" + root_child4.getComputedTop() + ")"); + console.assert(50 === root_child4.getComputedWidth(), "50 === root_child4.getComputedWidth() (" + root_child4.getComputedWidth() + ")"); + console.assert(50 === root_child4.getComputedHeight(), "50 === root_child4.getComputedHeight() (" + root_child4.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); diff --git a/javascript/tests/Facebook.Yoga/YGFlexWrapTest.js b/javascript/tests/Facebook.Yoga/YGFlexWrapTest.js index d2de9345..7048dbf8 100644 --- a/javascript/tests/Facebook.Yoga/YGFlexWrapTest.js +++ b/javascript/tests/Facebook.Yoga/YGFlexWrapTest.js @@ -409,3 +409,139 @@ it("flex_wrap_children_with_min_main_overriding_flex_basis", function () { (typeof gc !== "undefined") && gc(); console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); }); +it("flex_wrap_wrap_to_child_height", function () { + var root = Yoga.Node.create(); + + var root_child0 = Yoga.Node.create(); + root_child0.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root_child0.setAlignItems(Yoga.ALIGN_FLEX_START); + root_child0.setFlexWrap(Yoga.WRAP_WRAP); + root.insertChild(root_child0, 0); + + var root_child0_child0 = Yoga.Node.create(); + root_child0_child0.setWidth(100); + root_child0.insertChild(root_child0_child0, 0); + + var root_child0_child0_child0 = Yoga.Node.create(); + root_child0_child0_child0.setWidth(100); + root_child0_child0_child0.setHeight(100); + root_child0_child0.insertChild(root_child0_child0_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(100); + root_child1.setHeight(100); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(100 === root_child0.getComputedWidth(), "100 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")"); + console.assert(100 === root_child0_child0.getComputedWidth(), "100 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0_child0.getComputedHeight(), "100 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0_child0.getComputedLeft(), "0 === root_child0_child0_child0.getComputedLeft() (" + root_child0_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0_child0.getComputedTop(), "0 === root_child0_child0_child0.getComputedTop() (" + root_child0_child0_child0.getComputedTop() + ")"); + console.assert(100 === root_child0_child0_child0.getComputedWidth(), "100 === root_child0_child0_child0.getComputedWidth() (" + root_child0_child0_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0_child0_child0.getComputedHeight(), "100 === root_child0_child0_child0.getComputedHeight() (" + root_child0_child0_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(100 === root_child1.getComputedTop(), "100 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(100 === root_child1.getComputedWidth(), "100 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(100 === root_child0.getComputedWidth(), "100 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")"); + console.assert(100 === root_child0_child0.getComputedWidth(), "100 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0_child0.getComputedHeight(), "100 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child0_child0_child0.getComputedLeft(), "0 === root_child0_child0_child0.getComputedLeft() (" + root_child0_child0_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0_child0_child0.getComputedTop(), "0 === root_child0_child0_child0.getComputedTop() (" + root_child0_child0_child0.getComputedTop() + ")"); + console.assert(100 === root_child0_child0_child0.getComputedWidth(), "100 === root_child0_child0_child0.getComputedWidth() (" + root_child0_child0_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0_child0_child0.getComputedHeight(), "100 === root_child0_child0_child0.getComputedHeight() (" + root_child0_child0_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(100 === root_child1.getComputedTop(), "100 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(100 === root_child1.getComputedWidth(), "100 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("flex_wrap_align_stretch_fits_one_row", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setFlexWrap(Yoga.WRAP_WRAP); + root.setWidth(150); + root.setHeight(100); + + var root_child0 = Yoga.Node.create(); + root_child0.setWidth(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(150 === root.getComputedWidth(), "150 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(100 === root_child0.getComputedHeight(), "100 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(100 === root_child1.getComputedHeight(), "100 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); diff --git a/javascript/tests/Facebook.Yoga/YGMarginTest.js b/javascript/tests/Facebook.Yoga/YGMarginTest.js index 78fab2cf..4aefca2c 100644 --- a/javascript/tests/Facebook.Yoga/YGMarginTest.js +++ b/javascript/tests/Facebook.Yoga/YGMarginTest.js @@ -440,3 +440,770 @@ it("margin_with_sibling_column", function () { (typeof gc !== "undefined") && gc(); console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); }); +it("margin_auto_bottom", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_BOTTOM, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_top", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_TOP, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(100 === root_child0.getComputedTop(), "100 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(100 === root_child0.getComputedTop(), "100 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_bottom_and_top", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_TOP, "auto"); + root_child0.setMargin(Yoga.EDGE_BOTTOM, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(50 === root_child0.getComputedTop(), "50 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(50 === root_child0.getComputedTop(), "50 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_bottom_and_top_justify_center", function () { + var root = Yoga.Node.create(); + root.setJustifyContent(Yoga.JUSTIFY_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_TOP, "auto"); + root_child0.setMargin(Yoga.EDGE_BOTTOM, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(50 === root_child0.getComputedTop(), "50 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(150 === root_child0.getComputedLeft(), "150 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(50 === root_child0.getComputedTop(), "50 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(150 === root_child1.getComputedLeft(), "150 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_mutiple_children_column", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_TOP, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setMargin(Yoga.EDGE_TOP, "auto"); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root_child2.setHeight(50); + root.insertChild(root_child2, 2); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(25 === root_child0.getComputedTop(), "25 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(100 === root_child1.getComputedTop(), "100 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(75 === root_child2.getComputedLeft(), "75 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(150 === root_child2.getComputedTop(), "150 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(25 === root_child0.getComputedTop(), "25 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(100 === root_child1.getComputedTop(), "100 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(75 === root_child2.getComputedLeft(), "75 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(150 === root_child2.getComputedTop(), "150 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_mutiple_children_row", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + + var root_child2 = Yoga.Node.create(); + root_child2.setWidth(50); + root_child2.setHeight(50); + root.insertChild(root_child2, 2); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(75 === root_child0.getComputedTop(), "75 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(75 === root_child1.getComputedTop(), "75 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(150 === root_child2.getComputedLeft(), "150 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(75 === root_child2.getComputedTop(), "75 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(125 === root_child0.getComputedLeft(), "125 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(75 === root_child0.getComputedTop(), "75 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(50 === root_child1.getComputedLeft(), "50 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(75 === root_child1.getComputedTop(), "75 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + console.assert(0 === root_child2.getComputedLeft(), "0 === root_child2.getComputedLeft() (" + root_child2.getComputedLeft() + ")"); + console.assert(75 === root_child2.getComputedTop(), "75 === root_child2.getComputedTop() (" + root_child2.getComputedTop() + ")"); + console.assert(50 === root_child2.getComputedWidth(), "50 === root_child2.getComputedWidth() (" + root_child2.getComputedWidth() + ")"); + console.assert(50 === root_child2.getComputedHeight(), "50 === root_child2.getComputedHeight() (" + root_child2.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_left_and_right_column", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_LEFT, "auto"); + root_child0.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(50 === root_child0.getComputedLeft(), "50 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(75 === root_child0.getComputedTop(), "75 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(150 === root_child1.getComputedLeft(), "150 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(75 === root_child1.getComputedTop(), "75 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(75 === root_child0.getComputedTop(), "75 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(75 === root_child1.getComputedTop(), "75 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_left_and_right", function () { + var root = Yoga.Node.create(); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_LEFT, "auto"); + root_child0.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(150 === root_child1.getComputedLeft(), "150 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_left_and_right_column_and_center", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_LEFT, "auto"); + root_child0.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(75 === root_child0.getComputedLeft(), "75 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_left", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_LEFT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(150 === root_child0.getComputedLeft(), "150 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(150 === root_child0.getComputedLeft(), "150 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_right", function () { + var root = Yoga.Node.create(); + root.setAlignItems(Yoga.ALIGN_CENTER); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(75 === root_child1.getComputedLeft(), "75 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_left_and_right_strech", function () { + var root = Yoga.Node.create(); + root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_LEFT, "auto"); + root_child0.setMargin(Yoga.EDGE_RIGHT, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(50 === root_child0.getComputedLeft(), "50 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(150 === root_child1.getComputedLeft(), "150 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(0 === root_child1.getComputedTop(), "0 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); +it("margin_auto_top_and_bottom_strech", function () { + var root = Yoga.Node.create(); + root.setWidth(200); + root.setHeight(200); + + var root_child0 = Yoga.Node.create(); + root_child0.setMargin(Yoga.EDGE_TOP, "auto"); + root_child0.setMargin(Yoga.EDGE_BOTTOM, "auto"); + root_child0.setWidth(50); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + var root_child1 = Yoga.Node.create(); + root_child1.setWidth(50); + root_child1.setHeight(50); + root.insertChild(root_child1, 1); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(50 === root_child0.getComputedTop(), "50 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(200 === root.getComputedWidth(), "200 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(200 === root.getComputedHeight(), "200 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + console.assert(150 === root_child0.getComputedLeft(), "150 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")"); + console.assert(50 === root_child0.getComputedTop(), "50 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")"); + console.assert(50 === root_child0.getComputedWidth(), "50 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")"); + console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")"); + + console.assert(150 === root_child1.getComputedLeft(), "150 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")"); + console.assert(150 === root_child1.getComputedTop(), "150 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")"); + console.assert(50 === root_child1.getComputedWidth(), "50 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")"); + console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")"); + + if (typeof root !== "undefined") + root.freeRecursive(); + + (typeof gc !== "undefined") && gc(); + console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")"); +}); diff --git a/lib/android-support/BUCK b/lib/android-support/BUCK new file mode 100644 index 00000000..64a3434f --- /dev/null +++ b/lib/android-support/BUCK @@ -0,0 +1,14 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//YOGA_DEFS') + +prebuilt_jar( + name = 'android-support', + binary_jar = 'android-support-v4.jar', + visibility = [YOGA_ROOT], +) diff --git a/lib/android-support/android-support-v4.jar b/lib/android-support/android-support-v4.jar new file mode 100644 index 00000000..aa0b1a5c Binary files /dev/null and b/lib/android-support/android-support-v4.jar differ diff --git a/lib/appcompat/BUCK b/lib/appcompat/BUCK new file mode 100644 index 00000000..45df9d74 --- /dev/null +++ b/lib/appcompat/BUCK @@ -0,0 +1,14 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//YOGA_DEFS') + +android_prebuilt_aar( + name = 'appcompat', + aar = 'appcompat-v7-19.1.0.aar', + visibility = [YOGA_ROOT], +) diff --git a/lib/appcompat/appcompat-v7-19.1.0.aar b/lib/appcompat/appcompat-v7-19.1.0.aar new file mode 100644 index 00000000..bf15013b Binary files /dev/null and b/lib/appcompat/appcompat-v7-19.1.0.aar differ diff --git a/tests/YGAlignContentTest.cpp b/tests/YGAlignContentTest.cpp index 2061af12..d6dac67a 100644 --- a/tests/YGAlignContentTest.cpp +++ b/tests/YGAlignContentTest.cpp @@ -110,17 +110,14 @@ TEST(YogaTest, align_content_flex_start) { YGNodeFreeRecursive(root); } -TEST(YogaTest, align_content_flex_end) { +TEST(YogaTest, align_content_flex_start_without_height_on_children) { const YGNodeRef root = YGNodeNew(); - YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); - YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); YGNodeStyleSetFlexWrap(root, YGWrapWrap); - YGNodeStyleSetWidth(root, 130); + YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); const YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, 50); - YGNodeStyleSetHeight(root_child0, 10); YGNodeInsertChild(root, root_child0, 0); const YGNodeRef root_child1 = YGNodeNew(); @@ -130,7 +127,6 @@ TEST(YogaTest, align_content_flex_end) { const YGNodeRef root_child2 = YGNodeNew(); YGNodeStyleSetWidth(root_child2, 50); - YGNodeStyleSetHeight(root_child2, 10); YGNodeInsertChild(root, root_child2, 2); const YGNodeRef root_child3 = YGNodeNew(); @@ -140,81 +136,179 @@ TEST(YogaTest, align_content_flex_end) { const YGNodeRef root_child4 = YGNodeNew(); 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, YGNodeLayoutGetWidth(root)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); - ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(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, YGNodeLayoutGetHeight(root_child0)); - ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child1)); + 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(80, YGNodeLayoutGetTop(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(0, YGNodeLayoutGetHeight(root_child2)); - ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + 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(90, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); - ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(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(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); - ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child0)); + 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(0, YGNodeLayoutGetHeight(root_child0)); - ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child1)); + 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(80, YGNodeLayoutGetLeft(root_child2)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, 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(0, YGNodeLayoutGetHeight(root_child2)); - ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child3)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetTop(root_child3)); + 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(80, YGNodeLayoutGetLeft(root_child4)); - ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child4)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child4)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); - ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child4)); YGNodeFreeRecursive(root); } -TEST(YogaTest, align_content_center) { +TEST(YogaTest, align_content_flex_start_with_flex) { const YGNodeRef root = YGNodeNew(); - YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); - YGNodeStyleSetAlignContent(root, YGAlignCenter); YGNodeStyleSetFlexWrap(root, YGWrapWrap); - YGNodeStyleSetWidth(root, 130); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 120); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + 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 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_flex_end) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignContent(root, YGAlignFlexEnd); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); YGNodeStyleSetHeight(root, 100); const YGNodeRef root_child0 = YGNodeNew(); @@ -245,31 +339,31 @@ TEST(YogaTest, align_content_center) { ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); - ASSERT_FLOAT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); - ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(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(35, YGNodeLayoutGetTop(root_child1)); + 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(45, YGNodeLayoutGetTop(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(45, YGNodeLayoutGetTop(root_child3)); + 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(55, YGNodeLayoutGetTop(root_child4)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child4)); ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child4)); ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child4)); @@ -277,31 +371,31 @@ TEST(YogaTest, align_content_center) { ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); - ASSERT_FLOAT_EQ(130, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); - ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); - ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child0)); + 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(30, YGNodeLayoutGetLeft(root_child1)); - ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child1)); + 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(80, YGNodeLayoutGetLeft(root_child2)); - ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child2)); + 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(30, YGNodeLayoutGetLeft(root_child3)); - ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child3)); + 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(80, YGNodeLayoutGetLeft(root_child4)); - ASSERT_FLOAT_EQ(55, YGNodeLayoutGetTop(root_child4)); + 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)); @@ -598,3 +692,1059 @@ TEST(YogaTest, align_content_spacearound) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, align_content_stretch_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_children) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_flex) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + 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 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_flex_no_shrink) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetFlexGrow(root_child3, 1); + YGNodeStyleSetFlexBasisPercent(root_child3, 0); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_margin) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + 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 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_padding) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + 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 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_single_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_fixed_height) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 60); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_max_height) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetMaxHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_row_with_min_height) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetMinHeight(root_child1, 80); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} + +TEST(YogaTest, align_content_stretch_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 150); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNew(); + 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 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetHeight(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + + const YGNodeRef root_child4 = YGNodeNew(); + 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); +} diff --git a/tests/YGDefaultValuesTest.cpp b/tests/YGDefaultValuesTest.cpp index 8d460d70..8dc613df 100644 --- a/tests/YGDefaultValuesTest.cpp +++ b/tests/YGDefaultValuesTest.cpp @@ -27,7 +27,7 @@ TEST(YogaTest, assert_default_values) { ASSERT_EQ(YGOverflowVisible, YGNodeStyleGetOverflow(root)); ASSERT_FLOAT_EQ(0, YGNodeStyleGetFlexGrow(root)); ASSERT_FLOAT_EQ(0, YGNodeStyleGetFlexShrink(root)); - ASSERT_FALSE(YGNodeStyleGetFlexBasis(root).unit != YGUnitUndefined); + ASSERT_FALSE(YGNodeStyleGetFlexBasis(root).unit != YGUnitAuto); ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeLeft).unit, YGUnitUndefined); ASSERT_EQ(YGNodeStyleGetPosition(root, YGEdgeTop).unit, YGUnitUndefined); @@ -57,8 +57,8 @@ TEST(YogaTest, assert_default_values) { ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeStart))); ASSERT_TRUE(YGFloatIsUndefined(YGNodeStyleGetBorder(root, YGEdgeEnd))); - ASSERT_EQ(YGNodeStyleGetWidth(root).unit, YGUnitUndefined); - ASSERT_EQ(YGNodeStyleGetHeight(root).unit, YGUnitUndefined); + ASSERT_EQ(YGNodeStyleGetWidth(root).unit, YGUnitAuto); + ASSERT_EQ(YGNodeStyleGetHeight(root).unit, YGUnitAuto); ASSERT_EQ(YGNodeStyleGetMinWidth(root).unit, YGUnitUndefined); ASSERT_EQ(YGNodeStyleGetMinHeight(root).unit, YGUnitUndefined); ASSERT_EQ(YGNodeStyleGetMaxWidth(root).unit, YGUnitUndefined); diff --git a/tests/YGFlexWrapTest.cpp b/tests/YGFlexWrapTest.cpp index 57552a3a..03799b0e 100644 --- a/tests/YGFlexWrapTest.cpp +++ b/tests/YGFlexWrapTest.cpp @@ -394,3 +394,133 @@ TEST(YogaTest, flex_wrap_children_with_min_main_overriding_flex_basis) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, flex_wrap_wrap_to_child_height) { + const YGNodeRef root = YGNodeNew(); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root_child0, YGAlignFlexStart); + YGNodeStyleSetFlexWrap(root_child0, YGWrapWrap); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0_child0, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 100); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, flex_wrap_align_stretch_fits_one_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 150); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + 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); +} diff --git a/tests/YGMarginTest.cpp b/tests/YGMarginTest.cpp index 42908d68..af1bb179 100644 --- a/tests/YGMarginTest.cpp +++ b/tests/YGMarginTest.cpp @@ -410,3 +410,731 @@ TEST(YogaTest, margin_with_sibling_column) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, margin_auto_bottom) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_top) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_bottom_and_top) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_bottom_and_top_justify_center) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_mutiple_children_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeTop); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child1, YGEdgeTop); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_mutiple_children_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child1, YGEdgeRight); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(125, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_left_and_right_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_left_and_right) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_left_and_right_column_and_center) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_left) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_right) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_left_and_right_strech) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, margin_auto_top_and_bottom_strech) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNew(); + 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 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 5a97ef78..f2534334 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -116,11 +116,12 @@ typedef YG_ENUM_BEGIN(YGPrintOptions) { YGPrintOptionsChildren = 4, } YG_ENUM_END(YGPrintOptions); -#define YGUnitCount 3 +#define YGUnitCount 4 typedef YG_ENUM_BEGIN(YGUnit) { YGUnitUndefined, - YGUnitPixel, + YGUnitPoint, YGUnitPercent, + YGUnitAuto, } YG_ENUM_END(YGUnit); #define YGWrapCount 2 diff --git a/yoga/Yoga.c b/yoga/Yoga.c index e8d5c31e..f799a617 100644 --- a/yoga/Yoga.c +++ b/yoga/Yoga.c @@ -118,6 +118,9 @@ typedef struct YGNode { #define YG_UNDEFINED_VALUES \ { .value = YGUndefined, .unit = YGUnitUndefined } +#define YG_AUTO_VALUES \ + { .value = YGUndefined, .unit = YGUnitAuto } + #define YG_DEFAULT_EDGE_VALUES_UNIT \ { \ [YGEdgeLeft] = YG_UNDEFINED_VALUES, [YGEdgeTop] = YG_UNDEFINED_VALUES, \ @@ -133,6 +136,9 @@ typedef struct YGNode { #define YG_DEFAULT_DIMENSION_VALUES_UNIT \ { [YGDimensionWidth] = YG_UNDEFINED_VALUES, [YGDimensionHeight] = YG_UNDEFINED_VALUES, } +#define YG_DEFAULT_DIMENSION_VALUES_AUTO_UNIT \ + { [YGDimensionWidth] = YG_AUTO_VALUES, [YGDimensionHeight] = YG_AUTO_VALUES, } + static YGNode gYGNodeDefaults = { .parent = NULL, .children = NULL, @@ -146,7 +152,7 @@ static YGNode gYGNodeDefaults = { .flex = YGUndefined, .flexGrow = YGUndefined, .flexShrink = YGUndefined, - .flexBasis = YG_UNDEFINED_VALUES, + .flexBasis = YG_AUTO_VALUES, .justifyContent = YGJustifyFlexStart, .alignItems = YGAlignStretch, .alignContent = YGAlignFlexStart, @@ -154,7 +160,7 @@ static YGNode gYGNodeDefaults = { .flexDirection = YGFlexDirectionColumn, .overflow = YGOverflowVisible, .display = YGDisplayFlex, - .dimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, + .dimensions = YG_DEFAULT_DIMENSION_VALUES_AUTO_UNIT, .minDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, .maxDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT, .position = YG_DEFAULT_EDGE_VALUES_UNIT, @@ -189,7 +195,7 @@ YGCalloc gYGCalloc = &calloc; YGRealloc gYGRealloc = &realloc; YGFree gYGFree = &free; -static YGValue YGValueZero = {.value = 0, .unit = YGUnitPixel}; +static YGValue YGValueZero = {.value = 0, .unit = YGUnitPoint}; #ifdef ANDROID #include @@ -265,8 +271,9 @@ static inline const YGValue *YGComputedEdgeValue(const YGValue edges[YGEdgeCount static inline float YGValueResolve(const YGValue *const value, const float parentSize) { switch (value->unit) { case YGUnitUndefined: + case YGUnitAuto: return YGUndefined; - case YGUnitPixel: + case YGUnitPoint: return value->value; case YGUnitPercent: return value->value * parentSize / 100.0f; @@ -274,6 +281,10 @@ static inline float YGValueResolve(const YGValue *const value, const float paren return YGUndefined; } +static inline float YGValueResolveMargin(const YGValue *const value, const float parentSize) { + return value->unit == YGUnitAuto ? 0 : YGValueResolve(value, parentSize); +} + int32_t gNodeInstanceCount = 0; YGNodeRef YGNodeNew(void) { @@ -423,13 +434,13 @@ inline float YGNodeStyleGetFlexShrink(const YGNodeRef node) { } static inline const YGValue *YGNodeStyleGetFlexBasisPtr(const YGNodeRef node) { - if (node->style.flexBasis.unit != YGUnitUndefined) { + if (node->style.flexBasis.unit != YGUnitAuto) { return &node->style.flexBasis; } if (!YGFloatIsUndefined(node->style.flex) && node->style.flex > 0.0f) { return &YGValueZero; } - return &YGValueUndefined; + return &YGValueAuto; } inline YGValue YGNodeStyleGetFlexBasis(const YGNodeRef node) { @@ -463,10 +474,10 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { #define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_IMPL(type, name, paramName, instanceName) \ void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ if (node->style.instanceName.value != paramName || \ - node->style.instanceName.unit != YGUnitPixel) { \ + node->style.instanceName.unit != YGUnitPoint) { \ node->style.instanceName.value = paramName; \ node->style.instanceName.unit = \ - YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPixel; \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint; \ YGNodeMarkDirtyInternal(node); \ } \ } \ @@ -481,6 +492,33 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { } \ } +#define YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL(type, name, paramName, instanceName) \ + void YGNodeStyleSet##name(const YGNodeRef node, const type paramName) { \ + if (node->style.instanceName.value != paramName || \ + node->style.instanceName.unit != YGUnitPoint) { \ + node->style.instanceName.value = YGFloatIsUndefined(paramName) ? YGUndefined : paramName; \ + node->style.instanceName.unit = YGFloatIsUndefined(paramName) ? YGUnitAuto : YGUnitPoint; \ + YGNodeMarkDirtyInternal(node); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Percent(const YGNodeRef node, const type paramName) { \ + if (node->style.instanceName.value != paramName || \ + node->style.instanceName.unit != YGUnitPercent) { \ + node->style.instanceName.value = YGFloatIsUndefined(paramName) ? YGUndefined : paramName; \ + node->style.instanceName.unit = YGFloatIsUndefined(paramName) ? YGUnitAuto : YGUnitPercent; \ + YGNodeMarkDirtyInternal(node); \ + } \ + } \ + \ + void YGNodeStyleSet##name##Auto(const YGNodeRef node) { \ + if (node->style.instanceName.unit != YGUnitAuto) { \ + node->style.instanceName.value = YGUndefined; \ + node->style.instanceName.unit = YGUnitAuto; \ + YGNodeMarkDirtyInternal(node); \ + } \ + } + #define YG_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \ YG_NODE_STYLE_PROPERTY_SETTER_IMPL(type, name, paramName, instanceName) \ \ @@ -495,13 +533,29 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { return node->style.instanceName; \ } +#define YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(type, name, paramName, instanceName) \ + YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL(float, name, paramName, instanceName) \ + \ + type YGNodeStyleGet##name(const YGNodeRef node) { \ + return node->style.instanceName; \ + } + +#define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO_IMPL(type, name, instanceName) \ + void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge) { \ + if (node->style.instanceName[edge].unit != YGUnitAuto) { \ + node->style.instanceName[edge].value = YGUndefined; \ + node->style.instanceName[edge].unit = YGUnitAuto; \ + YGNodeMarkDirtyInternal(node); \ + } \ + } + #define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(type, name, paramName, instanceName) \ void YGNodeStyleSet##name(const YGNodeRef node, const YGEdge edge, const float paramName) { \ if (node->style.instanceName[edge].value != paramName || \ - node->style.instanceName[edge].unit != YGUnitPixel) { \ + node->style.instanceName[edge].unit != YGUnitPoint) { \ node->style.instanceName[edge].value = paramName; \ node->style.instanceName[edge].unit = \ - YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPixel; \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint; \ YGNodeMarkDirtyInternal(node); \ } \ } \ @@ -525,10 +579,10 @@ void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { #define YG_NODE_STYLE_EDGE_PROPERTY_IMPL(type, name, paramName, instanceName) \ void YGNodeStyleSet##name(const YGNodeRef node, const YGEdge edge, const float paramName) { \ if (node->style.instanceName[edge].value != paramName || \ - node->style.instanceName[edge].unit != YGUnitPixel) { \ + node->style.instanceName[edge].unit != YGUnitPoint) { \ node->style.instanceName[edge].value = paramName; \ node->style.instanceName[edge].unit = \ - YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPixel; \ + YGFloatIsUndefined(paramName) ? YGUnitUndefined : YGUnitPoint; \ YGNodeMarkDirtyInternal(node); \ } \ } \ @@ -582,15 +636,16 @@ YG_NODE_STYLE_PROPERTY_IMPL(YGDisplay, Display, display, display); YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexGrow, flexGrow, flexGrow); YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexShrink, flexShrink, flexShrink); -YG_NODE_STYLE_PROPERTY_SETTER_UNIT_IMPL(float, FlexBasis, flexBasis, flexBasis); +YG_NODE_STYLE_PROPERTY_SETTER_UNIT_AUTO_IMPL(float, FlexBasis, flexBasis, flexBasis); YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Position, position, position); YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Margin, margin, margin); +YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Margin, margin); YG_NODE_STYLE_EDGE_PROPERTY_UNIT_IMPL(YGValue, Padding, padding, padding); YG_NODE_STYLE_EDGE_PROPERTY_IMPL(float, Border, border, border); -YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, Width, width, dimensions[YGDimensionWidth]); -YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, Height, height, dimensions[YGDimensionHeight]); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Width, width, dimensions[YGDimensionWidth]); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO_IMPL(YGValue, Height, height, dimensions[YGDimensionHeight]); YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MinWidth, minWidth, minDimensions[YGDimensionWidth]); YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MinHeight, minHeight, minDimensions[YGDimensionHeight]); YG_NODE_STYLE_PROPERTY_UNIT_IMPL(YGValue, MaxWidth, maxWidth, maxDimensions[YGDimensionWidth]); @@ -670,7 +725,7 @@ static void YGPrintNumberIfNotZero(const char *str, const YGValue *const number) "%s: %g%s, ", str, number->value, - number->unit == YGUnitPixel ? "px" : "%"); + number->unit == YGUnitPoint ? "pt" : "%"); } } @@ -686,7 +741,7 @@ static void YGPrintNumberIfNotUndefined(const char *str, const YGValue *const nu "%s: %g%s, ", str, number->value, - number->unit == YGUnitPixel ? "px" : "%"); + number->unit == YGUnitPoint ? "pt" : "%"); } } @@ -902,22 +957,22 @@ static inline float YGNodeLeadingMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { if (YGFlexDirectionIsRow(axis) && node->style.margin[YGEdgeStart].unit != YGUnitUndefined) { - return YGValueResolve(&node->style.margin[YGEdgeStart], widthSize); + return YGValueResolveMargin(&node->style.margin[YGEdgeStart], widthSize); } - return YGValueResolve(YGComputedEdgeValue(node->style.margin, leading[axis], &YGValueZero), - widthSize); + return YGValueResolveMargin(YGComputedEdgeValue(node->style.margin, leading[axis], &YGValueZero), + widthSize); } static float YGNodeTrailingMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { if (YGFlexDirectionIsRow(axis) && node->style.margin[YGEdgeEnd].unit != YGUnitUndefined) { - return YGValueResolve(&node->style.margin[YGEdgeEnd], widthSize); + return YGValueResolveMargin(&node->style.margin[YGEdgeEnd], widthSize); } - return YGValueResolve(YGComputedEdgeValue(node->style.margin, trailing[axis], &YGValueZero), - widthSize); + return YGValueResolveMargin(YGComputedEdgeValue(node->style.margin, trailing[axis], &YGValueZero), + widthSize); } static float YGNodeLeadingPadding(const YGNodeRef node, @@ -1096,8 +1151,9 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node, static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, const YGFlexDirection axis, const float parentSize) { - return !(node->resolvedDimensions[dim[axis]]->unit == YGUnitUndefined || - (node->resolvedDimensions[dim[axis]]->unit == YGUnitPixel && + return !(node->resolvedDimensions[dim[axis]]->unit == YGUnitAuto || + node->resolvedDimensions[dim[axis]]->unit == YGUnitUndefined || + (node->resolvedDimensions[dim[axis]]->unit == YGUnitPoint && node->resolvedDimensions[dim[axis]]->value < 0.0f) || (node->resolvedDimensions[dim[axis]]->unit == YGUnitPercent && (node->resolvedDimensions[dim[axis]]->value < 0.0f || YGFloatIsUndefined(parentSize)))); @@ -1706,27 +1762,6 @@ static void YGZeroOutLayoutRecursivly(const YGNodeRef node) { // * The 'wrap' property supports only 'nowrap' (which is the default) or // 'wrap'. The // rarely-used 'wrap-reverse' is not supported. -// * Rather than allowing arbitrary combinations of flexGrow, flexShrink and -// flexBasis, this algorithm supports only the three most common -// combinations: -// flex: 0 is equiavlent to flex: 0 0 auto -// flex: n (where n is a positive value) is equivalent to flex: n 1 auto -// If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0 -// This is faster because the content doesn't need to be measured, but -// it's -// less flexible because the basis is always 0 and can't be overriden -// with -// the width/height attributes. -// flex: -1 (or any negative value) is equivalent to flex: 0 1 auto -// * Margins cannot be specified as 'auto'. They must be specified in terms of -// pixel -// values, and the default value is 0. -// * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must -// be -// specified as pixel values, not as percentages. -// * There is no support for calculation of dimensions based on intrinsic -// aspect ratios -// (e.g. images). // * There is no support for forced breaks. // * It does not support vertical inline directions (top-to-bottom or // bottom-to-top text). @@ -1956,6 +1991,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, } } + float totalFlexBasis = 0; + // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeListGet(node->children, i); @@ -2005,8 +2042,13 @@ static void YGNodelayoutImpl(const YGNodeRef node, direction); } } + + totalFlexBasis += child->layout.computedFlexBasis; } + const bool flexBasisOverflows = + measureModeMainDim == YGMeasureModeUndefined ? false : totalFlexBasis > availableInnerMainDim; + // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES // Indexes of children that represent the first and last items in the line. @@ -2123,7 +2165,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // based on its // content. // sizeConsumedOnCurrentLine is negative which means the node will - // allocate 0 pixels for + // allocate 0 points for // its content. Consequently, remainingFreeSpace is 0 - // sizeConsumedOnCurrentLine. remainingFreeSpace = -sizeConsumedOnCurrentLine; @@ -2287,6 +2329,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGFlexDirectionColumn, availableInnerHeight) && heightMeasureMode == YGMeasureModeExactly && + !(isNodeFlexWrap && flexBasisOverflows) && YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch) { childHeight = availableInnerCrossDim; childHeightMeasureMode = YGMeasureModeExactly; @@ -2312,7 +2355,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, !YGNodeIsStyleDimDefined(currentRelativeChild, YGFlexDirectionRow, availableInnerWidth) && - widthMeasureMode == YGMeasureModeExactly && + widthMeasureMode == YGMeasureModeExactly && !(isNodeFlexWrap && flexBasisOverflows) && YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch) { childWidth = availableInnerCrossDim; childWidthMeasureMode = YGMeasureModeExactly; @@ -2422,27 +2465,42 @@ static void YGNodelayoutImpl(const YGNodeRef node, } } - switch (justifyContent) { - case YGJustifyCenter: - leadingMainDim = remainingFreeSpace / 2; - break; - case YGJustifyFlexEnd: - leadingMainDim = remainingFreeSpace; - break; - case YGJustifySpaceBetween: - if (itemsOnLine > 1) { - betweenMainDim = fmaxf(remainingFreeSpace, 0) / (itemsOnLine - 1); - } else { - betweenMainDim = 0; + int numberOfAutoMarginsOnCurrentLine = 0; + for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { + const YGNodeRef child = YGNodeListGet(node->children, i); + if (child->style.positionType == YGPositionTypeRelative) { + if (child->style.margin[leading[mainAxis]].unit == YGUnitAuto) { + numberOfAutoMarginsOnCurrentLine++; } - break; - case YGJustifySpaceAround: - // Space on the edges is half of the space between elements - betweenMainDim = remainingFreeSpace / itemsOnLine; - leadingMainDim = betweenMainDim / 2; - break; - case YGJustifyFlexStart: - break; + if (child->style.margin[trailing[mainAxis]].unit == YGUnitAuto) { + numberOfAutoMarginsOnCurrentLine++; + } + } + } + + if (numberOfAutoMarginsOnCurrentLine == 0) { + switch (justifyContent) { + case YGJustifyCenter: + leadingMainDim = remainingFreeSpace / 2; + break; + case YGJustifyFlexEnd: + leadingMainDim = remainingFreeSpace; + break; + case YGJustifySpaceBetween: + if (itemsOnLine > 1) { + betweenMainDim = fmaxf(remainingFreeSpace, 0) / (itemsOnLine - 1); + } else { + betweenMainDim = 0; + } + break; + case YGJustifySpaceAround: + // Space on the edges is half of the space between elements + betweenMainDim = remainingFreeSpace / itemsOnLine; + leadingMainDim = betweenMainDim / 2; + break; + case YGJustifyFlexStart: + break; + } } float mainDim = leadingPaddingAndBorderMain + leadingMainDim; @@ -2469,10 +2527,18 @@ static void YGNodelayoutImpl(const YGNodeRef node, // We need to do that only for relative elements. Absolute elements // do not take part in that phase. if (child->style.positionType == YGPositionTypeRelative) { + if (child->style.margin[leading[mainAxis]].unit == YGUnitAuto) { + mainDim += remainingFreeSpace / numberOfAutoMarginsOnCurrentLine; + } + if (performLayout) { child->layout.position[pos[mainAxis]] += mainDim; } + if (child->style.margin[trailing[mainAxis]].unit == YGUnitAuto) { + mainDim += remainingFreeSpace / numberOfAutoMarginsOnCurrentLine; + } + if (canSkipFlex) { // If we skipped the flex step, then we can't rely on the // measuredDims because @@ -2481,13 +2547,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, child->layout.computedFlexBasis; crossDim = availableInnerCrossDim; } else { - // The main dimension is the sum of all the elements dimension plus - // the spacing. + // The main dimension is the sum of all the elements dimension plus the spacing. mainDim += betweenMainDim + YGNodeDimWithMargin(child, mainAxis, availableInnerWidth); // The cross dimension is the max of the elements dimension since - // there - // can only be one element in that cross dimension. + // there can only be one element in that cross dimension. crossDim = fmaxf(crossDim, YGNodeDimWithMargin(child, crossAxis, availableInnerWidth)); } } else if (performLayout) { @@ -2563,7 +2627,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, // time, this time // forcing the cross-axis size to be the computed cross size for the // current line. - if (alignItem == YGAlignStretch) { + if (alignItem == YGAlignStretch && + child->style.margin[leading[crossAxis]].unit != YGUnitAuto && + child->style.margin[trailing[crossAxis]].unit != YGUnitAuto) { const bool isCrossSizeDefinite = (isMainAxisRow && YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, availableInnerHeight)) || @@ -2630,17 +2696,25 @@ static void YGNodelayoutImpl(const YGNodeRef node, true, "stretch"); } - } else if (alignItem != YGAlignFlexStart) { + } else { const float remainingCrossDim = containerCrossAxis - YGNodeDimWithMargin(child, crossAxis, availableInnerWidth); - if (alignItem == YGAlignCenter) { + if (child->style.margin[leading[crossAxis]].unit == YGUnitAuto && + child->style.margin[trailing[crossAxis]].unit == YGUnitAuto) { leadingCrossDim += remainingCrossDim / 2; - } else { // YGAlignFlexEnd + } else if (child->style.margin[trailing[crossAxis]].unit == YGUnitAuto) { + // No-Op + } else if (child->style.margin[leading[crossAxis]].unit == YGUnitAuto) { + leadingCrossDim += remainingCrossDim; + } else if (alignItem == YGAlignFlexStart) { + // No-Op + } else if (alignItem == YGAlignCenter) { + leadingCrossDim += remainingCrossDim / 2; + } else { leadingCrossDim += remainingCrossDim; } } - // And we apply the position child->layout.position[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim; } @@ -2652,7 +2726,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, } // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (performLayout && (lineCount > 1 || YGIsBaselineLayout(node)) && + if (performLayout && + (lineCount > 1 || node->style.alignContent == YGAlignStretch || YGIsBaselineLayout(node)) && !YGFloatIsUndefined(availableInnerCrossDim)) { const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; @@ -2760,8 +2835,36 @@ static void YGNodelayoutImpl(const YGNodeRef node, case YGAlignStretch: { child->layout.position[pos[crossAxis]] = currentLead + YGNodeLeadingMargin(child, crossAxis, availableInnerWidth); - // TODO(prenaux): Correctly set the height of items with indefinite - // (auto) crossAxis dimension. + + // Remeasure child with the line height as it as been only measured with the + // parents height yet. + if (!YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim)) { + const float childWidth = + isMainAxisRow ? (child->layout.measuredDimensions[YGDimensionWidth] + + YGNodeMarginForAxis(child, crossAxis, availableInnerWidth)) + : lineHeight; + + const float childHeight = + !isMainAxisRow ? (child->layout.measuredDimensions[YGDimensionHeight] + + YGNodeMarginForAxis(child, crossAxis, availableInnerWidth)) + : lineHeight; + + if (!(YGFloatsEqual(childWidth, + child->layout.measuredDimensions[YGDimensionWidth]) && + YGFloatsEqual(childHeight, + child->layout.measuredDimensions[YGDimensionHeight]))) { + YGLayoutNodeInternal(child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + availableInnerWidth, + availableInnerHeight, + true, + "stretch"); + } + } break; } case YGAlignBaseline: { @@ -3162,7 +3265,7 @@ bool YGLayoutNodeInternal(const YGNodeRef node, return (needToVisitNode || cachedResults == NULL); } -static void roundToPixelGrid(const YGNodeRef node) { +static void YGRoundToPixelGrid(const YGNodeRef node) { const float fractialLeft = node->layout.position[YGEdgeLeft] - floorf(node->layout.position[YGEdgeLeft]); const float fractialTop = @@ -3177,7 +3280,7 @@ static void roundToPixelGrid(const YGNodeRef node) { const uint32_t childCount = YGNodeListCount(node->children); for (uint32_t i = 0; i < childCount; i++) { - roundToPixelGrid(YGNodeGetChild(node, i)); + YGRoundToPixelGrid(YGNodeGetChild(node, i)); } } @@ -3236,7 +3339,7 @@ void YGNodeCalculateLayout(const YGNodeRef node, YGNodeSetPosition(node, node->layout.direction, availableWidth, availableHeight, availableWidth); if (YGIsExperimentalFeatureEnabled(YGExperimentalFeatureRounding)) { - roundToPixelGrid(node); + YGRoundToPixelGrid(node); } if (gPrintTree) { diff --git a/yoga/Yoga.h b/yoga/Yoga.h index bf9bd3e8..4969f17c 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -44,6 +44,7 @@ typedef struct YGValue { } YGValue; static const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined}; +static const YGValue YGValueAuto = {0, YGUnitAuto}; typedef struct YGNode *YGNodeRef; typedef YGSize (*YGMeasureFunc)(YGNodeRef node, @@ -121,6 +122,10 @@ WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode WIN_EXPORT void YGNodeStyleSet##name##Percent(const YGNodeRef node, const float paramName); \ WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node); +#define YG_NODE_STYLE_PROPERTY_UNIT_AUTO(type, name, paramName) \ + YG_NODE_STYLE_PROPERTY_UNIT(type, name, paramName) \ + WIN_EXPORT void YGNodeStyleSet##name##Auto(const YGNodeRef node); + #define YG_NODE_STYLE_EDGE_PROPERTY(type, name, paramName) \ WIN_EXPORT void YGNodeStyleSet##name(const YGNodeRef node, \ const YGEdge edge, \ @@ -136,6 +141,9 @@ WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode const float paramName); \ WIN_EXPORT type YGNodeStyleGet##name(const YGNodeRef node, const YGEdge edge); +#define YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO(type, name) \ + WIN_EXPORT void YGNodeStyleSet##name##Auto(const YGNodeRef node, const YGEdge edge); + #define YG_NODE_LAYOUT_PROPERTY(type, name) \ WIN_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node); @@ -162,15 +170,16 @@ YG_NODE_STYLE_PROPERTY(YGDisplay, Display, display); WIN_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex); YG_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow); YG_NODE_STYLE_PROPERTY(float, FlexShrink, flexShrink); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, FlexBasis, flexBasis); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, FlexBasis, flexBasis); YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Position, position); YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Margin, margin); +YG_NODE_STYLE_EDGE_PROPERTY_UNIT_AUTO(YGValue, Margin); YG_NODE_STYLE_EDGE_PROPERTY_UNIT(YGValue, Padding, padding); YG_NODE_STYLE_EDGE_PROPERTY(float, Border, border); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, Width, width); -YG_NODE_STYLE_PROPERTY_UNIT(YGValue, Height, height); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, Width, width); +YG_NODE_STYLE_PROPERTY_UNIT_AUTO(YGValue, Height, height); YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MinWidth, minWidth); YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MinHeight, minHeight); YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MaxWidth, maxWidth); @@ -200,7 +209,7 @@ YG_NODE_LAYOUT_PROPERTY(float, Height); YG_NODE_LAYOUT_PROPERTY(YGDirection, Direction); // Get the computed values for these nodes after performing layout. If they were set using -// pixel values then the returned value will be the same as YGNodeStyleGetXXX. However if +// point values then the returned value will be the same as YGNodeStyleGetXXX. However if // they were set using a percentage value then the returned value is the computed value used // during layout. YG_NODE_LAYOUT_EDGE_PROPERTY(float, Margin);