diff --git a/.gitignore b/.gitignore index 5b346768..fca97a4b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,44 @@ # Visual studio code .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 diff --git a/.hgignore b/.hgignore index 5b346768..fca97a4b 100644 --- a/.hgignore +++ b/.hgignore @@ -8,3 +8,44 @@ # Visual studio code .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 diff --git a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.xcworkspace/xcuserdata/emilsj.xcuserdatad/UserInterfaceState.xcuserstate b/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.xcworkspace/xcuserdata/emilsj.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 47db969a..00000000 Binary files a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/project.xcworkspace/xcuserdata/emilsj.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/xcuserdata/emilsj.xcuserdatad/xcschemes/YogaKitSample.xcscheme b/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/xcuserdata/emilsj.xcuserdatad/xcschemes/YogaKitSample.xcscheme deleted file mode 100644 index e785e85e..00000000 --- a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/xcuserdata/emilsj.xcuserdatad/xcschemes/YogaKitSample.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/xcuserdata/emilsj.xcuserdatad/xcschemes/xcschememanagement.plist b/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/xcuserdata/emilsj.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index 336f995f..00000000 --- a/YogaKit/YogaKitSample/YogaKitSample.xcodeproj/xcuserdata/emilsj.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - SchemeUserState - - YogaKitSample.xcscheme - - orderHint - 0 - - - SuppressBuildableAutocreation - - 13687D421DF8748300E7C260 - - primary - - - - - diff --git a/csharp/Facebook.Yoga/Native.cs b/csharp/Facebook.Yoga/Native.cs index f9ad6282..a1cc0437 100644 --- a/csharp/Facebook.Yoga/Native.cs +++ b/csharp/Facebook.Yoga/Native.cs @@ -20,18 +20,40 @@ namespace Facebook.Yoga private const string DllName = "yoga"; #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)] public static extern void YGInteropSetLogger( [MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func); [DllImport(DllName)] - public static extern IntPtr YGNodeNew(); + public static extern YGNodeHandle YGNodeNew(); [DllImport(DllName)] public static extern void YGNodeFree(IntPtr node); [DllImport(DllName)] - public static extern void YGNodeReset(IntPtr node); + public static extern void YGNodeReset(YGNodeHandle node); [DllImport(DllName)] public static extern int YGNodeGetInstanceCount(); @@ -46,237 +68,231 @@ namespace Facebook.Yoga YogaExperimentalFeature feature); [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)] - public static extern void YGNodeRemoveChild(IntPtr node, IntPtr child); + public static extern void YGNodeRemoveChild(YGNodeHandle node, YGNodeHandle child); [DllImport(DllName)] - public static extern IntPtr YGNodeGetChild(IntPtr node, uint index); - - [DllImport(DllName)] - public static extern uint YGNodeGetChildCount(IntPtr node); - - [DllImport(DllName)] - public static extern void YGNodeCalculateLayout(IntPtr node, + public static extern void YGNodeCalculateLayout(YGNodeHandle node, float availableWidth, float availableHeight, YogaDirection parentDirection); [DllImport(DllName)] - public static extern void YGNodeMarkDirty(IntPtr node); + public static extern void YGNodeMarkDirty(YGNodeHandle node); [DllImport(DllName)] [return: MarshalAs(UnmanagedType.I1)] - public static extern bool YGNodeIsDirty(IntPtr node); + public static extern bool YGNodeIsDirty(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodePrint(IntPtr node, YogaPrintOptions options); + public static extern void YGNodePrint(YGNodeHandle node, YogaPrintOptions options); [DllImport(DllName)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool YGValueIsUndefined(float value); [DllImport(DllName)] - public static extern void YGNodeCopyStyle(IntPtr dstNode, IntPtr srcNode); + public static extern void YGNodeCopyStyle(YGNodeHandle dstNode, YGNodeHandle srcNode); #region YG_NODE_PROPERTY [DllImport(DllName)] - public static extern void YGNodeSetContext(IntPtr node, IntPtr context); + public static extern void YGNodeSetContext(YGNodeHandle node, IntPtr context); [DllImport(DllName)] - public static extern IntPtr YGNodeGetContext(IntPtr node); + public static extern IntPtr YGNodeGetContext(YGNodeHandle node); [DllImport(DllName)] public static extern void YGNodeSetMeasureFunc( - IntPtr node, + YGNodeHandle node, [MarshalAs(UnmanagedType.FunctionPtr)] YogaMeasureFunc measureFunc); [DllImport(DllName)] [return: MarshalAs(UnmanagedType.FunctionPtr)] - public static extern YogaMeasureFunc YGNodeGetMeasureFunc(IntPtr node); + public static extern YogaMeasureFunc YGNodeGetMeasureFunc(YGNodeHandle node); [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)] [return: MarshalAs(UnmanagedType.I1)] - public static extern bool YGNodeGetHasNewLayout(IntPtr node); + public static extern bool YGNodeGetHasNewLayout(YGNodeHandle node); #endregion #region YG_NODE_STYLE_PROPERTY [DllImport(DllName)] - public static extern void YGNodeStyleSetDirection(IntPtr node, YogaDirection direction); + public static extern void YGNodeStyleSetDirection(YGNodeHandle node, YogaDirection direction); [DllImport(DllName)] - public static extern YogaDirection YGNodeStyleGetDirection(IntPtr node); + public static extern YogaDirection YGNodeStyleGetDirection(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetFlexDirection(IntPtr node, YogaFlexDirection flexDirection); + public static extern void YGNodeStyleSetFlexDirection(YGNodeHandle node, YogaFlexDirection flexDirection); [DllImport(DllName)] - public static extern YogaFlexDirection YGNodeStyleGetFlexDirection(IntPtr node); + public static extern YogaFlexDirection YGNodeStyleGetFlexDirection(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetJustifyContent(IntPtr node, YogaJustify justifyContent); + public static extern void YGNodeStyleSetJustifyContent(YGNodeHandle node, YogaJustify justifyContent); [DllImport(DllName)] - public static extern YogaJustify YGNodeStyleGetJustifyContent(IntPtr node); + public static extern YogaJustify YGNodeStyleGetJustifyContent(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetAlignContent(IntPtr node, YogaAlign alignContent); + public static extern void YGNodeStyleSetAlignContent(YGNodeHandle node, YogaAlign alignContent); [DllImport(DllName)] - public static extern YogaAlign YGNodeStyleGetAlignContent(IntPtr node); + public static extern YogaAlign YGNodeStyleGetAlignContent(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetAlignItems(IntPtr node, YogaAlign alignItems); + public static extern void YGNodeStyleSetAlignItems(YGNodeHandle node, YogaAlign alignItems); [DllImport(DllName)] - public static extern YogaAlign YGNodeStyleGetAlignItems(IntPtr node); + public static extern YogaAlign YGNodeStyleGetAlignItems(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetAlignSelf(IntPtr node, YogaAlign alignSelf); + public static extern void YGNodeStyleSetAlignSelf(YGNodeHandle node, YogaAlign alignSelf); [DllImport(DllName)] - public static extern YogaAlign YGNodeStyleGetAlignSelf(IntPtr node); + public static extern YogaAlign YGNodeStyleGetAlignSelf(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetPositionType(IntPtr node, YogaPositionType positionType); + public static extern void YGNodeStyleSetPositionType(YGNodeHandle node, YogaPositionType positionType); [DllImport(DllName)] - public static extern YogaPositionType YGNodeStyleGetPositionType(IntPtr node); + public static extern YogaPositionType YGNodeStyleGetPositionType(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetFlexWrap(IntPtr node, YogaWrap flexWrap); + public static extern void YGNodeStyleSetFlexWrap(YGNodeHandle node, YogaWrap flexWrap); [DllImport(DllName)] - public static extern YogaWrap YGNodeStyleGetFlexWrap(IntPtr node); + public static extern YogaWrap YGNodeStyleGetFlexWrap(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetOverflow(IntPtr node, YogaOverflow flexWrap); + public static extern void YGNodeStyleSetOverflow(YGNodeHandle node, YogaOverflow flexWrap); [DllImport(DllName)] - public static extern YogaOverflow YGNodeStyleGetOverflow(IntPtr node); + public static extern YogaOverflow YGNodeStyleGetOverflow(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetFlex(IntPtr node, float flex); + public static extern void YGNodeStyleSetFlex(YGNodeHandle node, float flex); [DllImport(DllName)] - public static extern void YGNodeStyleSetFlexGrow(IntPtr node, float flexGrow); + public static extern void YGNodeStyleSetFlexGrow(YGNodeHandle node, float flexGrow); [DllImport(DllName)] - public static extern float YGNodeStyleGetFlexGrow(IntPtr node); + public static extern float YGNodeStyleGetFlexGrow(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetFlexShrink(IntPtr node, float flexShrink); + public static extern void YGNodeStyleSetFlexShrink(YGNodeHandle node, float flexShrink); [DllImport(DllName)] - public static extern float YGNodeStyleGetFlexShrink(IntPtr node); + public static extern float YGNodeStyleGetFlexShrink(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetFlexBasis(IntPtr node, YogaValue flexBasis); + public static extern void YGNodeStyleSetFlexBasis(YGNodeHandle node, YogaValue flexBasis); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetFlexBasis(IntPtr node); + public static extern YogaValue YGNodeStyleGetFlexBasis(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetWidth(IntPtr node, YogaValue width); + public static extern void YGNodeStyleSetWidth(YGNodeHandle node, YogaValue width); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetWidth(IntPtr node); + public static extern YogaValue YGNodeStyleGetWidth(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetHeight(IntPtr node, YogaValue height); + public static extern void YGNodeStyleSetHeight(YGNodeHandle node, YogaValue height); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetHeight(IntPtr node); + public static extern YogaValue YGNodeStyleGetHeight(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetMinWidth(IntPtr node, YogaValue minWidth); + public static extern void YGNodeStyleSetMinWidth(YGNodeHandle node, YogaValue minWidth); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetMinWidth(IntPtr node); + public static extern YogaValue YGNodeStyleGetMinWidth(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetMinHeight(IntPtr node, YogaValue minHeight); + public static extern void YGNodeStyleSetMinHeight(YGNodeHandle node, YogaValue minHeight); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetMinHeight(IntPtr node); + public static extern YogaValue YGNodeStyleGetMinHeight(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetMaxWidth(IntPtr node, YogaValue maxWidth); + public static extern void YGNodeStyleSetMaxWidth(YGNodeHandle node, YogaValue maxWidth); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetMaxWidth(IntPtr node); + public static extern YogaValue YGNodeStyleGetMaxWidth(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetMaxHeight(IntPtr node, YogaValue maxHeight); + public static extern void YGNodeStyleSetMaxHeight(YGNodeHandle node, YogaValue maxHeight); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetMaxHeight(IntPtr node); + public static extern YogaValue YGNodeStyleGetMaxHeight(YGNodeHandle node); [DllImport(DllName)] - public static extern void YGNodeStyleSetAspectRatio(IntPtr node, float aspectRatio); + public static extern void YGNodeStyleSetAspectRatio(YGNodeHandle node, float aspectRatio); [DllImport(DllName)] - public static extern float YGNodeStyleGetAspectRatio(IntPtr node); + public static extern float YGNodeStyleGetAspectRatio(YGNodeHandle node); #endregion #region YG_NODE_STYLE_EDGE_PROPERTY [DllImport(DllName)] - public static extern void YGNodeStyleSetPosition(IntPtr node, YogaEdge edge, YogaValue position); + public static extern void YGNodeStyleSetPosition(YGNodeHandle node, YogaEdge edge, YogaValue position); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetPosition(IntPtr node, YogaEdge edge); + public static extern YogaValue YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge); [DllImport(DllName)] - public static extern void YGNodeStyleSetMargin(IntPtr node, YogaEdge edge, YogaValue margin); + public static extern void YGNodeStyleSetMargin(YGNodeHandle node, YogaEdge edge, YogaValue margin); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetMargin(IntPtr node, YogaEdge edge); + public static extern YogaValue YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge); [DllImport(DllName)] - public static extern void YGNodeStyleSetPadding(IntPtr node, YogaEdge edge, YogaValue padding); + public static extern void YGNodeStyleSetPadding(YGNodeHandle node, YogaEdge edge, YogaValue padding); [DllImport(DllName)] - public static extern YogaValue YGNodeStyleGetPadding(IntPtr node, YogaEdge edge); + public static extern YogaValue YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge); [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)] - public static extern float YGNodeStyleGetBorder(IntPtr node, YogaEdge edge); + public static extern float YGNodeStyleGetBorder(YGNodeHandle node, YogaEdge edge); #endregion #region YG_NODE_LAYOUT_PROPERTY [DllImport(DllName)] - public static extern float YGNodeLayoutGetLeft(IntPtr node); + public static extern float YGNodeLayoutGetLeft(YGNodeHandle node); [DllImport(DllName)] - public static extern float YGNodeLayoutGetTop(IntPtr node); + public static extern float YGNodeLayoutGetTop(YGNodeHandle node); [DllImport(DllName)] - public static extern float YGNodeLayoutGetRight(IntPtr node); + public static extern float YGNodeLayoutGetRight(YGNodeHandle node); [DllImport(DllName)] - public static extern float YGNodeLayoutGetBottom(IntPtr node); + public static extern float YGNodeLayoutGetBottom(YGNodeHandle node); [DllImport(DllName)] - public static extern float YGNodeLayoutGetWidth(IntPtr node); + public static extern float YGNodeLayoutGetWidth(YGNodeHandle node); [DllImport(DllName)] - public static extern float YGNodeLayoutGetHeight(IntPtr node); + public static extern float YGNodeLayoutGetHeight(YGNodeHandle node); [DllImport(DllName)] - public static extern YogaDirection YGNodeLayoutGetDirection(IntPtr node); + public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node); #endregion } diff --git a/csharp/Facebook.Yoga/YogaNode.cs b/csharp/Facebook.Yoga/YogaNode.cs index 5948f852..02b1954c 100644 --- a/csharp/Facebook.Yoga/YogaNode.cs +++ b/csharp/Facebook.Yoga/YogaNode.cs @@ -16,7 +16,7 @@ namespace Facebook.Yoga { public partial class YogaNode : IEnumerable { - private IntPtr _ygNode; + private Native.YGNodeHandle _ygNode; private WeakReference _parent; private List _children; private MeasureFunction _measureFunction; @@ -28,17 +28,12 @@ namespace Facebook.Yoga YogaLogger.Initialize(); _ygNode = Native.YGNodeNew(); - if (_ygNode == IntPtr.Zero) + if (_ygNode.IsInvalid) { throw new InvalidOperationException("Failed to allocate native memory"); } } - ~YogaNode() - { - Native.YGNodeFree(_ygNode); - } - public void Reset() { _measureFunction = null; diff --git a/csharp/Facebook.Yoga/project.json b/csharp/Facebook.Yoga/project.json index a0454a86..a188a056 100644 --- a/csharp/Facebook.Yoga/project.json +++ b/csharp/Facebook.Yoga/project.json @@ -3,7 +3,8 @@ "version": "3.0.0-*", "dependencies": { - "NETStandard.Library": "1.6.0" + "NETStandard.Library": "1.6.0", + "System.Runtime.Handles": "4.3.0" }, "frameworks": { diff --git a/csharp/Unity/.gitignore b/csharp/Unity/.gitignore new file mode 100644 index 00000000..a26b100a --- /dev/null +++ b/csharp/Unity/.gitignore @@ -0,0 +1,3 @@ +Yoga +yoga.dll +yoga.unitypackage diff --git a/csharp/Unity/pack.sh b/csharp/Unity/pack.sh new file mode 100755 index 00000000..cc79ef0b --- /dev/null +++ b/csharp/Unity/pack.sh @@ -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" diff --git a/csharp/Unity/win.bat b/csharp/Unity/win.bat new file mode 100755 index 00000000..3f838cd4 --- /dev/null +++ b/csharp/Unity/win.bat @@ -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 diff --git a/csharp/tests/Facebook.Yoga/YogaNodeTest.cs b/csharp/tests/Facebook.Yoga/YogaNodeTest.cs index acf33f4b..a404c5fc 100644 --- a/csharp/tests/Facebook.Yoga/YogaNodeTest.cs +++ b/csharp/tests/Facebook.Yoga/YogaNodeTest.cs @@ -228,7 +228,6 @@ namespace Facebook.Yoga Assert.AreEqual(100.Px(), node0.MaxHeight); } -#if !UNITY_EDITOR private void ForceGC() { GC.Collect(GC.MaxGeneration); @@ -356,6 +355,5 @@ namespace Facebook.Yoga return MeasureOutput.Make(120, 130); }); } -#endif } } diff --git a/enums.py b/enums.py index e51d3ee8..c8caf95b 100644 --- a/enums.py +++ b/enums.py @@ -115,22 +115,22 @@ def to_java_upper(symbol): 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: f.write(LICENSE) f.write('#pragma once\n\n') f.write('#include "YGMacros.h"\n\n') f.write('YG_EXTERN_C_BEGIN\n\n') for name, values in ENUMS.items(): + f.write('#define YG%sCount %s\n' % (name, len(values))) f.write('typedef enum YG%s {\n' % name) for value in values: if isinstance(value, tuple): f.write(' YG%s%s = %d,\n' % (name, value[0], value[1])) else: f.write(' YG%s%s,\n' % (name, value)) - f.write(' YG%sCount,\n' % name) f.write('} YG%s;\n' % name) f.write('\n') f.write('YG_EXTERN_C_END\n') diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index 7dd4ccc0..67cc661b 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -63,12 +63,15 @@ TEST(YogaTest, aspect_ratio_main_defined) { YGNodeFreeRecursive(root); } -TEST(YogaTest, aspect_ratio_both_dimensions_defined) { +TEST(YogaTest, aspect_ratio_both_dimensions_defined_row) { const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); YGNodeStyleSetWidth(root, YGPx(100)); YGNodeStyleSetHeight(root, YGPx(100)); const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(100)); YGNodeStyleSetHeight(root_child0, YGPx(50)); YGNodeStyleSetAspectRatio(root_child0, 1); 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, YGNodeLayoutGetTop(root_child0)); ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0)); + ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, aspect_ratio_both_dimensions_defined_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(100)); + YGNodeStyleSetHeight(root_child0, YGPx(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); @@ -351,7 +376,7 @@ TEST(YogaTest, aspect_ratio_double_main) { const YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, YGPx(50)); - YGNodeStyleSetAspectRatio(root_child0, 2); + YGNodeStyleSetAspectRatio(root_child0, 0.5); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -372,7 +397,7 @@ TEST(YogaTest, aspect_ratio_half_main) { const YGNodeRef root_child0 = YGNodeNew(); YGNodeStyleSetWidth(root_child0, YGPx(100)); - YGNodeStyleSetAspectRatio(root_child0, 0.5); + YGNodeStyleSetAspectRatio(root_child0, 2); YGNodeInsertChild(root, root_child0, 0); YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); @@ -405,3 +430,249 @@ TEST(YogaTest, aspect_ratio_with_measure_func) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, aspect_ratio_width_height_flex_grow_row) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetWidth(root, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(200)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(50)); + YGNodeStyleSetHeight(root_child0, YGPx(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, YGPx(200)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(50)); + YGNodeStyleSetHeight(root_child0, YGPx(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, YGPx(200)); + YGNodeStyleSetHeight(root, YGPx(200)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, YGPx(50)); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetHeight(root_child1, YGPx(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, YGPx(200)); + YGNodeStyleSetHeight(root, YGPx(200)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(50)); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetAspectRatio(root_child0, 1); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, YGPx(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, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(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, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, YGPx(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, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, YGPx(10)); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, YGPx(10)); + YGNodeStyleSetPosition(root_child0, YGEdgeRight, YGPx(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, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute); + YGNodeStyleSetPosition(root_child0, YGEdgeLeft, YGPx(10)); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, YGPx(10)); + YGNodeStyleSetPosition(root_child0, YGEdgeBottom, YGPx(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, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, YGPx(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, YGPx(100)); + YGNodeStyleSetHeight(root, YGPx(100)); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetHeight(root_child0, YGPx(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); +} diff --git a/tests/YGMemoryFuncTest.cpp b/tests/YGMemoryFuncTest.cpp index bef2985c..b6481373 100644 --- a/tests/YGMemoryFuncTest.cpp +++ b/tests/YGMemoryFuncTest.cpp @@ -56,7 +56,7 @@ TEST(YogaTest, memory_func_test_funcs) { } YGNodeFreeRecursive(root); ASSERT_NE(testMallocCount, 0); - ASSERT_NE(testCallocCount, 0); + ASSERT_EQ(testCallocCount, 0); ASSERT_NE(testReallocCount, 0); ASSERT_NE(testFreeCount, 0); YGSetMemoryFuncs(NULL, NULL, NULL, NULL); diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 761f00e5..7f3af522 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -13,34 +13,35 @@ YG_EXTERN_C_BEGIN +#define YGFlexDirectionCount 4 typedef enum YGFlexDirection { YGFlexDirectionColumn, YGFlexDirectionColumnReverse, YGFlexDirectionRow, YGFlexDirectionRowReverse, - YGFlexDirectionCount, } YGFlexDirection; +#define YGUnitCount 2 typedef enum YGUnit { YGUnitPixel, YGUnitPercent, - YGUnitCount, } YGUnit; +#define YGMeasureModeCount 3 typedef enum YGMeasureMode { YGMeasureModeUndefined, YGMeasureModeExactly, YGMeasureModeAtMost, - YGMeasureModeCount, } YGMeasureMode; +#define YGPrintOptionsCount 3 typedef enum YGPrintOptions { YGPrintOptionsLayout = 1, YGPrintOptionsStyle = 2, YGPrintOptionsChildren = 4, - YGPrintOptionsCount, } YGPrintOptions; +#define YGEdgeCount 9 typedef enum YGEdge { YGEdgeLeft, YGEdgeTop, @@ -51,72 +52,71 @@ typedef enum YGEdge { YGEdgeHorizontal, YGEdgeVertical, YGEdgeAll, - YGEdgeCount, } YGEdge; +#define YGPositionTypeCount 2 typedef enum YGPositionType { YGPositionTypeRelative, YGPositionTypeAbsolute, - YGPositionTypeCount, } YGPositionType; +#define YGDimensionCount 2 typedef enum YGDimension { YGDimensionWidth, YGDimensionHeight, - YGDimensionCount, } YGDimension; +#define YGJustifyCount 5 typedef enum YGJustify { YGJustifyFlexStart, YGJustifyCenter, YGJustifyFlexEnd, YGJustifySpaceBetween, YGJustifySpaceAround, - YGJustifyCount, } YGJustify; +#define YGDirectionCount 3 typedef enum YGDirection { YGDirectionInherit, YGDirectionLTR, YGDirectionRTL, - YGDirectionCount, } YGDirection; +#define YGLogLevelCount 5 typedef enum YGLogLevel { YGLogLevelError, YGLogLevelWarn, YGLogLevelInfo, YGLogLevelDebug, YGLogLevelVerbose, - YGLogLevelCount, } YGLogLevel; +#define YGWrapCount 2 typedef enum YGWrap { YGWrapNoWrap, YGWrapWrap, - YGWrapCount, } YGWrap; +#define YGOverflowCount 3 typedef enum YGOverflow { YGOverflowVisible, YGOverflowHidden, YGOverflowScroll, - YGOverflowCount, } YGOverflow; +#define YGExperimentalFeatureCount 2 typedef enum YGExperimentalFeature { YGExperimentalFeatureRounding, YGExperimentalFeatureWebFlexBasis, - YGExperimentalFeatureCount, } YGExperimentalFeature; +#define YGAlignCount 5 typedef enum YGAlign { YGAlignAuto, YGAlignFlexStart, YGAlignCenter, YGAlignFlexEnd, YGAlignStretch, - YGAlignCount, } YGAlign; YG_EXTERN_C_END diff --git a/yoga/Yoga.c b/yoga/Yoga.c index 87090ac9..64cf4ebb 100644 --- a/yoga/Yoga.c +++ b/yoga/Yoga.c @@ -42,7 +42,7 @@ typedef struct YGCachedMeasurement { // 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. -enum { YG_MAX_CACHED_RESULT_COUNT = 16 }; +#define YG_MAX_CACHED_RESULT_COUNT 16 typedef struct YGLayout { float position[4]; @@ -106,6 +106,66 @@ typedef struct YGNode { void *context; } 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); YGMalloc gYGMalloc = &malloc; @@ -145,8 +205,6 @@ static int YGAndroidLog(YGLogLevel level, const char *format, va_list args) { case YGLogLevelVerbose: androidLevel = ANDROID_LOG_VERBOSE; break; - case YGLogLevelCount: - break; } const int result = __android_log_vprint(androidLevel, "YG-layout", format, args); return result; @@ -205,61 +263,6 @@ static inline float YGValueResolve(const YGValue * const unit, const float paren } } -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 = YGValueUndefined; - - node->style.alignItems = YGAlignStretch; - node->style.justifyContent = YGJustifyFlexStart; - 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] = YGValueUndefined; - node->style.dimensions[YGDimensionHeight] = YGValueUndefined; - - node->style.minDimensions[YGDimensionWidth] = YGValueUndefined; - node->style.minDimensions[YGDimensionHeight] = YGValueUndefined; - - node->style.maxDimensions[YGDimensionWidth] = YGValueUndefined; - node->style.maxDimensions[YGDimensionHeight] = YGValueUndefined; - - for (YGEdge edge = YGEdgeLeft; edge < YGEdgeCount; edge++) { - node->style.position[edge] = YGValueUndefined; - node->style.margin[edge] = YGValueUndefined; - node->style.padding[edge] = YGValueUndefined; - node->style.border[edge] = YGValueUndefined; - } - - 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; YGValue YGPx(const float value){ @@ -281,11 +284,11 @@ YGValue YGPercent(const float value){ } 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"); gNodeInstanceCount++; - YGNodeInit(node); + memcpy(node, &gYGNodeDefaults, sizeof(YGNode)); return node; } @@ -320,8 +323,7 @@ void YGNodeReset(const YGNodeRef node) { YG_ASSERT(node->parent == NULL, "Cannot reset a node still attached to a parent"); YGNodeListFree(node->children); - memset(node, 0, sizeof(YGNode)); - YGNodeInit(node); + memcpy(node, &gYGNodeDefaults, sizeof(YGNode)); } int32_t YGNodeGetInstanceCount(void) { @@ -900,7 +902,7 @@ static YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection, static inline bool YGNodeIsFlex(const YGNodeRef node) { return (node->style.positionType == YGPositionTypeRelative && - (node->style.flexGrow != 0.0f || node->style.flexShrink != 0.0f || node->style.flex != 0.0f)); + (YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0)); } static inline float YGNodeDimWithMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -1023,8 +1025,6 @@ static void YGConstrainMaxSizeForMode(const float maxSize, YGMeasureMode *mode, *size = maxSize; } break; - case YGMeasureModeCount: - break; } } @@ -1138,7 +1138,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, if (!YGFloatIsUndefined(child->style.aspectRatio)) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { child->layout.computedFlexBasis = - fmaxf(childWidth * child->style.aspectRatio, + fmaxf(childWidth / child->style.aspectRatio, YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentWidth)); return; } else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { @@ -1236,7 +1236,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, childWidth = fmaxf(childHeight * child->style.aspectRatio, YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, width)); } else if (YGFloatIsUndefined(childHeight)) { - childHeight = fmaxf(childWidth * child->style.aspectRatio, + childHeight = fmaxf(childWidth / child->style.aspectRatio, YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, width)); } } @@ -1591,8 +1591,9 @@ static void YGNodelayoutImpl(const YGNodeRef node, const YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; const YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; - const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, parentWidth); - const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, parentWidth); + const float paddingAndBorderAxisRow = isMainAxisRow ? paddingAndBorderAxisMain : paddingAndBorderAxisCross; + const float paddingAndBorderAxisColumn = isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain; + const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, parentWidth); const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, parentWidth); @@ -1603,11 +1604,11 @@ static void YGNodelayoutImpl(const YGNodeRef node, const float maxInnerHeight = YGValueResolve(&node->style.maxDimensions[YGDimensionHeight], parentHeight) - 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 const float availableInnerWidth = fmaxf(fminf(availableWidth - marginAxisRow - paddingAndBorderAxisRow, maxInnerWidth), minInnerWidth); const float availableInnerHeight = fmaxf(fminf(availableHeight - marginAxisColumn - paddingAndBorderAxisColumn, maxInnerHeight), minInnerHeight); - + float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; @@ -1764,7 +1765,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // Calculate the remaining available space that needs to be allocated. // If the main dimension size isn't known, it is computed based on // the line length, so there's no more space left to distribute. - + // We resolve main dimension to fit minimum and maximum values if (YGFloatIsUndefined(availableInnerMainDim)) { if (!YGFloatIsUndefined(minInnerMainDim) && @@ -1775,7 +1776,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, availableInnerMainDim = maxInnerMainDim; } } - + float remainingFreeSpace = 0; if (!YGFloatIsUndefined(availableInnerMainDim)) { remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine; @@ -1963,16 +1964,22 @@ static void YGNodelayoutImpl(const YGNodeRef node, } if (!YGFloatIsUndefined(currentRelativeChild->style.aspectRatio)) { - if (isMainAxisRow && childHeightMeasureMode != YGMeasureModeExactly) { + if (isMainAxisRow) { childHeight = - fmaxf(childWidth * currentRelativeChild->style.aspectRatio, + fmaxf(childWidth / currentRelativeChild->style.aspectRatio, YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionColumn, availableInnerWidth)); childHeightMeasureMode = YGMeasureModeExactly; - } else if (!isMainAxisRow && childWidthMeasureMode != YGMeasureModeExactly) { + + childHeight = fminf(childHeight, availableInnerHeight); + childWidth = childHeight * currentRelativeChild->style.aspectRatio; + } else { childWidth = fmaxf(childHeight * currentRelativeChild->style.aspectRatio, YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionRow, availableInnerWidth)); childWidthMeasureMode = YGMeasureModeExactly; + + childWidth = fminf(childWidth, availableInnerWidth); + childHeight = childWidth / currentRelativeChild->style.aspectRatio; } } @@ -2049,7 +2056,6 @@ static void YGNodelayoutImpl(const YGNodeRef node, leadingMainDim = betweenMainDim / 2; break; case YGJustifyFlexStart: - case YGJustifyCount: break; } @@ -2167,13 +2173,23 @@ static void YGNodelayoutImpl(const YGNodeRef node, YGMeasureMode childHeightMeasureMode = YGMeasureModeExactly; if (isMainAxisRow) { - childHeight = crossDim; childWidth = child->layout.measuredDimensions[YGDimensionWidth] + YGNodeMarginForAxis(child, YGFlexDirectionRow, availableInnerWidth); + + if (!YGFloatIsUndefined(child->style.aspectRatio)) { + childHeight = childWidth / child->style.aspectRatio; + } else { + childHeight = crossDim; + } } else { - childWidth = crossDim; childHeight = child->layout.measuredDimensions[YGDimensionHeight] + YGNodeMarginForAxis(child, YGFlexDirectionColumn, availableInnerWidth); + + if (!YGFloatIsUndefined(child->style.aspectRatio)) { + childWidth = childHeight * child->style.aspectRatio; + } else { + childWidth = crossDim; + } } YGConstrainMaxSizeForMode(YGValueResolve(&child->style.maxDimensions[YGDimensionWidth], availableInnerWidth), @@ -2244,7 +2260,6 @@ static void YGNodelayoutImpl(const YGNodeRef node, break; case YGAlignAuto: case YGAlignFlexStart: - case YGAlignCount: break; } @@ -2304,7 +2319,6 @@ static void YGNodelayoutImpl(const YGNodeRef node, break; } case YGAlignAuto: - case YGAlignCount: break; } } diff --git a/yoga/Yoga.h b/yoga/Yoga.h index ebf2d02e..7172f9ea 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -170,6 +170,9 @@ YG_NODE_STYLE_PROPERTY_UNIT(YGValue, MaxHeight, maxHeight); // Yoga specific properties, not compatible with flexbox specification // Aspect ratio control the size of the undefined dimension of a node. +// Aspect ratio is encoded as a floating point value width/height. e.g. A value of 2 leads to a node +// with a width twice the size of its height while a value of 0.5 gives the opposite effect. +// // - On a node with a set width/height aspect ratio control the size of the unset dimension // - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if // unset