Compare commits

..

33 Commits

Author SHA1 Message Date
Lukas Woehrl
cd78291de5 C# use YogaSize throughout the measure call chain
Summary:
Java still has the same problem (see #296)

Also there is no need to have double in the method signature as we only use float internally, which could confuse some.
Closes https://github.com/facebook/yoga/pull/300

Reviewed By: splhack

Differential Revision: D4365993

Pulled By: emilsjolander

fbshipit-source-id: 681f8b1725e63eddcfb9a6c756f2ae215a44425a
2016-12-24 02:54:38 -08:00
Emil Sjolander
ab595d1875 ignore .buckversion
Summary: ignore .buckversion file from source control

Reviewed By: vjeux

Differential Revision: D4366002

fbshipit-source-id: 910173bab5f3235673a8686ae6b606624380df09
2016-12-24 02:54:38 -08:00
Emil Sjolander
597544e30a Add note about gtest submodule to readme
Summary: Add note about gtest submodule to readme

Reviewed By: vjeux

Differential Revision: D4366004

fbshipit-source-id: 13ddc040faa251d52aa4c253caff9f5478e12ca6
2016-12-24 02:54:38 -08:00
Kazuki Sakamoto
9f59a13836 Remove unused P/Invoke interface
Summary:
- Remove YGNodeGetContext and YGNodeSetContext from Native.cs
- https://github.com/facebook/yoga/pull/297#discussion_r93789907

Reviewed By: emilsjolander

Differential Revision: D4365845

fbshipit-source-id: 89b41ec773baa1b4901f637f5e83427c9fba4aed
2016-12-23 12:09:40 -08:00
Kazuki Sakamoto
12017e49bd Update .git/hgignore
Summary: Fix paths

Reviewed By: emilsjolander

Differential Revision: D4365853

fbshipit-source-id: 1eb5b1046f4bb7a18b8f29d2876c0d560c3fad49
2016-12-23 12:09:40 -08:00
Kazuki Sakamoto
abad796c44 Fix BUCK
Summary: Remove internal arg

Reviewed By: emilsjolander

Differential Revision: D4365827

fbshipit-source-id: 705855732146e03da65f21cbaa746277719b72f4
2016-12-23 11:24:37 -08:00
desmondyao
92137273a2 Not re-calculate value in Step1.
Summary:
Not re-calculate `paddingAndBorderAxisMain`/`paddingAndBorderAxisCross`/`paddingAndBorderAxisRow`/`paddingAndBorderAxisColumn` in Step1 of `YGNodelayoutImpl`.

They can be figure out by values calculated before.
Closes https://github.com/facebook/yoga/pull/298

Reviewed By: dshahidehpour

Differential Revision: D4365533

Pulled By: emilsjolander

fbshipit-source-id: 6caf60bc6ef3addd49915b39b48f01a8b4926e9c
2016-12-23 10:24:32 -08:00
Kazuki Sakamoto
f1ab289022 Run unit tests before building Unity package
Summary:
- Enable destructor unit tests in Unity Editor
- Exit pack.sh immediately if a command exits with a non-zero status
- Run unit tests before building Unity package

Reviewed By: emilsjolander

Differential Revision: D4365773

fbshipit-source-id: 20d0a51f4cef791154c17d329ac36598dc333a60
2016-12-23 09:54:32 -08:00
David Hart
a302b76d59 Added gitignore rule for Xcode xcuserdata
Summary: Closes https://github.com/facebook/yoga/pull/294

Reviewed By: dshahidehpour

Differential Revision: D4365534

Pulled By: emilsjolander

fbshipit-source-id: ff899d3526156ce9bbe8cba07418ca77b2f38ac8
2016-12-23 08:54:37 -08:00
Filip Frącz
4717594e93 Switched to using SafeHandle for native code interrupt
Summary:
This PR fixes issue #295

- Created a new internal YGNodeHandle class extending SafeHandle.
- YogaNode now stores a reference to YGNodeHandle.
- Removed finalizer from YogaNode.
- Pulling in System.Runtime.Handles 4.3.0.
Closes https://github.com/facebook/yoga/pull/297

Reviewed By: emilsjolander

Differential Revision: D4365462

Pulled By: splhack

fbshipit-source-id: 73293b105962cbedb71f4e3d8d1244251db1ea79
2016-12-23 08:39:33 -08:00
Hannes Verlinde
df0f76bba5 Run unit tests on Sandcastle
Summary:
- Change the CI config so it runs the tests for Editor on Sandcastle
- Don't run tests for effects-framework and yoga libraries when building for Mac (triggers code signing issues that I don't want to deal with right now)
- Add target for unit tests (aka EditorTests)
- Make the existing unit tests build and pass. These include both Objective-C and Swift (we should probably get rid of some of these though). I will convert these to Swift 3 before landing (after the migration is complete).
- Exclude the EditorUITests target for now. It only contains a single dummy test and it causes a code signing failure on Sandcastle. I did not manage to work around that yet but there is a separate task for it.

Reviewed By: Perspx

Differential Revision: D4352670

fbshipit-source-id: 0295004a72953bd8e7ae83895b2e5712bab7bd32
2016-12-23 02:09:35 -08:00
Kazuki Sakamoto
e43c9f66ff Add script to build Unity package
Summary:
Added Bash script and bat file to build a package of Yoga in order to import Yoga for Unity easily.
Closes https://github.com/facebook/yoga/pull/288

Reviewed By: emilsjolander

Differential Revision: D4344198

Pulled By: splhack

fbshipit-source-id: 49ae27dbc513b4a2d161840ca5c5f4c9df2ab227
2016-12-22 08:39:35 -08:00
Emil Sjolander
0df58d8aa2 Declaratively initialize default values of nodes
Summary: Improve performance of allocations and reseting by writing fewer bits. Also just looks nicer imho.

Reviewed By: passy

Differential Revision: D4356994

fbshipit-source-id: ebbe52163e0c86230bfa4131b657941afe16fbf1
2016-12-22 03:10:06 -08:00
David Hart
ff1a0e1eb8 Transform the Count enum values into private constants
Summary:
Hides implementation details for the C, Objective-C and Swift APIs.
Closes https://github.com/facebook/yoga/pull/292

Differential Revision: D4351523

Pulled By: emilsjolander

fbshipit-source-id: 18a1149d169f0d52bd078714295000b5d07434dd
2016-12-22 03:10:06 -08:00
Emil Sjolander
ed765fe508 Convert max cache count into a define
Summary: This should not be an enum. A define makes a whole lot more sense

Differential Revision: D4346529

fbshipit-source-id: 8641c4c5017d915d64e5884cae09ac8f01861337
2016-12-22 03:10:06 -08:00
Emil Sjolander
1b5eb7da5e BREAKING - Increase priority of AspectRatio to override flex, align stretch, and fixed sizes if specified.
Summary:
@public
AspectRatio is a new addition and soon after introduction we noticed use cases which is did not support. Specifically we wanted to support a node being as large as possible within a container while maintaining an arbitrary aspect ratio. This was not possible due to the low priority of AspectRatio, by increasing the priority of AspectRatio this is now possible as FlexGrow will grow an item to fit its parent unless the AspectRatio makes it too big in the cross axis, the AspectRatio will now override the FlexGrow in the main axis in that case.

Differential Revision: D4346720

fbshipit-source-id: 1f15613604190e3ad5ff4a467ba57db4bcfd2741
2016-12-22 03:10:06 -08:00
Emil Sjolander
071f576db9 BREAKING - Change aspect ratio to always be width/height
Summary:
@public

Aspect ratio being defined as width/height or height/width depending on the situation it was used in turned out to be very confusing. This diff makes aspect ratio always be defined as width/height irregardless of the usage.

Differential Revision: D4339132

fbshipit-source-id: e5da32750b55ddaf6acaf1cbd7662d86f2b480c3
2016-12-22 03:10:06 -08:00
Emil Sjolander
3d10ba5f72 Correctly check if child is flex by also accounting for undefined
Summary: We were incorrectly returning true for children which had no flex as the flex was nan and not 0.

Differential Revision: D4346712

fbshipit-source-id: 69ef0bb3fe5b4fcd3b3e2fe5aa348529be40252a
2016-12-22 03:10:05 -08:00
Georgiy Kassabli
85b8386ba1 Test for minHeight with flexing
Summary: This test creates a repro case for Yoga to emulate UFI layout failure

Reviewed By: emilsjolander

Differential Revision: D4313632

fbshipit-source-id: 35be7d86b50a9ae08c81891a889a74e4b61f2d27
2016-12-21 11:39:34 -08:00
Dustin Shahidehpour
7ec3607446 Fix diffing algorithm for reattaching views.
Summary:
There is a bug currently where we don't traverse the entire tree to detect view hierarchy changes.

Currently, if you had a hierachy like this:
```
container = UIView
container.subviews = @[subview1, subview2];

subview1.subviews = @[sub11, sub12, sub13];
subview2.subviews = @[sub21, sub22, sub23];
```

and then modified via:
```
subview2.subviews = @[newView1, newView2, newView3];
```

our algorithm wouldn't identify that we had new views that needed their layout calculated, and would cause a crash later on.

Reviewed By: emilsjolander

Differential Revision: D4357662

fbshipit-source-id: 2f61f213c5f1a62948a653f3b1fa3d874c5075f7
2016-12-21 11:09:38 -08:00
Dustin Shahidehpour
835bb1cd9c Add isLeaf flag to Views.
Summary: While building some views with YogaKit, I found an interesting problem. If you are apply `yg_` properties to a view which is constructed of subclassed views (that don't use Yoga.) we still treat view (and it's subviews) like they are using YogaKit. This fixes that behavior.

Reviewed By: emilsjolander

Differential Revision: D4348344

fbshipit-source-id: 37b8648918529f55afea1d1883a03af398aac849
2016-12-20 11:39:36 -08:00
yiminghe
9d35dce63e explicit default justifyContent value
Summary:
make default justifyContent value explicit like alignItems

https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content

https://developer.mozilla.org/en-US/docs/Web/CSS/align-items

https://developer.mozilla.org/en-US/docs/Web/CSS/align-content
Closes https://github.com/facebook/yoga/pull/293

Differential Revision: D4351597

Pulled By: emilsjolander

fbshipit-source-id: b65ff2284ede4d75f1cc5e22d4106042ab0b0d02
2016-12-20 03:24:40 -08:00
Emil Sjolander
74fb205083 Rename test files to match other test file names
Summary: Rename test files to match other test file names

Differential Revision: D4335198

fbshipit-source-id: b8f38162c3094231476059eb1f54326d8ba84848
2016-12-16 09:09:37 -08:00
Kazuki Sakamoto
ba0bb10366 Build iOS fat static library for Unity and Xamarin
Summary:
$ buck build //csharp:yoganet-ios
    $ buck targets --show-output //csharp:yoganet-ios
    //csharp:yoganet-ios buck-out/gen/csharp/yoganet-ios/libyoga.a

    $ lipo -info buck-out/gen/csharp/yoganet-ios/libyoga.a
    Architectures in the fat file: buck-out/gen/csharp/yoganet-ios/libyoga.a are: armv7 x86_64 arm64

    $ nm buck-out/gen/csharp/yoganet-ios/libyoga.a|grep -e 'T _YGNodeNew' -e 'ygNode' -e 'T _YGInteropSetLogger'
    0000000000000000 T _YGNodeNew
    0000000000001070 t -[UIView(Yoga) ygNode]
    0000000000000000 T _YGInteropSetLogger
Closes https://github.com/facebook/yoga/pull/286

Reviewed By: emilsjolander

Differential Revision: D4338919

Pulled By: splhack

fbshipit-source-id: 7acfdfa0dc4d152d7bfe92161efdeb9f161f70e6
2016-12-16 06:54:35 -08:00
Emil Sjolander
0296511f2c YGNodeChildCount -> YGNodeGetChildCount for consistency
Summary: I kept wrongly typing this function which is a good sign that the name is inconsistent.

Reviewed By: gkassabli

Differential Revision: D4333480

fbshipit-source-id: 17058f18fa9e26b3e02f7a1651f7295cae59acad
2016-12-16 04:39:41 -08:00
Kazuki Sakamoto
04fe81f88f YGNodeInit is no longer exported
Summary:
- Problem: Can't link yoga static libraries with Unity and Xamarin.iOS since YGNodeInit is undefined in the libraries.
- Solution: Remove the reference in Native.cs

Reviewed By: emilsjolander

Differential Revision: D4338485

fbshipit-source-id: 9dc95aec8f1fd50f3f9d66e1623afe2fb1992210
2016-12-16 00:09:40 -08:00
Kazuki Sakamoto
98bbc15435 Support Xamarin.iOS
Summary:
- `__Internal`

https://developer.xamarin.com/guides/ios/advanced_topics/native_interop/#Static_Libraries

 > Since you can only use static libraries on iOS, there is no external shared library to link with, so the path parameter in the DllImport attribute needs to use the special name __Internal (note the double underscore characters at the start of the name) as opposed to the path name.

- `__IOS__`

https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_4_-_platform_divergence_abstraction_divergent_implementation/#iOS

 > Xamarin.iOS defines __IOS__ which you can use to detect iOS devices.
Closes https://github.com/facebook/yoga/pull/277

Reviewed By: emilsjolander

Differential Revision: D4338420

Pulled By: splhack

fbshipit-source-id: 375efecbaf88fffbba544073c6d6b30fb1f4c8ba
2016-12-16 00:09:40 -08:00
Kazuki Sakamoto
25b206ac53 Build native library with BUCK for .NET (Mono, Xamarin)
Summary:
Examples:

- macOS on macOS (Mono, Xamarin.Mac, Unity)
  - `buck build //csharp:yoganet#shared,default` -> `libyoga.dylib`
- Android (Xamarin.Android, Unity)
  - `buck build //csharp:yoganet#shared,android-armv7` -> `libyoga.so`
- iOS (Xamarin.iOS, Unity)
  - `buck build //:yoga#static,iphoneos-arm64` -> `libyoga.a`
  - `buck build //csharp:yoganet#static,iphoneos-arm64` -> `libyoganet.a`
Closes https://github.com/facebook/yoga/pull/282

Reviewed By: emilsjolander

Differential Revision: D4333811

Pulled By: splhack

fbshipit-source-id: 54f4364d93b2419d7504392eb558296a5d06772f
2016-12-15 13:54:34 -08:00
Emil Sjolander
88a4e44fd4 Add YGNodeGetParent api
Summary: Fixes https://github.com/facebook/css-layout/issues/248

Reviewed By: gkassabli

Differential Revision: D4333456

fbshipit-source-id: 388afd0a01c19a6db73c175bf24c566278832cb9
2016-12-15 09:54:35 -08:00
Kazuki Sakamoto
642ea07d6f Update unmanaged dll name
Summary: - Update unmanaged dll name from `Yoga.dll` to `yoga.dll` since Native.cs `DllName` referes lowercase `yoga`

Reviewed By: emilsjolander

Differential Revision: D4295954

fbshipit-source-id: 16b91c407506685b84902102cf4380cb149b5b2c
2016-12-15 07:24:46 -08:00
Kazuki Sakamoto
e85c5ce39d lowercase argument
Summary: - Fix arguments of YogaNode.Create

Reviewed By: emilsjolander

Differential Revision: D4296488

fbshipit-source-id: f6eb5074b1b1462f2251d330929f7b8082ad72eb
2016-12-15 07:24:46 -08:00
Jatin Pandey
cf753af247 Make documentation clearer
Summary:
Fixing a typo :)
Closes https://github.com/facebook/yoga/pull/270

Reviewed By: dshahidehpour

Differential Revision: D4333129

Pulled By: emilsjolander

fbshipit-source-id: 28215de8fcd571fb889fe145ff303f231a50c598
2016-12-15 07:24:46 -08:00
Emil Sjolander
12efe604bb Fix YogaKit tests on travis
Summary: Fix include path

Reviewed By: dshahidehpour

Differential Revision: D4333185

fbshipit-source-id: 27638324e093260aa1b23134fab5140a0c703bc9
2016-12-15 07:24:46 -08:00
39 changed files with 1575 additions and 420 deletions

42
.gitignore vendored
View File

@@ -5,6 +5,48 @@
/.buckconfig.local /.buckconfig.local
/.buckd /.buckd
/gentest/test.html /gentest/test.html
.buckversion
# Visual studio code # Visual studio code
.vscode .vscode
# Xcode
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xcuserstate
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build

View File

@@ -5,6 +5,48 @@
/.buckconfig.local /.buckconfig.local
/.buckd /.buckd
/gentest/test.html /gentest/test.html
.buckversion
# Visual studio code # Visual studio code
.vscode .vscode
# Xcode
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xcuserstate
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build

8
BUCK
View File

@@ -7,14 +7,6 @@
include_defs('//YOGA_DEFS') include_defs('//YOGA_DEFS')
BASE_COMPILER_FLAGS = [
'-fno-omit-frame-pointer',
'-fexceptions',
'-Wall',
'-Werror',
'-O3',
]
GMOCK_OVERRIDE_FLAGS = [ GMOCK_OVERRIDE_FLAGS = [
# gmock does not mark mocked methods as override, ignore the warnings in tests # gmock does not mark mocked methods as override, ignore the warnings in tests
'-Wno-inconsistent-missing-override', '-Wno-inconsistent-missing-override',

View File

@@ -4,6 +4,8 @@
Yoga builds with [buck](https://buckbuild.com). Make sure you install buck before contributing to Yoga. Yoga's main implementation is in C, with bindings to supported languages and frameworks. When making changes to Yoga please ensure the changes are also propagated to these bindings when applicable. Yoga builds with [buck](https://buckbuild.com). Make sure you install buck before contributing to Yoga. Yoga's main implementation is in C, with bindings to supported languages and frameworks. When making changes to Yoga please ensure the changes are also propagated to these bindings when applicable.
## Testing ## Testing
For testing we rely on [gtest](https://github.com/google/googletest) as a submodule. After cloning Yoga run `git submodule init` followed by `git submodule update`.
For any changes you make you should ensure that all the tests are passing. In case you make any fixes or additions to the library please also add tests for that change to ensure we don't break anything in the future. Tests are located in the `tests` directory. Run the tests by executing `buck test //:yoga`. For any changes you make you should ensure that all the tests are passing. In case you make any fixes or additions to the library please also add tests for that change to ensure we don't break anything in the future. Tests are located in the `tests` directory. Run the tests by executing `buck test //:yoga`.
Instead of manually writing a test which ensures parity with web implementations of Flexbox you can run `gentest/gentest.rb` to generated a test for you. You can write html which you want to verify in Yoga, in `gentest/fixtures` folder, such as the following. Instead of manually writing a test which ensures parity with web implementations of Flexbox you can run `gentest/gentest.rb` to generated a test for you. You can write html which you want to verify in Yoga, in `gentest/fixtures` folder, such as the following.

View File

@@ -17,6 +17,14 @@ CXX_LIBRARY_WHITELIST = [
'//java:jni', '//java:jni',
] ]
BASE_COMPILER_FLAGS = [
'-fno-omit-frame-pointer',
'-fexceptions',
'-Wall',
'-Werror',
'-O3',
]
def yoga_dep(dep): def yoga_dep(dep):
return '//' + dep return '//' + dep

View File

@@ -9,7 +9,7 @@
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#import "UIView+Yoga.h" #import <YogaKit/UIView+Yoga.h>
@interface YogaKitTests : XCTestCase @interface YogaKitTests : XCTestCase
@end @end
@@ -268,4 +268,79 @@
} }
} }
- (void)testyg_isLeafFlag
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertTrue(view.yg_isLeaf);
for (int i=0; i<10; i++) {
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
[view addSubview:subview];
}
XCTAssertTrue(view.yg_isLeaf);
[view yg_setUsesYoga:YES];
[view yg_setWidth:50.0];
XCTAssertTrue(view.yg_isLeaf);
UIView *const subview = view.subviews[0];
[subview yg_setUsesYoga:YES];
[subview yg_setWidth:50.0];
XCTAssertFalse(view.yg_isLeaf);
}
- (void)testThatWeCorrectlyAttachNestedViews
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionColumn];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setWidth:100];
[subview1 yg_setFlexGrow:1];
[subview1 yg_setFlexDirection:YGFlexDirectionColumn];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setWidth:150];
[subview2 yg_setFlexGrow:1];
[subview2 yg_setFlexDirection:YGFlexDirectionColumn];
[container addSubview:subview2];
for (UIView *view in @[subview1, subview2]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
[someView yg_setUsesYoga:YES];
[someView yg_setFlexGrow:1];
[view addSubview:someView];
}
[container yg_applyLayout];
// Add the same amount of new views, reapply layout.
for (UIView *view in @[subview1, subview2]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
[someView yg_setUsesYoga:YES];
[someView yg_setFlexGrow:1];
[view addSubview:someView];
}
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 25), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size));
for (UIView *subview in subview1.subviews) {
const CGSize subviewSize = subview.bounds.size;
XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subviewSize));
XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width));
}
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 25), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size));
for (UIView *subview in subview2.subviews) {
const CGSize subviewSize = subview.bounds.size;
XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subview.bounds.size));
XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width));
}
}
@end @end

View File

@@ -55,7 +55,7 @@
- (YGDirection)yg_resolvedDirection; - (YGDirection)yg_resolvedDirection;
/** /**
Perform a layout calculation and update the frames of the views in the hierarchy with th results Perform a layout calculation and update the frames of the views in the hierarchy with the results
*/ */
- (void)yg_applyLayout; - (void)yg_applyLayout;
@@ -69,4 +69,9 @@
*/ */
- (NSUInteger)yg_numberOfChildren; - (NSUInteger)yg_numberOfChildren;
/**
Return a BOOL indiciating whether or not we this node contains any subviews that are included in Yoga's layout.
*/
- (BOOL)yg_isLeaf;
@end @end

View File

@@ -53,7 +53,21 @@
- (NSUInteger)yg_numberOfChildren - (NSUInteger)yg_numberOfChildren
{ {
return YGNodeChildCount([self ygNode]); return YGNodeGetChildCount([self ygNode]);
}
- (BOOL)yg_isLeaf
{
NSAssert([NSThread isMainThread], @"This method must be called on the main thread.");
if ([self yg_usesYoga]) {
for (UIView *subview in self.subviews) {
if ([subview yg_usesYoga] && [subview yg_includeInLayout]) {
return NO;
}
}
}
return YES;
} }
#pragma mark - Setters #pragma mark - Setters
@@ -276,17 +290,32 @@ static CGFloat YGSanitizeMeasurement(
return result; return result;
} }
static void YGAttachNodesFromViewHierachy(UIView *view) { static BOOL YGNodeHasExactSameChildren(const YGNodeRef node, NSArray<UIView *> *subviews)
YGNodeRef node = [view ygNode]; {
if (YGNodeGetChildCount(node) != subviews.count) {
return NO;
}
for (int i=0; i<subviews.count; i++) {
if (YGNodeGetChild(node, i) != subviews[i].ygNode) {
return NO;
}
}
return YES;
}
static void YGAttachNodesFromViewHierachy(UIView *const view)
{
const YGNodeRef node = [view ygNode];
// Only leaf nodes should have a measure function // Only leaf nodes should have a measure function
if (![view yg_usesYoga] || view.subviews.count == 0) { if (view.yg_isLeaf) {
YGNodeSetMeasureFunc(node, YGMeasureView); YGNodeSetMeasureFunc(node, YGMeasureView);
YGRemoveAllChildren(node); YGRemoveAllChildren(node);
} else { } else {
YGNodeSetMeasureFunc(node, NULL); YGNodeSetMeasureFunc(node, NULL);
// Create a list of all the subviews that we are going to use for layout.
NSMutableArray<UIView *> *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count]; NSMutableArray<UIView *> *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count];
for (UIView *subview in view.subviews) { for (UIView *subview in view.subviews) {
if ([subview yg_includeInLayout]) { if ([subview yg_includeInLayout]) {
@@ -294,27 +323,16 @@ static void YGAttachNodesFromViewHierachy(UIView *view) {
} }
} }
BOOL shouldReconstructChildList = NO; if (!YGNodeHasExactSameChildren(node, subviewsToInclude)) {
if (YGNodeChildCount(node) != subviewsToInclude.count) {
shouldReconstructChildList = YES;
} else {
for (int i = 0; i < subviewsToInclude.count; i++) {
if (YGNodeGetChild(node, i) != [subviewsToInclude[i] ygNode]) {
shouldReconstructChildList = YES;
break;
}
}
}
if (shouldReconstructChildList) {
YGRemoveAllChildren(node); YGRemoveAllChildren(node);
for (int i=0; i<subviewsToInclude.count; i++) {
for (int i = 0 ; i < subviewsToInclude.count; i++) { YGNodeInsertChild(node, [subviewsToInclude[i] ygNode], i);
UIView *const subview = subviewsToInclude[i];
YGNodeInsertChild(node, [subview ygNode], i);
YGAttachNodesFromViewHierachy(subview);
} }
} }
for (UIView *const subview in subviewsToInclude) {
YGAttachNodesFromViewHierachy(subview);
}
} }
} }
@@ -324,8 +342,8 @@ static void YGRemoveAllChildren(const YGNodeRef node)
return; return;
} }
while (YGNodeChildCount(node) > 0) { while (YGNodeGetChildCount(node) > 0) {
YGNodeRemoveChild(node, YGNodeGetChild(node, YGNodeChildCount(node) - 1)); YGNodeRemoveChild(node, YGNodeGetChild(node, YGNodeGetChildCount(node) - 1));
} }
} }
@@ -340,7 +358,8 @@ static CGFloat YGRoundPixelValue(CGFloat value)
return round(value * scale) / scale; return round(value * scale) / scale;
} }
static void YGApplyLayoutToViewHierarchy(UIView *view) { static void YGApplyLayoutToViewHierarchy(UIView *view)
{
NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread."); NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread.");
if (![view yg_includeInLayout]) { if (![view yg_includeInLayout]) {
return; return;
@@ -368,9 +387,8 @@ static void YGApplyLayoutToViewHierarchy(UIView *view) {
}, },
}; };
const BOOL isLeaf = ![view yg_usesYoga] || view.subviews.count == 0; if (!view.yg_isLeaf) {
if (!isLeaf) { for (NSUInteger i=0; i<view.subviews.count; i++) {
for (NSUInteger i = 0; i < view.subviews.count; i++) {
YGApplyLayoutToViewHierarchy(view.subviews[i]); YGApplyLayoutToViewHierarchy(view.subviews[i]);
} }
} }

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>YogaKitSample.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>13687D421DF8748300E7C260</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

9
csharp/.gitignore vendored
View File

@@ -30,15 +30,14 @@ bld/
# MSTest test Results # MSTest test Results
[Tt]est[Rr]esult*/ [Tt]est[Rr]esult*/
[Bb]uild[Ll]og.* [Bb]uild[Ll]og.*
csharp/tests/Facebook.Yoga/NUnit-[0-9\.]+/
csharp/tests/Facebook.Yoga/YogaTest.dll
csharp/tests/Facebook.Yoga/YogaTest.dll.mdb
csharp/tests/Facebook.Yoga/libyoga.dylib
csharp/tests/Facebook.Yoga/libyoga.dylib.dSYM/
# NUNIT # NUNIT
*.VisualState.xml *.VisualState.xml
TestResult.xml TestResult.xml
tests/Facebook.Yoga/NUnit-[0-9\.]*/
tests/Facebook.Yoga/YogaTest.dll
tests/Facebook.Yoga/YogaTest.dll.mdb
tests/Facebook.Yoga/libyoga.dylib
# Build Results of an ATL Project # Build Results of an ATL Project
[Dd]ebugPS/ [Dd]ebugPS/

View File

@@ -34,11 +34,10 @@ bld/
# NUNIT # NUNIT
*.VisualState.xml *.VisualState.xml
TestResult.xml TestResult.xml
csharp/tests/Facebook.Yoga/NUnit-[0-9\.]+/ tests/Facebook.Yoga/NUnit-[0-9\.]*/
csharp/tests/Facebook.Yoga/YogaTest.dll tests/Facebook.Yoga/YogaTest.dll
csharp/tests/Facebook.Yoga/YogaTest.dll.mdb tests/Facebook.Yoga/YogaTest.dll.mdb
csharp/tests/Facebook.Yoga/libyoga.dylib tests/Facebook.Yoga/libyoga.dylib
csharp/tests/Facebook.Yoga/libyoga.dylib.dSYM/
# Build Results of an ATL Project # Build Results of an ATL Project
[Dd]ebugPS/ [Dd]ebugPS/

View File

@@ -5,6 +5,10 @@
# LICENSE file in the root directory of this source tree. An additional grant # 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. # of patent rights can be found in the PATENTS file in the same directory.
include_defs('//YOGA_DEFS')
COMPILER_FLAGS = BASE_COMPILER_FLAGS + ['-std=c++11']
csharp_library( csharp_library(
name = 'yogalibnet46', name = 'yogalibnet46',
dll_name = 'Facebook.Yoga.dll', dll_name = 'Facebook.Yoga.dll',
@@ -18,3 +22,42 @@ csharp_library(
framework_ver = 'net45', framework_ver = 'net45',
srcs = glob(['**/*.cs']), srcs = glob(['**/*.cs']),
) )
cxx_library(
name = 'yoganet',
soname = 'libyoga.$(ext)',
srcs = glob(['Yoga/YGInterop.cpp']),
compiler_flags = COMPILER_FLAGS,
link_style = 'static',
link_whole = True,
deps = [yoga_dep(':yoga')],
visibility = ['PUBLIC'],
)
with allow_unsafe_import():
import os
if os.path.isdir('/Applications/Xcode.app'):
yoganet_ios_srcs = []
for arch in ['iphonesimulator-x86_64', 'iphoneos-arm64', 'iphoneos-armv7']:
name = 'yoganet-' + arch
yoganet_ios_srcs.append(':' + name)
genrule(
name = name,
srcs = [
yoga_dep(':yoga#%s,static' % arch),
yoga_dep('YogaKit:YogaKit#%s,static' % arch),
yoga_dep('csharp:yoganet#%s,static' % arch),
],
out = 'libyoga-%s.a' % arch,
cmd = 'libtool -static -o $OUT $SRCS',
visibility = [yoga_dep('csharp:yoganet-ios')],
)
genrule(
name = 'yoganet-ios',
srcs = yoganet_ios_srcs,
out = 'libyoga.a',
cmd = 'lipo $SRCS -create -output $OUT',
visibility = ['PUBLIC'],
)

View File

@@ -9,7 +9,7 @@
namespace Facebook.Yoga namespace Facebook.Yoga
{ {
public delegate long MeasureFunction( public delegate YogaSize MeasureFunction(
YogaNode node, YogaNode node,
float width, float width,
YogaMeasureMode widthMode, YogaMeasureMode widthMode,

View File

@@ -11,24 +11,9 @@ namespace Facebook.Yoga
{ {
public class MeasureOutput public class MeasureOutput
{ {
public static long Make(double width, double height) public static YogaSize Make(float width, float height)
{ {
return Make((int) width, (int) height); return new YogaSize { width = width, height = height};
}
public static long Make(int width, int height)
{
return (long)(((ulong) width) << 32 | ((uint) height));
}
public static int GetWidth(long measureOutput)
{
return (int) (0xFFFFFFFF & (measureOutput >> 32));
}
public static int GetHeight(long measureOutput)
{
return (int) (0xFFFFFFFF & measureOutput);
} }
} }
} }

View File

@@ -14,27 +14,46 @@ namespace Facebook.Yoga
{ {
internal static class Native internal static class Native
{ {
#if UNITY_IOS && !UNITY_EDITOR #if (UNITY_IOS && !UNITY_EDITOR) || __IOS__
private const string DllName = "__Internal"; private const string DllName = "__Internal";
#else #else
private const string DllName = "yoga"; private const string DllName = "yoga";
#endif #endif
internal class YGNodeHandle : SafeHandle
{
private YGNodeHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get
{
return this.handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
Native.YGNodeFree(this.handle);
GC.KeepAlive(this);
return true;
}
}
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGInteropSetLogger( public static extern void YGInteropSetLogger(
[MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func); [MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func);
[DllImport(DllName)] [DllImport(DllName)]
public static extern IntPtr YGNodeNew(); public static extern YGNodeHandle YGNodeNew();
[DllImport(DllName)]
public static extern void YGNodeInit(IntPtr node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeFree(IntPtr node); public static extern void YGNodeFree(IntPtr node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeReset(IntPtr node); public static extern void YGNodeReset(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern int YGNodeGetInstanceCount(); public static extern int YGNodeGetInstanceCount();
@@ -49,237 +68,225 @@ namespace Facebook.Yoga
YogaExperimentalFeature feature); YogaExperimentalFeature feature);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeInsertChild(IntPtr node, IntPtr child, uint index); public static extern void YGNodeInsertChild(YGNodeHandle node, YGNodeHandle child, uint index);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeRemoveChild(IntPtr node, IntPtr child); public static extern void YGNodeRemoveChild(YGNodeHandle node, YGNodeHandle child);
[DllImport(DllName)] [DllImport(DllName)]
public static extern IntPtr YGNodeGetChild(IntPtr node, uint index); public static extern void YGNodeCalculateLayout(YGNodeHandle node,
[DllImport(DllName)]
public static extern uint YGNodeChildCount(IntPtr node);
[DllImport(DllName)]
public static extern void YGNodeCalculateLayout(IntPtr node,
float availableWidth, float availableWidth,
float availableHeight, float availableHeight,
YogaDirection parentDirection); YogaDirection parentDirection);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeMarkDirty(IntPtr node); public static extern void YGNodeMarkDirty(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
public static extern bool YGNodeIsDirty(IntPtr node); public static extern bool YGNodeIsDirty(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodePrint(IntPtr node, YogaPrintOptions options); public static extern void YGNodePrint(YGNodeHandle node, YogaPrintOptions options);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
public static extern bool YGValueIsUndefined(float value); public static extern bool YGValueIsUndefined(float value);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeCopyStyle(IntPtr dstNode, IntPtr srcNode); public static extern void YGNodeCopyStyle(YGNodeHandle dstNode, YGNodeHandle srcNode);
#region YG_NODE_PROPERTY #region YG_NODE_PROPERTY
[DllImport(DllName)]
public static extern void YGNodeSetContext(IntPtr node, IntPtr context);
[DllImport(DllName)]
public static extern IntPtr YGNodeGetContext(IntPtr node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeSetMeasureFunc( public static extern void YGNodeSetMeasureFunc(
IntPtr node, YGNodeHandle node,
[MarshalAs(UnmanagedType.FunctionPtr)] YogaMeasureFunc measureFunc); [MarshalAs(UnmanagedType.FunctionPtr)] YogaMeasureFunc measureFunc);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.FunctionPtr)] [return: MarshalAs(UnmanagedType.FunctionPtr)]
public static extern YogaMeasureFunc YGNodeGetMeasureFunc(IntPtr node); public static extern YogaMeasureFunc YGNodeGetMeasureFunc(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeSetHasNewLayout(IntPtr node, [MarshalAs(UnmanagedType.I1)] bool hasNewLayout); public static extern void YGNodeSetHasNewLayout(YGNodeHandle node, [MarshalAs(UnmanagedType.I1)] bool hasNewLayout);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
public static extern bool YGNodeGetHasNewLayout(IntPtr node); public static extern bool YGNodeGetHasNewLayout(YGNodeHandle node);
#endregion #endregion
#region YG_NODE_STYLE_PROPERTY #region YG_NODE_STYLE_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetDirection(IntPtr node, YogaDirection direction); public static extern void YGNodeStyleSetDirection(YGNodeHandle node, YogaDirection direction);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaDirection YGNodeStyleGetDirection(IntPtr node); public static extern YogaDirection YGNodeStyleGetDirection(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexDirection(IntPtr node, YogaFlexDirection flexDirection); public static extern void YGNodeStyleSetFlexDirection(YGNodeHandle node, YogaFlexDirection flexDirection);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaFlexDirection YGNodeStyleGetFlexDirection(IntPtr node); public static extern YogaFlexDirection YGNodeStyleGetFlexDirection(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetJustifyContent(IntPtr node, YogaJustify justifyContent); public static extern void YGNodeStyleSetJustifyContent(YGNodeHandle node, YogaJustify justifyContent);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaJustify YGNodeStyleGetJustifyContent(IntPtr node); public static extern YogaJustify YGNodeStyleGetJustifyContent(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAlignContent(IntPtr node, YogaAlign alignContent); public static extern void YGNodeStyleSetAlignContent(YGNodeHandle node, YogaAlign alignContent);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaAlign YGNodeStyleGetAlignContent(IntPtr node); public static extern YogaAlign YGNodeStyleGetAlignContent(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAlignItems(IntPtr node, YogaAlign alignItems); public static extern void YGNodeStyleSetAlignItems(YGNodeHandle node, YogaAlign alignItems);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaAlign YGNodeStyleGetAlignItems(IntPtr node); public static extern YogaAlign YGNodeStyleGetAlignItems(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAlignSelf(IntPtr node, YogaAlign alignSelf); public static extern void YGNodeStyleSetAlignSelf(YGNodeHandle node, YogaAlign alignSelf);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaAlign YGNodeStyleGetAlignSelf(IntPtr node); public static extern YogaAlign YGNodeStyleGetAlignSelf(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetPositionType(IntPtr node, YogaPositionType positionType); public static extern void YGNodeStyleSetPositionType(YGNodeHandle node, YogaPositionType positionType);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaPositionType YGNodeStyleGetPositionType(IntPtr node); public static extern YogaPositionType YGNodeStyleGetPositionType(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexWrap(IntPtr node, YogaWrap flexWrap); public static extern void YGNodeStyleSetFlexWrap(YGNodeHandle node, YogaWrap flexWrap);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaWrap YGNodeStyleGetFlexWrap(IntPtr node); public static extern YogaWrap YGNodeStyleGetFlexWrap(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetOverflow(IntPtr node, YogaOverflow flexWrap); public static extern void YGNodeStyleSetOverflow(YGNodeHandle node, YogaOverflow flexWrap);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaOverflow YGNodeStyleGetOverflow(IntPtr node); public static extern YogaOverflow YGNodeStyleGetOverflow(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlex(IntPtr node, float flex); public static extern void YGNodeStyleSetFlex(YGNodeHandle node, float flex);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexGrow(IntPtr node, float flexGrow); public static extern void YGNodeStyleSetFlexGrow(YGNodeHandle node, float flexGrow);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetFlexGrow(IntPtr node); public static extern float YGNodeStyleGetFlexGrow(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexShrink(IntPtr node, float flexShrink); public static extern void YGNodeStyleSetFlexShrink(YGNodeHandle node, float flexShrink);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetFlexShrink(IntPtr node); public static extern float YGNodeStyleGetFlexShrink(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexBasis(IntPtr node, float flexBasis); public static extern void YGNodeStyleSetFlexBasis(YGNodeHandle node, float flexBasis);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetFlexBasis(IntPtr node); public static extern float YGNodeStyleGetFlexBasis(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetWidth(IntPtr node, float width); public static extern void YGNodeStyleSetWidth(YGNodeHandle node, float width);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetWidth(IntPtr node); public static extern float YGNodeStyleGetWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetHeight(IntPtr node, float height); public static extern void YGNodeStyleSetHeight(YGNodeHandle node, float height);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetHeight(IntPtr node); public static extern float YGNodeStyleGetHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMinWidth(IntPtr node, float minWidth); public static extern void YGNodeStyleSetMinWidth(YGNodeHandle node, float minWidth);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMinWidth(IntPtr node); public static extern float YGNodeStyleGetMinWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMinHeight(IntPtr node, float minHeight); public static extern void YGNodeStyleSetMinHeight(YGNodeHandle node, float minHeight);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMinHeight(IntPtr node); public static extern float YGNodeStyleGetMinHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMaxWidth(IntPtr node, float maxWidth); public static extern void YGNodeStyleSetMaxWidth(YGNodeHandle node, float maxWidth);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMaxWidth(IntPtr node); public static extern float YGNodeStyleGetMaxWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMaxHeight(IntPtr node, float maxHeight); public static extern void YGNodeStyleSetMaxHeight(YGNodeHandle node, float maxHeight);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMaxHeight(IntPtr node); public static extern float YGNodeStyleGetMaxHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAspectRatio(IntPtr node, float aspectRatio); public static extern void YGNodeStyleSetAspectRatio(YGNodeHandle node, float aspectRatio);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetAspectRatio(IntPtr node); public static extern float YGNodeStyleGetAspectRatio(YGNodeHandle node);
#endregion #endregion
#region YG_NODE_STYLE_EDGE_PROPERTY #region YG_NODE_STYLE_EDGE_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetPosition(IntPtr node, YogaEdge edge, float position); public static extern void YGNodeStyleSetPosition(YGNodeHandle node, YogaEdge edge, float position);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetPosition(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMargin(IntPtr node, YogaEdge edge, float margin); public static extern void YGNodeStyleSetMargin(YGNodeHandle node, YogaEdge edge, float margin);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMargin(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetPadding(IntPtr node, YogaEdge edge, float padding); public static extern void YGNodeStyleSetPadding(YGNodeHandle node, YogaEdge edge, float padding);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetPadding(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetBorder(IntPtr node, YogaEdge edge, float border); public static extern void YGNodeStyleSetBorder(YGNodeHandle node, YogaEdge edge, float border);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetBorder(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetBorder(YGNodeHandle node, YogaEdge edge);
#endregion #endregion
#region YG_NODE_LAYOUT_PROPERTY #region YG_NODE_LAYOUT_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetLeft(IntPtr node); public static extern float YGNodeLayoutGetLeft(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetTop(IntPtr node); public static extern float YGNodeLayoutGetTop(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetRight(IntPtr node); public static extern float YGNodeLayoutGetRight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetBottom(IntPtr node); public static extern float YGNodeLayoutGetBottom(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetWidth(IntPtr node); public static extern float YGNodeLayoutGetWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetHeight(IntPtr node); public static extern float YGNodeLayoutGetHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaDirection YGNodeLayoutGetDirection(IntPtr node); public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node);
#endregion #endregion
} }

View File

@@ -31,12 +31,12 @@ namespace Facebook.Yoga
Spacing margin = null, Spacing margin = null,
Spacing padding = null, Spacing padding = null,
Spacing border = null, Spacing border = null,
float? Width = null, float? width = null,
float? Height = null, float? height = null,
float? MaxWidth = null, float? maxWidth = null,
float? MaxHeight = null, float? maxHeight = null,
float? MinWidth = null, float? minWidth = null,
float? MinHeight = null) float? minHeight = null)
{ {
YogaNode node = new YogaNode(); YogaNode node = new YogaNode();
@@ -197,34 +197,34 @@ namespace Facebook.Yoga
} }
} }
if (Width.HasValue) if (width.HasValue)
{ {
node.Width = Width.Value; node.Width = width.Value;
} }
if (Height.HasValue) if (height.HasValue)
{ {
node.Height = Height.Value; node.Height = height.Value;
} }
if (MinWidth.HasValue) if (minWidth.HasValue)
{ {
node.MinWidth = MinWidth.Value; node.MinWidth = minWidth.Value;
} }
if (MinHeight.HasValue) if (minHeight.HasValue)
{ {
node.MinHeight = MinHeight.Value; node.MinHeight = minHeight.Value;
} }
if (MaxWidth.HasValue) if (maxWidth.HasValue)
{ {
node.MaxWidth = MaxWidth.Value; node.MaxWidth = maxWidth.Value;
} }
if (MaxHeight.HasValue) if (maxHeight.HasValue)
{ {
node.MaxHeight = MaxHeight.Value; node.MaxHeight = maxHeight.Value;
} }
return node; return node;

View File

@@ -17,7 +17,7 @@ namespace Facebook.Yoga
{ {
public partial class YogaNode : IEnumerable<YogaNode> public partial class YogaNode : IEnumerable<YogaNode>
{ {
private IntPtr _ygNode; private Native.YGNodeHandle _ygNode;
private WeakReference _parent; private WeakReference _parent;
private List<YogaNode> _children; private List<YogaNode> _children;
private MeasureFunction _measureFunction; private MeasureFunction _measureFunction;
@@ -29,17 +29,12 @@ namespace Facebook.Yoga
YogaLogger.Initialize(); YogaLogger.Initialize();
_ygNode = Native.YGNodeNew(); _ygNode = Native.YGNodeNew();
if (_ygNode == IntPtr.Zero) if (_ygNode.IsInvalid)
{ {
throw new InvalidOperationException("Failed to allocate native memory"); throw new InvalidOperationException("Failed to allocate native memory");
} }
} }
~YogaNode()
{
Native.YGNodeFree(_ygNode);
}
public void Reset() public void Reset()
{ {
_measureFunction = null; _measureFunction = null;
@@ -537,8 +532,7 @@ namespace Facebook.Yoga
throw new InvalidOperationException("Measure function is not defined."); throw new InvalidOperationException("Measure function is not defined.");
} }
long output = _measureFunction(this, width, widthMode, height, heightMode); return _measureFunction(this, width, widthMode, height, heightMode);
return new YogaSize { width = MeasureOutput.GetWidth(output), height = MeasureOutput.GetHeight(output) };
} }
public string Print(YogaPrintOptions options = public string Print(YogaPrintOptions options =

View File

@@ -3,7 +3,8 @@
"version": "3.0.0-*", "version": "3.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.6.0" "NETStandard.Library": "1.6.0",
"System.Runtime.Handles": "4.3.0"
}, },
"frameworks": { "frameworks": {

3
csharp/Unity/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
Yoga
yoga.dll
yoga.unitypackage

64
csharp/Unity/pack.sh Executable file
View File

@@ -0,0 +1,64 @@
#!/bin/sh
# 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.
set -e
cd "$( dirname "$0" )"
if [ \! -f yoga.dll ]; then
echo "Launch win.bat on Windows and copy yoga.dll to here"
exit 1
fi
function build {
buck build $1
echo "$root/`buck targets --show-output $1|tail -1|awk '{print $2}'`"
}
function copy {
mkdir -p $3
cp $1 $3/$2
}
rm -rf Yoga yoga.unitypackage
root=`buck root|tail -f`
mac=$(build '//csharp:yoganet#default,shared')
armv7=$(build '//csharp:yoganet#android-armv7,shared')
ios=$(build '//csharp:yoganet-ios')
win=yoga.dll
Unity -quit -batchMode -createProject Yoga
copy $win ${win##*/} Yoga/Assets/Facebook.Yoga/Plugins/x86_64
copy $mac yoga Yoga/Assets/Facebook.Yoga/Plugins/x86_64/yoga.bundle/Contents/MacOS
armv7path=Assets/Plugins/Android/libs/armeabi-v7a
copy $armv7 ${armv7##*/} Yoga/$armv7path
iospath=Assets/Plugins/iOS
copy $ios ${ios##*/} Yoga/$iospath
libs="$armv7path/${armv7##*/} $iospath/${ios##*/}"
scripts=Yoga/Assets/Facebook.Yoga/Scripts/Facebook.Yoga
mkdir -p $scripts
(cd ../Facebook.Yoga; tar cf - *.cs)|tar -C $scripts -xf -
tests=Yoga/Assets/Facebook.Yoga/Editor/Facebook.Yoga.Tests
mkdir -p $tests
(cd ../tests/Facebook.Yoga; tar cf - *.cs)|tar -C $tests -xf -
function onerror {
local xml=Yoga/EditorTestResults.xml
if [ -f $xml ]; then cat $xml|grep 'success="False"'; fi
}
trap onerror EXIT
Unity -quit -batchMode -projectPath `pwd`/Yoga -runEditorTests
pkg="`pwd`/yoga.unitypackage"
Unity -quit -batchMode -projectPath `pwd`/Yoga -exportPackage Assets/Facebook.Yoga $libs $pkg
echo "Success: $pkg"

2
csharp/Unity/win.bat Executable file
View File

@@ -0,0 +1,2 @@
"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" ..\Yoga\Yoga.vcxproj /p:configuration=Release /property:Platform=x64
xcopy "..\Yoga\x64\Release\yoga.dll" %~dp0 /s /d /y

View File

@@ -21,6 +21,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}</ProjectGuid> <ProjectGuid>{0446C86B-F47B-4C46-B673-C7AE0CFF35D5}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectName>yoga</ProjectName>
<RootNamespace>Yoga</RootNamespace> <RootNamespace>Yoga</RootNamespace>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>

View File

@@ -454,5 +454,226 @@ namespace Facebook.Yoga
Assert.AreEqual(20f, root_child0_child0.LayoutHeight); Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
} }
[Test]
public void Test_flex_grow_within_constrained_min_row()
{
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.MinWidth = 100f;
root.Height = 100f;
YogaNode root_child0 = new YogaNode();
root_child0.FlexGrow = 1f;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Width = 50f;
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(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(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(50f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(50f, root_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0.LayoutHeight);
Assert.AreEqual(0f, 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_flex_grow_within_constrained_min_column()
{
YogaNode root = new YogaNode();
root.MinHeight = 100f;
YogaNode root_child0 = new YogaNode();
root_child0.FlexGrow = 1f;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Height = 50f;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(0f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(0f, 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(0f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(0f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(0f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
[Test]
public void Test_flex_grow_within_constrained_max_row()
{
YogaNode root = new YogaNode();
root.Width = 200f;
YogaNode root_child0 = new YogaNode();
root_child0.FlexDirection = YogaFlexDirection.Row;
root_child0.MaxWidth = 100f;
root_child0.Height = 100f;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.FlexShrink = 1f;
root_child0_child0.FlexBasis = 100f;
root_child0.Insert(0, root_child0_child0);
YogaNode root_child0_child1 = new YogaNode();
root_child0_child1.Width = 50f;
root_child0.Insert(1, root_child0_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(200f, root.LayoutWidth);
Assert.AreEqual(100f, 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(50f, root_child0_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
Assert.AreEqual(50f, root_child0_child1.LayoutX);
Assert.AreEqual(0f, root_child0_child1.LayoutY);
Assert.AreEqual(50f, root_child0_child1.LayoutWidth);
Assert.AreEqual(100f, root_child0_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(100f, root.LayoutHeight);
Assert.AreEqual(100f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0.LayoutHeight);
Assert.AreEqual(50f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(50f, root_child0_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child1.LayoutX);
Assert.AreEqual(0f, root_child0_child1.LayoutY);
Assert.AreEqual(50f, root_child0_child1.LayoutWidth);
Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
}
[Test]
public void Test_flex_grow_within_constrained_max_column()
{
YogaNode root = new YogaNode();
root.Width = 100f;
root.MaxHeight = 100f;
YogaNode root_child0 = new YogaNode();
root_child0.FlexShrink = 1f;
root_child0.FlexBasis = 100f;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Height = 50f;
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(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(100f, 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(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(100f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
}
} }
} }

View File

@@ -87,12 +87,12 @@ namespace Facebook.Yoga
padding: new Spacing(top: 13, bottom: 14, left: 15, right: 16), padding: new Spacing(top: 13, bottom: 14, left: 15, right: 16),
border: new Spacing(top: 17, bottom: 18, left: 19, right: 20), border: new Spacing(top: 17, bottom: 18, left: 19, right: 20),
Width: 21, width: 21,
Height: 22, height: 22,
MinWidth: 23, minWidth: 23,
MinHeight: 24, minHeight: 24,
MaxWidth: 25, maxWidth: 25,
MaxHeight: 26); maxHeight: 26);
Assert.AreEqual(YogaDirection.RTL, node.StyleDirection); Assert.AreEqual(YogaDirection.RTL, node.StyleDirection);
Assert.AreEqual(YogaFlexDirection.RowReverse, node.FlexDirection); Assert.AreEqual(YogaFlexDirection.RowReverse, node.FlexDirection);

View File

@@ -169,8 +169,8 @@ namespace Facebook.Yoga
return MeasureOutput.Make(123.4f, 81.7f); return MeasureOutput.Make(123.4f, 81.7f);
}); });
node.CalculateLayout(); node.CalculateLayout();
Assert.AreEqual(123, node.LayoutWidth); Assert.AreEqual(123.4f, node.LayoutWidth);
Assert.AreEqual(81, node.LayoutHeight); Assert.AreEqual(81.7f, node.LayoutHeight);
} }
[Test] [Test]
@@ -228,7 +228,6 @@ namespace Facebook.Yoga
Assert.AreEqual(100, node0.MaxHeight); Assert.AreEqual(100, node0.MaxHeight);
} }
#if !UNITY_EDITOR
private void ForceGC() private void ForceGC()
{ {
GC.Collect(GC.MaxGeneration); GC.Collect(GC.MaxGeneration);
@@ -356,6 +355,5 @@ namespace Facebook.Yoga
return MeasureOutput.Make(120, 130); return MeasureOutput.Make(120, 130);
}); });
} }
#endif
} }
} }

View File

@@ -1,16 +1,6 @@
#!/bin/sh #!/bin/sh
if clang --version >/dev/null 2>&1; then true; else if mcs --version >/dev/null 2>&1 && mono --version >/dev/null 2>&1; then true; else
echo "ERROR: Can't execute clang. You need to install Xcode and command line tools." echo "ERROR: Need to install Mono (brew install mono, or http://www.mono-project.com/download/)"
exit 1
fi
if mcs --version >/dev/null 2>&1; then true; else
echo "ERROR: Can't execute mcs. You need to install Mono from http://www.mono-project.com/download/ and re-login to apply PATH environment."
exit 1
fi
if mono --version >/dev/null 2>&1; then true; else
echo "ERROR: Can't execute mono64. You need to install Mono from http://www.mono-project.com/download/ and re-login to apply PATH environment."
exit 1 exit 1
fi fi
@@ -28,6 +18,11 @@ if [ -d $NUNIT \
rm NUnit-2.6.4.zip rm NUnit-2.6.4.zip
fi fi
clang -g -Wall -Wextra -dynamiclib -o libyoga.dylib -I../../.. ../../../yoga/*.c ../../Yoga/YGInterop.cpp TARGET=//csharp:yoganet#default,shared
buck build $TARGET
ROOT=`buck root|tail -1`
DYLIB=`buck targets --show-output $TARGET|tail -1|awk '{print $2}'`
cp $ROOT/$DYLIB .
mcs -debug -t:library -r:$NUNIT/nunit.framework.dll -out:YogaTest.dll *.cs ../../../csharp/Facebook.Yoga/*cs mcs -debug -t:library -r:$NUNIT/nunit.framework.dll -out:YogaTest.dll *.cs ../../../csharp/Facebook.Yoga/*cs
MONO_PATH=$NUNIT mono --arch=64 --debug $NUNIT/nunit-console.exe YogaTest.dll MONO_PATH=$NUNIT mono --arch=64 --debug $NUNIT/nunit-console.exe YogaTest.dll

View File

@@ -111,22 +111,22 @@ def to_java_upper(symbol):
return out return out
root = os.path.dirname(__file__) root = os.path.dirname(os.path.abspath(__file__))
# write out C header # write out C headers
with open(root + '/yoga/YGEnums.h', 'w') as f: with open(root + '/yoga/YGEnums.h', 'w') as f:
f.write(LICENSE) f.write(LICENSE)
f.write('#pragma once\n\n') f.write('#pragma once\n\n')
f.write('#include "YGMacros.h"\n\n') f.write('#include "YGMacros.h"\n\n')
f.write('YG_EXTERN_C_BEGIN\n\n') f.write('YG_EXTERN_C_BEGIN\n\n')
for name, values in ENUMS.items(): for name, values in ENUMS.items():
f.write('#define YG%sCount %s\n' % (name, len(values)))
f.write('typedef enum YG%s {\n' % name) f.write('typedef enum YG%s {\n' % name)
for value in values: for value in values:
if isinstance(value, tuple): if isinstance(value, tuple):
f.write(' YG%s%s = %d,\n' % (name, value[0], value[1])) f.write(' YG%s%s = %d,\n' % (name, value[0], value[1]))
else: else:
f.write(' YG%s%s,\n' % (name, value)) f.write(' YG%s%s,\n' % (name, value))
f.write(' YG%sCount,\n' % name)
f.write('} YG%s;\n' % name) f.write('} YG%s;\n' % name)
f.write('\n') f.write('\n')
f.write('YG_EXTERN_C_END\n') f.write('YG_EXTERN_C_END\n')

View File

@@ -41,3 +41,25 @@
<div style="height: 20px; flex-grow: 1;"></div> <div style="height: 20px; flex-grow: 1;"></div>
</div> </div>
</div> </div>
<div id="flex_grow_within_constrained_min_row" style="min-width: 100px; height:100px; flex-direction: row;">
<div style="flex-grow:1;"></div>
<div style="width: 50px;"></div>
</div>
<div id="flex_grow_within_constrained_min_column" style="min-height: 100px;">
<div style="flex-grow:1;"></div>
<div style="height: 50px;"></div>
</div>
<div id="flex_grow_within_constrained_max_row" style="width: 200px;">
<div style="height: 100px; max-width: 100px; flex-direction: row;">
<div style="flex-shrink:1; flex-basis:100px"></div>
<div style="width: 50px;"></div>
</div>
</div>
<div id="flex_grow_within_constrained_max_column" style="max-height: 100px; width: 100px;">
<div style="flex-shrink:1; flex-basis:100px"></div>
<div style="height: 50px;"></div>
</div>

View File

@@ -36,7 +36,7 @@ static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
obj->setFieldValue(topField, YGNodeLayoutGetTop(root)); obj->setFieldValue(topField, YGNodeLayoutGetTop(root));
YGTransferLayoutDirection(root, obj); YGTransferLayoutDirection(root, obj);
for (uint32_t i = 0; i < YGNodeChildCount(root); i++) { for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) {
YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i)); YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i));
} }
} else { } else {

View File

@@ -444,4 +444,221 @@ public class YGMinMaxDimensionTest {
assertEquals(20f, root_child0_child0.getLayoutHeight(), 0.0f); assertEquals(20f, root_child0_child0.getLayoutHeight(), 0.0f);
} }
@Test
public void test_flex_grow_within_constrained_min_row() {
final YogaNode root = new YogaNode();
root.setFlexDirection(YogaFlexDirection.ROW);
root.setMinWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = new YogaNode();
root_child0.setFlexGrow(1f);
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();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, 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(100f, 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(100f, root_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_flex_grow_within_constrained_min_column() {
final YogaNode root = new YogaNode();
root.setMinHeight(100f);
final YogaNode root_child0 = new YogaNode();
root_child0.setFlexGrow(1f);
root.addChildAt(root_child0, 0);
final YogaNode root_child1 = new YogaNode();
root_child1.setHeight(50f);
root.addChildAt(root_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(0f, 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(0f, 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(0f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
root.setDirection(YogaDirection.RTL);
root.calculateLayout();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(0f, 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(0f, 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(0f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_flex_grow_within_constrained_max_row() {
final YogaNode root = new YogaNode();
root.setWidth(200f);
final YogaNode root_child0 = new YogaNode();
root_child0.setFlexDirection(YogaFlexDirection.ROW);
root_child0.setMaxWidth(100f);
root_child0.setHeight(100f);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.setFlexShrink(1f);
root_child0_child0.setFlexBasis(100f);
root_child0.addChildAt(root_child0_child0, 0);
final YogaNode root_child0_child1 = new YogaNode();
root_child0_child1.setWidth(50f);
root_child0.addChildAt(root_child0_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(200f, 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(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(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0_child1.getLayoutHeight(), 0.0f);
root.setDirection(YogaDirection.RTL);
root.calculateLayout();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(200f, 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(100f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0_child1.getLayoutHeight(), 0.0f);
}
@Test
public void test_flex_grow_within_constrained_max_column() {
final YogaNode root = new YogaNode();
root.setWidth(100f);
root.setMaxHeight(100f);
final YogaNode root_child0 = new YogaNode();
root_child0.setFlexShrink(1f);
root_child0.setFlexBasis(100f);
root.addChildAt(root_child0, 0);
final YogaNode root_child1 = new YogaNode();
root_child1.setHeight(50f);
root.addChildAt(root_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(100f, 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(100f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
root.setDirection(YogaDirection.RTL);
root.calculateLayout();
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, 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(100f, 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(100f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
}
} }

View File

@@ -63,12 +63,15 @@ TEST(YogaTest, aspect_ratio_main_defined) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
TEST(YogaTest, aspect_ratio_both_dimensions_defined) { TEST(YogaTest, aspect_ratio_both_dimensions_defined_row) {
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 100); YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100); YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew(); const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 100);
YGNodeStyleSetHeight(root_child0, 50); YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetAspectRatio(root_child0, 1); YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0); YGNodeInsertChild(root, root_child0, 0);
@@ -78,6 +81,28 @@ TEST(YogaTest, aspect_ratio_both_dimensions_defined) {
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0)); ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0)); ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_both_dimensions_defined_column) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 100);
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0)); ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
@@ -351,7 +376,7 @@ TEST(YogaTest, aspect_ratio_double_main) {
const YGNodeRef root_child0 = YGNodeNew(); const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50); YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetAspectRatio(root_child0, 2); YGNodeStyleSetAspectRatio(root_child0, 0.5);
YGNodeInsertChild(root, root_child0, 0); YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
@@ -372,7 +397,7 @@ TEST(YogaTest, aspect_ratio_half_main) {
const YGNodeRef root_child0 = YGNodeNew(); const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 100); YGNodeStyleSetWidth(root_child0, 100);
YGNodeStyleSetAspectRatio(root_child0, 0.5); YGNodeStyleSetAspectRatio(root_child0, 2);
YGNodeInsertChild(root, root_child0, 0); YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
@@ -405,3 +430,249 @@ TEST(YogaTest, aspect_ratio_with_measure_func) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
TEST(YogaTest, aspect_ratio_width_height_flex_grow_row) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 200);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_width_height_flex_grow_column) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 200);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_height_as_flex_basis) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetWidth(root, 200);
YGNodeStyleSetHeight(root, 200);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child1 = YGNodeNew();
YGNodeStyleSetHeight(root_child1, 100);
YGNodeStyleSetFlexGrow(root_child1, 1);
YGNodeStyleSetAspectRatio(root_child1, 1);
YGNodeInsertChild(root, root_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(75, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(75, YGNodeLayoutGetHeight(root_child0));
ASSERT_EQ(75, YGNodeLayoutGetLeft(root_child1));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_EQ(125, YGNodeLayoutGetWidth(root_child1));
ASSERT_EQ(125, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_width_as_flex_basis) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 200);
YGNodeStyleSetHeight(root, 200);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child1 = YGNodeNew();
YGNodeStyleSetWidth(root_child1, 100);
YGNodeStyleSetFlexGrow(root_child1, 1);
YGNodeStyleSetAspectRatio(root_child1, 1);
YGNodeInsertChild(root, root_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(75, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(75, YGNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_EQ(75, YGNodeLayoutGetTop(root_child1));
ASSERT_EQ(125, YGNodeLayoutGetWidth(root_child1));
ASSERT_EQ(125, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_overrides_flex_grow_row) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetAspectRatio(root_child0, 0.5);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_overrides_flex_grow_column) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetAspectRatio(root_child0, 2);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_left_right_absolute) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute);
YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10);
YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10);
YGNodeStyleSetPosition(root_child0, YGEdgeRight, 10);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(10, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(10, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(80, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(80, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_top_bottom_absolute) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute);
YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10);
YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10);
YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(10, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(10, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(80, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(80, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_width_overrides_align_stretch_row) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, aspect_ratio_height_overrides_align_stretch_column) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}

View File

@@ -13,7 +13,7 @@
TEST(YogaTest, assert_default_values) { TEST(YogaTest, assert_default_values) {
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
ASSERT_EQ(0, YGNodeChildCount(root)); ASSERT_EQ(0, YGNodeGetChildCount(root));
ASSERT_EQ(NULL, YGNodeGetChild(root, 1)); ASSERT_EQ(NULL, YGNodeGetChild(root, 1));
ASSERT_EQ(YGDirectionInherit, YGNodeStyleGetDirection(root)); ASSERT_EQ(YGDirectionInherit, YGNodeStyleGetDirection(root));

View File

@@ -56,7 +56,7 @@ TEST(YogaTest, memory_func_test_funcs) {
} }
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
ASSERT_NE(testMallocCount, 0); ASSERT_NE(testMallocCount, 0);
ASSERT_NE(testCallocCount, 0); ASSERT_EQ(testCallocCount, 0);
ASSERT_NE(testReallocCount, 0); ASSERT_NE(testReallocCount, 0);
ASSERT_NE(testFreeCount, 0); ASSERT_NE(testFreeCount, 0);
YGSetMemoryFuncs(NULL, NULL, NULL, NULL); YGSetMemoryFuncs(NULL, NULL, NULL, NULL);

View File

@@ -430,3 +430,216 @@ TEST(YogaTest, flex_grow_within_constrained_max_width) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
TEST(YogaTest, flex_grow_within_constrained_min_row) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetMinWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetFlexGrow(root_child0, 1);
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(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, flex_grow_within_constrained_min_column) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetMinHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child1 = YGNodeNew();
YGNodeStyleSetHeight(root_child1, 50);
YGNodeInsertChild(root, root_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, flex_grow_within_constrained_max_row) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 200);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow);
YGNodeStyleSetMaxWidth(root_child0, 100);
YGNodeStyleSetHeight(root_child0, 100);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child0_child0 = YGNodeNew();
YGNodeStyleSetFlexShrink(root_child0_child0, 1);
YGNodeStyleSetFlexBasis(root_child0_child0, 100);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
const YGNodeRef root_child0_child1 = YGNodeNew();
YGNodeStyleSetWidth(root_child0_child1, 50);
YGNodeInsertChild(root_child0, root_child0_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, flex_grow_within_constrained_max_column) {
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetMaxHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetFlexShrink(root_child0, 1);
YGNodeStyleSetFlexBasis(root_child0, 100);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child1 = YGNodeNew();
YGNodeStyleSetHeight(root_child1, 50);
YGNodeInsertChild(root, root_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
}

View File

@@ -13,28 +13,29 @@
YG_EXTERN_C_BEGIN YG_EXTERN_C_BEGIN
#define YGFlexDirectionCount 4
typedef enum YGFlexDirection { typedef enum YGFlexDirection {
YGFlexDirectionColumn, YGFlexDirectionColumn,
YGFlexDirectionColumnReverse, YGFlexDirectionColumnReverse,
YGFlexDirectionRow, YGFlexDirectionRow,
YGFlexDirectionRowReverse, YGFlexDirectionRowReverse,
YGFlexDirectionCount,
} YGFlexDirection; } YGFlexDirection;
#define YGMeasureModeCount 3
typedef enum YGMeasureMode { typedef enum YGMeasureMode {
YGMeasureModeUndefined, YGMeasureModeUndefined,
YGMeasureModeExactly, YGMeasureModeExactly,
YGMeasureModeAtMost, YGMeasureModeAtMost,
YGMeasureModeCount,
} YGMeasureMode; } YGMeasureMode;
#define YGPrintOptionsCount 3
typedef enum YGPrintOptions { typedef enum YGPrintOptions {
YGPrintOptionsLayout = 1, YGPrintOptionsLayout = 1,
YGPrintOptionsStyle = 2, YGPrintOptionsStyle = 2,
YGPrintOptionsChildren = 4, YGPrintOptionsChildren = 4,
YGPrintOptionsCount,
} YGPrintOptions; } YGPrintOptions;
#define YGEdgeCount 9
typedef enum YGEdge { typedef enum YGEdge {
YGEdgeLeft, YGEdgeLeft,
YGEdgeTop, YGEdgeTop,
@@ -45,72 +46,71 @@ typedef enum YGEdge {
YGEdgeHorizontal, YGEdgeHorizontal,
YGEdgeVertical, YGEdgeVertical,
YGEdgeAll, YGEdgeAll,
YGEdgeCount,
} YGEdge; } YGEdge;
#define YGPositionTypeCount 2
typedef enum YGPositionType { typedef enum YGPositionType {
YGPositionTypeRelative, YGPositionTypeRelative,
YGPositionTypeAbsolute, YGPositionTypeAbsolute,
YGPositionTypeCount,
} YGPositionType; } YGPositionType;
#define YGDimensionCount 2
typedef enum YGDimension { typedef enum YGDimension {
YGDimensionWidth, YGDimensionWidth,
YGDimensionHeight, YGDimensionHeight,
YGDimensionCount,
} YGDimension; } YGDimension;
#define YGJustifyCount 5
typedef enum YGJustify { typedef enum YGJustify {
YGJustifyFlexStart, YGJustifyFlexStart,
YGJustifyCenter, YGJustifyCenter,
YGJustifyFlexEnd, YGJustifyFlexEnd,
YGJustifySpaceBetween, YGJustifySpaceBetween,
YGJustifySpaceAround, YGJustifySpaceAround,
YGJustifyCount,
} YGJustify; } YGJustify;
#define YGDirectionCount 3
typedef enum YGDirection { typedef enum YGDirection {
YGDirectionInherit, YGDirectionInherit,
YGDirectionLTR, YGDirectionLTR,
YGDirectionRTL, YGDirectionRTL,
YGDirectionCount,
} YGDirection; } YGDirection;
#define YGLogLevelCount 5
typedef enum YGLogLevel { typedef enum YGLogLevel {
YGLogLevelError, YGLogLevelError,
YGLogLevelWarn, YGLogLevelWarn,
YGLogLevelInfo, YGLogLevelInfo,
YGLogLevelDebug, YGLogLevelDebug,
YGLogLevelVerbose, YGLogLevelVerbose,
YGLogLevelCount,
} YGLogLevel; } YGLogLevel;
#define YGWrapCount 2
typedef enum YGWrap { typedef enum YGWrap {
YGWrapNoWrap, YGWrapNoWrap,
YGWrapWrap, YGWrapWrap,
YGWrapCount,
} YGWrap; } YGWrap;
#define YGOverflowCount 3
typedef enum YGOverflow { typedef enum YGOverflow {
YGOverflowVisible, YGOverflowVisible,
YGOverflowHidden, YGOverflowHidden,
YGOverflowScroll, YGOverflowScroll,
YGOverflowCount,
} YGOverflow; } YGOverflow;
#define YGExperimentalFeatureCount 2
typedef enum YGExperimentalFeature { typedef enum YGExperimentalFeature {
YGExperimentalFeatureRounding, YGExperimentalFeatureRounding,
YGExperimentalFeatureWebFlexBasis, YGExperimentalFeatureWebFlexBasis,
YGExperimentalFeatureCount,
} YGExperimentalFeature; } YGExperimentalFeature;
#define YGAlignCount 5
typedef enum YGAlign { typedef enum YGAlign {
YGAlignAuto, YGAlignAuto,
YGAlignFlexStart, YGAlignFlexStart,
YGAlignCenter, YGAlignCenter,
YGAlignFlexEnd, YGAlignFlexEnd,
YGAlignStretch, YGAlignStretch,
YGAlignCount,
} YGAlign; } YGAlign;
YG_EXTERN_C_END YG_EXTERN_C_END

View File

@@ -42,7 +42,7 @@ typedef struct YGCachedMeasurement {
// This value was chosen based on empiracle data. Even the most complicated // This value was chosen based on empiracle data. Even the most complicated
// layouts should not require more than 16 entries to fit within the cache. // layouts should not require more than 16 entries to fit within the cache.
enum { YG_MAX_CACHED_RESULT_COUNT = 16 }; #define YG_MAX_CACHED_RESULT_COUNT 16
typedef struct YGLayout { typedef struct YGLayout {
float position[4]; float position[4];
@@ -106,6 +106,66 @@ typedef struct YGNode {
void *context; void *context;
} YGNode; } YGNode;
#define YG_DEFAULT_EDGE_VALUES { \
[YGEdgeLeft] = YGUndefined, \
[YGEdgeTop] = YGUndefined, \
[YGEdgeRight] = YGUndefined, \
[YGEdgeBottom] = YGUndefined, \
[YGEdgeStart] = YGUndefined, \
[YGEdgeEnd] = YGUndefined, \
[YGEdgeHorizontal] = YGUndefined, \
[YGEdgeVertical] = YGUndefined, \
[YGEdgeAll] = YGUndefined, \
}
#define YG_DEFAULT_DIMENSION_VALUES { \
[YGDimensionWidth] = YGUndefined, \
[YGDimensionHeight] = YGUndefined, \
}
YGNode gYGNodeDefaults = {
.parent = NULL,
.children = NULL,
.hasNewLayout = true,
.isDirty = false,
.style = {
.flex = YGUndefined,
.flexGrow = YGUndefined,
.flexShrink = YGUndefined,
.flexBasis = YGUndefined,
.justifyContent = YGJustifyFlexStart,
.alignItems = YGAlignStretch,
.alignContent = YGAlignFlexStart,
.direction = YGDirectionInherit,
.flexDirection = YGFlexDirectionColumn,
.overflow = YGOverflowVisible,
.dimensions = YG_DEFAULT_DIMENSION_VALUES,
.minDimensions = YG_DEFAULT_DIMENSION_VALUES,
.maxDimensions = YG_DEFAULT_DIMENSION_VALUES,
.position = YG_DEFAULT_EDGE_VALUES,
.margin = YG_DEFAULT_EDGE_VALUES,
.padding = YG_DEFAULT_EDGE_VALUES,
.border = YG_DEFAULT_EDGE_VALUES,
.aspectRatio = YGUndefined,
},
.layout = {
.dimensions = YG_DEFAULT_DIMENSION_VALUES,
.lastParentDirection = (YGDirection) -1,
.nextCachedMeasurementsIndex = 0,
.computedFlexBasis = YGUndefined,
.measuredDimensions = YG_DEFAULT_DIMENSION_VALUES,
.cachedLayout = {
.widthMeasureMode = (YGMeasureMode) -1,
.heightMeasureMode = (YGMeasureMode) -1,
.computedWidth = -1,
.computedHeight = -1,
},
},
};
static void YGNodeMarkDirtyInternal(const YGNodeRef node); static void YGNodeMarkDirtyInternal(const YGNodeRef node);
YGMalloc gYGMalloc = &malloc; YGMalloc gYGMalloc = &malloc;
@@ -133,8 +193,6 @@ static int YGAndroidLog(YGLogLevel level, const char *format, va_list args) {
case YGLogLevelVerbose: case YGLogLevelVerbose:
androidLevel = ANDROID_LOG_VERBOSE; androidLevel = ANDROID_LOG_VERBOSE;
break; break;
case YGLogLevelCount:
break;
} }
const int result = __android_log_vprint(androidLevel, "YG-layout", format, args); const int result = __android_log_vprint(androidLevel, "YG-layout", format, args);
return result; return result;
@@ -185,68 +243,14 @@ static inline float YGComputedEdgeValue(const float edges[YGEdgeCount],
return defaultValue; return defaultValue;
} }
static void YGNodeInit(const YGNodeRef node) {
node->parent = NULL;
node->children = NULL;
node->hasNewLayout = true;
node->isDirty = false;
node->style.flex = YGUndefined;
node->style.flexGrow = YGUndefined;
node->style.flexShrink = YGUndefined;
node->style.flexBasis = YGUndefined;
node->style.alignItems = YGAlignStretch;
node->style.alignContent = YGAlignFlexStart;
node->style.direction = YGDirectionInherit;
node->style.flexDirection = YGFlexDirectionColumn;
node->style.overflow = YGOverflowVisible;
// Some of the fields default to undefined and not 0
node->style.dimensions[YGDimensionWidth] = YGUndefined;
node->style.dimensions[YGDimensionHeight] = YGUndefined;
node->style.minDimensions[YGDimensionWidth] = YGUndefined;
node->style.minDimensions[YGDimensionHeight] = YGUndefined;
node->style.maxDimensions[YGDimensionWidth] = YGUndefined;
node->style.maxDimensions[YGDimensionHeight] = YGUndefined;
for (YGEdge edge = YGEdgeLeft; edge < YGEdgeCount; edge++) {
node->style.position[edge] = YGUndefined;
node->style.margin[edge] = YGUndefined;
node->style.padding[edge] = YGUndefined;
node->style.border[edge] = YGUndefined;
}
node->style.aspectRatio = YGUndefined;
node->layout.dimensions[YGDimensionWidth] = YGUndefined;
node->layout.dimensions[YGDimensionHeight] = YGUndefined;
// Such that the comparison is always going to be false
node->layout.lastParentDirection = (YGDirection) -1;
node->layout.nextCachedMeasurementsIndex = 0;
node->layout.computedFlexBasis = YGUndefined;
node->layout.measuredDimensions[YGDimensionWidth] = YGUndefined;
node->layout.measuredDimensions[YGDimensionHeight] = YGUndefined;
node->layout.cachedLayout.widthMeasureMode = (YGMeasureMode) -1;
node->layout.cachedLayout.heightMeasureMode = (YGMeasureMode) -1;
node->layout.cachedLayout.computedWidth = -1;
node->layout.cachedLayout.computedHeight = -1;
}
int32_t gNodeInstanceCount = 0; int32_t gNodeInstanceCount = 0;
YGNodeRef YGNodeNew(void) { YGNodeRef YGNodeNew(void) {
const YGNodeRef node = gYGCalloc(1, sizeof(YGNode)); const YGNodeRef node = gYGMalloc(sizeof(YGNode));
YG_ASSERT(node, "Could not allocate memory for node"); YG_ASSERT(node, "Could not allocate memory for node");
gNodeInstanceCount++; gNodeInstanceCount++;
YGNodeInit(node); memcpy(node, &gYGNodeDefaults, sizeof(YGNode));
return node; return node;
} }
@@ -256,7 +260,7 @@ void YGNodeFree(const YGNodeRef node) {
node->parent = NULL; node->parent = NULL;
} }
const uint32_t childCount = YGNodeChildCount(node); const uint32_t childCount = YGNodeGetChildCount(node);
for (uint32_t i = 0; i < childCount; i++) { for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeGetChild(node, i); const YGNodeRef child = YGNodeGetChild(node, i);
child->parent = NULL; child->parent = NULL;
@@ -268,7 +272,7 @@ void YGNodeFree(const YGNodeRef node) {
} }
void YGNodeFreeRecursive(const YGNodeRef root) { void YGNodeFreeRecursive(const YGNodeRef root) {
while (YGNodeChildCount(root) > 0) { while (YGNodeGetChildCount(root) > 0) {
const YGNodeRef child = YGNodeGetChild(root, 0); const YGNodeRef child = YGNodeGetChild(root, 0);
YGNodeRemoveChild(root, child); YGNodeRemoveChild(root, child);
YGNodeFreeRecursive(child); YGNodeFreeRecursive(child);
@@ -277,12 +281,11 @@ void YGNodeFreeRecursive(const YGNodeRef root) {
} }
void YGNodeReset(const YGNodeRef node) { void YGNodeReset(const YGNodeRef node) {
YG_ASSERT(YGNodeChildCount(node) == 0, "Cannot reset a node which still has children attached"); YG_ASSERT(YGNodeGetChildCount(node) == 0, "Cannot reset a node which still has children attached");
YG_ASSERT(node->parent == NULL, "Cannot reset a node still attached to a parent"); YG_ASSERT(node->parent == NULL, "Cannot reset a node still attached to a parent");
YGNodeListFree(node->children); YGNodeListFree(node->children);
memset(node, 0, sizeof(YGNode)); memcpy(node, &gYGNodeDefaults, sizeof(YGNode));
YGNodeInit(node);
} }
int32_t YGNodeGetInstanceCount(void) { int32_t YGNodeGetInstanceCount(void) {
@@ -303,7 +306,7 @@ void YGNodeSetMeasureFunc(const YGNodeRef node, YGMeasureFunc measureFunc) {
if (measureFunc == NULL) { if (measureFunc == NULL) {
node->measure = NULL; node->measure = NULL;
} else { } else {
YG_ASSERT(YGNodeChildCount(node) == 0, YG_ASSERT(YGNodeGetChildCount(node) == 0,
"Cannot set measure function: Nodes with measure functions cannot have children."); "Cannot set measure function: Nodes with measure functions cannot have children.");
node->measure = measureFunc; node->measure = measureFunc;
} }
@@ -333,7 +336,11 @@ YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index) {
return YGNodeListGet(node->children, index); return YGNodeListGet(node->children, index);
} }
inline uint32_t YGNodeChildCount(const YGNodeRef node) { YGNodeRef YGNodeGetParent(const YGNodeRef node) {
return node->parent;
}
inline uint32_t YGNodeGetChildCount(const YGNodeRef node) {
return YGNodeListCount(node->children); return YGNodeListCount(node->children);
} }
@@ -820,7 +827,7 @@ static YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection,
static inline bool YGNodeIsFlex(const YGNodeRef node) { static inline bool YGNodeIsFlex(const YGNodeRef node) {
return (node->style.positionType == YGPositionTypeRelative && return (node->style.positionType == YGPositionTypeRelative &&
(node->style.flexGrow != 0 || node->style.flexShrink != 0 || node->style.flex != 0)); (YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
} }
static inline float YGNodeDimWithMargin(const YGNodeRef node, const YGFlexDirection axis) { static inline float YGNodeDimWithMargin(const YGNodeRef node, const YGFlexDirection axis) {
@@ -946,8 +953,6 @@ static void YGConstrainMaxSizeForMode(const float maxSize, YGMeasureMode *mode,
*size = maxSize; *size = maxSize;
} }
break; break;
case YGMeasureModeCount:
break;
} }
} }
@@ -1057,7 +1062,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (!YGValueIsUndefined(child->style.aspectRatio)) { if (!YGValueIsUndefined(child->style.aspectRatio)) {
if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(childWidth * child->style.aspectRatio, fmaxf(childWidth / child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn));
return; return;
} else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { } else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
@@ -1152,7 +1157,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
childWidth = fmaxf(childHeight * child->style.aspectRatio, childWidth = fmaxf(childHeight * child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn));
} else if (YGValueIsUndefined(childHeight)) { } else if (YGValueIsUndefined(childHeight)) {
childHeight = fmaxf(childWidth * child->style.aspectRatio, childHeight = fmaxf(childWidth / child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow));
} }
} }
@@ -1495,17 +1500,32 @@ static void YGNodelayoutImpl(const YGNodeRef node,
const YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; const YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;
const YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; const YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;
const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow); const float paddingAndBorderAxisRow = isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross;
const float paddingAndBorderAxisColumn = const float paddingAndBorderAxisColumn = isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain;
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn);
const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow); const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow);
const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn); const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn);
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
const float availableInnerHeight = const float minInnerWidth = node->style.minDimensions[YGDimensionWidth] - marginAxisRow - paddingAndBorderAxisRow;
const float maxInnerWidth = node->style.maxDimensions[YGDimensionWidth] - marginAxisRow - paddingAndBorderAxisRow;
float availableInnerHeight =
availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; const float minInnerHeight = node->style.minDimensions[YGDimensionHeight] - marginAxisColumn - paddingAndBorderAxisColumn;
const float maxInnerHeight = node->style.maxDimensions[YGDimensionHeight] - marginAxisColumn - paddingAndBorderAxisColumn;
const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight;
const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight;
// Max dimension overrides predefined dimension value; Min dimension in turn overrides both of the above
if (!YGValueIsUndefined(availableInnerWidth)) {
availableInnerWidth = fmaxf(fminf(availableInnerWidth, maxInnerWidth), minInnerWidth);
}
if (!YGValueIsUndefined(availableInnerHeight)) {
availableInnerHeight = fmaxf(fminf(availableInnerHeight, maxInnerHeight), minInnerHeight);
}
float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
// If there is only one child with flexGrow + flexShrink it means we can set the // If there is only one child with flexGrow + flexShrink it means we can set the
@@ -1659,6 +1679,18 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Calculate the remaining available space that needs to be allocated. // Calculate the remaining available space that needs to be allocated.
// If the main dimension size isn't known, it is computed based on // If the main dimension size isn't known, it is computed based on
// the line length, so there's no more space left to distribute. // the line length, so there's no more space left to distribute.
// We resolve main dimension to fit minimum and maximum values
if (YGValueIsUndefined(availableInnerMainDim)) {
if (!YGValueIsUndefined(minInnerMainDim) &&
sizeConsumedOnCurrentLine < minInnerMainDim) {
availableInnerMainDim = minInnerMainDim;
} else if (!YGValueIsUndefined(maxInnerMainDim) &&
sizeConsumedOnCurrentLine > maxInnerMainDim) {
availableInnerMainDim = maxInnerMainDim;
}
}
float remainingFreeSpace = 0; float remainingFreeSpace = 0;
if (!YGValueIsUndefined(availableInnerMainDim)) { if (!YGValueIsUndefined(availableInnerMainDim)) {
remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine; remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine;
@@ -1846,16 +1878,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
} }
if (!YGValueIsUndefined(currentRelativeChild->style.aspectRatio)) { if (!YGValueIsUndefined(currentRelativeChild->style.aspectRatio)) {
if (isMainAxisRow && childHeightMeasureMode != YGMeasureModeExactly) { if (isMainAxisRow) {
childHeight = childHeight =
fmaxf(childWidth * currentRelativeChild->style.aspectRatio, fmaxf(childWidth / currentRelativeChild->style.aspectRatio,
YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionColumn)); YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionColumn));
childHeightMeasureMode = YGMeasureModeExactly; childHeightMeasureMode = YGMeasureModeExactly;
} else if (!isMainAxisRow && childWidthMeasureMode != YGMeasureModeExactly) {
childHeight = fminf(childHeight, availableInnerHeight);
childWidth = childHeight * currentRelativeChild->style.aspectRatio;
} else {
childWidth = childWidth =
fmaxf(childHeight * currentRelativeChild->style.aspectRatio, fmaxf(childHeight * currentRelativeChild->style.aspectRatio,
YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionRow)); YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionRow));
childWidthMeasureMode = YGMeasureModeExactly; childWidthMeasureMode = YGMeasureModeExactly;
childWidth = fminf(childWidth, availableInnerWidth);
childHeight = childWidth / currentRelativeChild->style.aspectRatio;
} }
} }
@@ -1930,7 +1968,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
leadingMainDim = betweenMainDim / 2; leadingMainDim = betweenMainDim / 2;
break; break;
case YGJustifyFlexStart: case YGJustifyFlexStart:
case YGJustifyCount:
break; break;
} }
@@ -2048,13 +2085,23 @@ static void YGNodelayoutImpl(const YGNodeRef node,
YGMeasureMode childHeightMeasureMode = YGMeasureModeExactly; YGMeasureMode childHeightMeasureMode = YGMeasureModeExactly;
if (isMainAxisRow) { if (isMainAxisRow) {
childHeight = crossDim;
childWidth = child->layout.measuredDimensions[YGDimensionWidth] + childWidth = child->layout.measuredDimensions[YGDimensionWidth] +
YGNodeMarginForAxis(child, YGFlexDirectionRow); YGNodeMarginForAxis(child, YGFlexDirectionRow);
if (!YGValueIsUndefined(child->style.aspectRatio)) {
childHeight = childWidth / child->style.aspectRatio;
} else {
childHeight = crossDim;
}
} else { } else {
childWidth = crossDim;
childHeight = child->layout.measuredDimensions[YGDimensionHeight] + childHeight = child->layout.measuredDimensions[YGDimensionHeight] +
YGNodeMarginForAxis(child, YGFlexDirectionColumn); YGNodeMarginForAxis(child, YGFlexDirectionColumn);
if (!YGValueIsUndefined(child->style.aspectRatio)) {
childWidth = childHeight * child->style.aspectRatio;
} else {
childWidth = crossDim;
}
} }
YGConstrainMaxSizeForMode(child->style.maxDimensions[YGDimensionWidth], YGConstrainMaxSizeForMode(child->style.maxDimensions[YGDimensionWidth],
@@ -2123,7 +2170,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
break; break;
case YGAlignAuto: case YGAlignAuto:
case YGAlignFlexStart: case YGAlignFlexStart:
case YGAlignCount:
break; break;
} }
@@ -2183,7 +2229,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
break; break;
} }
case YGAlignAuto: case YGAlignAuto:
case YGAlignCount:
break; break;
} }
} }

View File

@@ -64,7 +64,8 @@ WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
const uint32_t index); const uint32_t index);
WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child); WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child);
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index); WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
WIN_EXPORT uint32_t YGNodeChildCount(const YGNodeRef node); WIN_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node);
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node, WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
const float availableWidth, const float availableWidth,
@@ -150,6 +151,9 @@ YG_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
// Yoga specific properties, not compatible with flexbox specification // Yoga specific properties, not compatible with flexbox specification
// Aspect ratio control the size of the undefined dimension of a node. // Aspect ratio control the size of the undefined dimension of a node.
// Aspect ratio is encoded as a floating point value width/height. e.g. A value of 2 leads to a node
// with a width twice the size of its height while a value of 0.5 gives the opposite effect.
//
// - On a node with a set width/height aspect ratio control the size of the unset dimension // - On a node with a set width/height aspect ratio control the size of the unset dimension
// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if // - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if
// unset // unset