Compare commits

..

1 Commits

Author SHA1 Message Date
yxping
8bea26d0a0 Fix test failure about zero_size_with_child
A test about parent has zero width and height can not pass.
2018-03-30 15:12:50 +08:00
35 changed files with 1115 additions and 1269 deletions

14
BUCK
View File

@@ -32,6 +32,20 @@ cxx_library(
], ],
) )
cxx_library(
name = "yogafastmath",
srcs = glob(["yoga/*.cpp"]),
header_namespace = "",
exported_headers = subdir_glob([("", "yoga/*.h")]),
compiler_flags = COMPILER_FLAGS + ["-ffast-math"],
soname = "libyogafastmathcore.$(ext)",
tests = [":YogaTests"],
visibility = ["PUBLIC"],
deps = [
yoga_dep("lib/fb:ndklog"),
],
)
cxx_test( cxx_test(
name = "YogaTests", name = "YogaTests",
srcs = glob(["tests/*.cpp"]), srcs = glob(["tests/*.cpp"]),

View File

@@ -46,14 +46,14 @@ import java.util.Map;
* <YogaLayout * <YogaLayout
* xmlns:android="http://schemas.android.com/apk/res/android" * xmlns:android="http://schemas.android.com/apk/res/android"
* xmlns:yoga="http://schemas.android.com/apk/com.facebook.yoga.android" * xmlns:yoga="http://schemas.android.com/apk/com.facebook.yoga.android"
* android:layout_width="match_owner" * android:layout_width="match_parent"
* android:layout_height="match_owner" * android:layout_height="match_parent"
* yoga:flex_direction="row" * yoga:flex_direction="row"
* yoga:padding_all="10dp" * yoga:padding_all="10dp"
* > * >
* <TextView * <TextView
* android:layout_width="match_owner" * android:layout_width="match_parent"
* android:layout_height="match_owner" * android:layout_height="match_parent"
* android:text="Hello, World!" * android:text="Hello, World!"
* yoga:flex="1" * yoga:flex="1"
* /> * />
@@ -262,11 +262,11 @@ public class YogaLayout extends ViewGroup {
return; return;
} }
final YogaNode owner = node.getOwner(); final YogaNode parent = node.getParent();
for (int i = 0; i < owner.getChildCount(); i++) { for (int i = 0; i < parent.getChildCount(); i++) {
if (owner.getChildAt(i).equals(node)) { if (parent.getChildAt(i).equals(node)) {
owner.removeChildAt(i); parent.removeChildAt(i);
break; break;
} }
} }
@@ -315,7 +315,7 @@ public class YogaLayout extends ViewGroup {
@Override @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) { protected void onLayout(boolean changed, int l, int t, int r, int b) {
// Either we are a root of a tree, or this function is called by our owner's onLayout, in which // Either we are a root of a tree, or this function is called by our parent's onLayout, in which
// case our r-l and b-t are the size of our node. // case our r-l and b-t are the size of our node.
if (!(getParent() instanceof YogaLayout)) { if (!(getParent() instanceof YogaLayout)) {
createLayout( createLayout(
@@ -699,7 +699,7 @@ public class YogaLayout extends ViewGroup {
/** /**
* Constructs a set of layout params, given width and height specs. In this case, we can set * Constructs a set of layout params, given width and height specs. In this case, we can set
* the {@code yoga:width} and {@code yoga:height} if we are given them explicitly. If other * the {@code yoga:width} and {@code yoga:height} if we are given them explicitly. If other
* options (such as {@code match_owner} or {@code wrap_content} are given, then the owner * options (such as {@code match_parent} or {@code wrap_content} are given, then the parent
* LayoutParams will store them, and we deal with them during layout. (see * LayoutParams will store them, and we deal with them during layout. (see
* {@link YogaLayout#createLayout}) * {@link YogaLayout#createLayout})
* *
@@ -773,9 +773,9 @@ public class YogaLayout extends ViewGroup {
* {@code View}'s measure function. * {@code View}'s measure function.
* *
* @param node The yoga node to measure * @param node The yoga node to measure
* @param width The suggested width from the owner * @param width The suggested width from the parent
* @param widthMode The type of suggestion for the width * @param widthMode The type of suggestion for the width
* @param height The suggested height from the owner * @param height The suggested height from the parent
* @param heightMode The type of suggestion for the height * @param heightMode The type of suggestion for the height
* @return A measurement output ({@code YogaMeasureOutput}) for the node * @return A measurement output ({@code YogaMeasureOutput}) for the node
*/ */

View File

@@ -227,31 +227,19 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\yoga\Utils.h" />
<ClInclude Include="..\..\yoga\YGConfig.h" />
<ClInclude Include="..\..\yoga\YGEnums.h" />
<ClInclude Include="..\..\yoga\YGFloatOptional.h" />
<ClInclude Include="..\..\yoga\YGLayout.h" />
<ClInclude Include="..\..\yoga\YGMacros.h" />
<ClInclude Include="..\..\yoga\YGNode.h" />
<ClInclude Include="..\..\yoga\YGNodePrint.h" />
<ClInclude Include="..\..\yoga\YGStyle.h" />
<ClInclude Include="..\..\yoga\Yoga-internal.h" />
<ClInclude Include="..\..\yoga\Yoga.h" /> <ClInclude Include="..\..\yoga\Yoga.h" />
<ClInclude Include="..\..\yoga\YGEnums.h" />
<ClInclude Include="..\..\yoga\YGMacros.h" />
<ClInclude Include="..\..\yoga\YGNodeList.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="YGInterop.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\yoga\Utils.cpp" /> <ClCompile Include="..\..\yoga\Yoga.c" />
<ClCompile Include="..\..\yoga\YGConfig.cpp" /> <ClCompile Include="..\..\yoga\YGEnums.c" />
<ClCompile Include="..\..\yoga\YGEnums.cpp" /> <ClCompile Include="..\..\yoga\YGNodeList.c" />
<ClCompile Include="..\..\yoga\YGFloatOptional.cpp" />
<ClCompile Include="..\..\yoga\YGLayout.cpp" />
<ClCompile Include="..\..\yoga\YGNode.cpp" />
<ClCompile Include="..\..\yoga\YGNodePrint.cpp" />
<ClCompile Include="..\..\yoga\YGStyle.cpp" />
<ClCompile Include="..\..\yoga\Yoga.cpp" />
<ClCompile Include="YGInterop.cpp" /> <ClCompile Include="YGInterop.cpp" />
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged> <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>

View File

@@ -21,40 +21,19 @@
<ClInclude Include="targetver.h"> <ClInclude Include="targetver.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="resource.h"> <ClInclude Include="..\..\yoga\Yoga.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGEnums.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGFloatOptional.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGLayout.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\yoga\YGMacros.h"> <ClInclude Include="..\..\yoga\YGMacros.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\yoga\YGNode.h"> <ClInclude Include="..\..\yoga\YGNodeList.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\yoga\YGNodePrint.h"> <ClInclude Include="YGInterop.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\yoga\YGStyle.h"> <ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\Yoga.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\Yoga-internal.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\yoga\YGConfig.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@@ -65,36 +44,15 @@
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\yoga\Yoga.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGNodeList.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="YGInterop.cpp"> <ClCompile Include="YGInterop.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\yoga\Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGEnums.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGFloatOptional.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGLayout.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGNode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGNodePrint.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGStyle.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\Yoga.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\yoga\YGConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="Yoga.rc"> <ResourceCompile Include="Yoga.rc">

View File

@@ -104,5 +104,58 @@ namespace Facebook.Yoga
Assert.AreEqual(100f, root_child0_child0.LayoutHeight); Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
} }
[Test]
public void Test_zero_size_with_child()
{
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
YogaNode root_child0 = new YogaNode(config);
root_child0.Width = 0;
root_child0.Height = 0;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode(config);
root_child0_child0.Width = 100;
root_child0_child0.Height = 100;
root_child0.Insert(0, root_child0_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(0f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(0f, root_child0.LayoutWidth);
Assert.AreEqual(0f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(0f, root.LayoutWidth);
Assert.AreEqual(0f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(0f, root_child0.LayoutWidth);
Assert.AreEqual(0f, root_child0.LayoutHeight);
Assert.AreEqual(-100f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(100f, root_child0_child0.LayoutWidth);
Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
}
} }
} }

View File

@@ -7,3 +7,9 @@
<div style="width: 100px; height: 100px;"></div> <div style="width: 100px; height: 100px;"></div>
</div> </div>
</div> </div>
<div id="zero_size_with_child">
<div style="width: 0px; height: 0px;">
<div style="width: 100px; height: 100px;"></div>
</div>
</div>

View File

@@ -411,6 +411,8 @@ function getDefaultStyleValue(style) {
case 'bottom': case 'bottom':
case 'start': case 'start':
case 'end': case 'end':
case 'width':
case 'height':
return 'undefined'; return 'undefined';
} }
var node = document.getElementById('default'); var node = document.getElementById('default');

View File

@@ -2,7 +2,7 @@
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
VERSION_NAME=1.8.0 VERSION_NAME=1.7.1-SNAPSHOT
POM_URL=https://github.com/facebook/yoga POM_URL=https://github.com/facebook/yoga
POM_SCM_URL=https://github.com/facebook/yoga.git POM_SCM_URL=https://github.com/facebook/yoga.git
POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git

View File

@@ -28,6 +28,29 @@ cxx_library(
], ],
) )
cxx_library(
name = "jniFastMath",
srcs = glob(["jni/*.cpp"]),
header_namespace = "",
compiler_flags = [
"-fno-omit-frame-pointer",
"-fexceptions",
"-fPIC",
"-Wall",
"-Werror",
"-O3",
"-std=c++11",
],
platforms = ANDROID,
soname = "libyogafastmath.$(ext)",
visibility = ["PUBLIC"],
deps = [
FBJNI_TARGET,
JNI_TARGET,
yoga_dep(":yogafastmath"),
],
)
java_library( java_library(
name = "java", name = "java",
srcs = glob(["com/facebook/yoga/*.java"]), srcs = glob(["com/facebook/yoga/*.java"]),
@@ -40,6 +63,7 @@ java_library(
visibility = ["PUBLIC"], visibility = ["PUBLIC"],
deps = [ deps = [
":jni", ":jni",
":jniFastMath",
INFER_ANNOTATIONS_TARGET, INFER_ANNOTATIONS_TARGET,
JSR_305_TARGET, JSR_305_TARGET,
PROGRUARD_ANNOTATIONS_TARGET, PROGRUARD_ANNOTATIONS_TARGET,

View File

@@ -16,12 +16,16 @@ public class YogaConfig {
public static int SPACING_TYPE = 1; public static int SPACING_TYPE = 1;
static { static {
if (YogaConstants.shouldUseFastMath) {
SoLoader.loadLibrary("yogafastmath");
} else {
SoLoader.loadLibrary("yoga"); SoLoader.loadLibrary("yoga");
} }
}
long mNativePointer; long mNativePointer;
private YogaLogger mLogger; private YogaLogger mLogger;
private YogaNodeCloneFunction mYogaNodeCloneFunction; private YogaNodeClonedFunction mNodeClonedFunction;
private native long jni_YGConfigNew(); private native long jni_YGConfigNew();
public YogaConfig() { public YogaConfig() {
@@ -93,15 +97,16 @@ public class YogaConfig {
return mLogger; return mLogger;
} }
private native void jni_YGConfigSetHasCloneNodeFunc(long nativePointer, boolean hasClonedFunc); private native void jni_YGConfigSetHasNodeClonedFunc(long nativePointer, boolean hasClonedFunc);
public void setOnCloneNode(YogaNodeCloneFunction cloneYogaNodeFunction) { public void setOnNodeCloned(YogaNodeClonedFunction nodeClonedFunction) {
mYogaNodeCloneFunction = cloneYogaNodeFunction; mNodeClonedFunction = nodeClonedFunction;
jni_YGConfigSetHasCloneNodeFunc(mNativePointer, cloneYogaNodeFunction != null); jni_YGConfigSetHasNodeClonedFunc(mNativePointer, nodeClonedFunction != null);
} }
@DoNotStrip @DoNotStrip
private final YogaNode cloneNode(YogaNode oldNode, YogaNode parent, int childIndex) { public final void onNodeCloned(
return mYogaNodeCloneFunction.cloneNode(oldNode, parent, childIndex); YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
mNodeClonedFunction.onNodeCloned(oldNode, newNode, parent, childIndex);
} }
} }

View File

@@ -18,6 +18,8 @@ public class YogaConstants {
*/ */
public static final float UNDEFINED = (float) (10E20); public static final float UNDEFINED = (float) (10E20);
public static boolean shouldUseFastMath = false;
public static boolean isUndefined(float value) { public static boolean isUndefined(float value) {
// Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN, // Value of a float in the case of it being not defined is 10.1E20. Earlier it used to be NAN,
// the benefit of which // the benefit of which

View File

@@ -17,16 +17,20 @@ import javax.annotation.Nullable;
public class YogaNode implements Cloneable { public class YogaNode implements Cloneable {
static { static {
if (YogaConstants.shouldUseFastMath) {
SoLoader.loadLibrary("yogafastmath");
} else {
SoLoader.loadLibrary("yoga"); SoLoader.loadLibrary("yoga");
} }
}
/** /**
* Get native instance count. Useful for testing only. * Get native instance count. Useful for testing only.
*/ */
static native int jni_YGNodeGetInstanceCount(); static native int jni_YGNodeGetInstanceCount();
private YogaNode mOwner; private YogaNode mParent;
@Nullable private List<YogaNode> mChildren; private List<YogaNode> mChildren;
private YogaMeasureFunction mMeasureFunction; private YogaMeasureFunction mMeasureFunction;
private YogaBaselineFunction mBaselineFunction; private YogaBaselineFunction mBaselineFunction;
private long mNativePointer; private long mNativePointer;
@@ -143,15 +147,12 @@ public class YogaNode implements Cloneable {
} }
public YogaNode getChildAt(int i) { public YogaNode getChildAt(int i) {
if (mChildren == null) {
throw new IllegalStateException("YogaNode does not have children");
}
return mChildren.get(i); return mChildren.get(i);
} }
private native void jni_YGNodeInsertChild(long nativePointer, long childPointer, int index); private native void jni_YGNodeInsertChild(long nativePointer, long childPointer, int index);
public void addChildAt(YogaNode child, int i) { public void addChildAt(YogaNode child, int i) {
if (child.mOwner != null) { if (child.mParent != null) {
throw new IllegalStateException("Child already has a parent, it must be removed first."); throw new IllegalStateException("Child already has a parent, it must be removed first.");
} }
@@ -159,84 +160,35 @@ public class YogaNode implements Cloneable {
mChildren = new ArrayList<>(4); mChildren = new ArrayList<>(4);
} }
mChildren.add(i, child); mChildren.add(i, child);
child.mOwner = this; child.mParent = this;
jni_YGNodeInsertChild(mNativePointer, child.mNativePointer, i); jni_YGNodeInsertChild(mNativePointer, child.mNativePointer, i);
} }
private native void jni_YGNodeInsertSharedChild(long nativePointer, long childPointer, int index);
public void addSharedChildAt(YogaNode child, int i) {
if (mChildren == null) {
mChildren = new ArrayList<>(4);
}
mChildren.add(i, child);
child.mOwner = null;
jni_YGNodeInsertSharedChild(mNativePointer, child.mNativePointer, i);
}
private native long jni_YGNodeClone(long nativePointer, Object newNode); private native long jni_YGNodeClone(long nativePointer, Object newNode);
@Override @Override
public YogaNode clone() { public YogaNode clone() throws CloneNotSupportedException {
try {
YogaNode clonedYogaNode = (YogaNode) super.clone(); YogaNode clonedYogaNode = (YogaNode) super.clone();
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode); long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
clonedYogaNode.mNativePointer = clonedNativePointer; clonedYogaNode.mNativePointer = clonedNativePointer;
clonedYogaNode.mOwner = null;
clonedYogaNode.mChildren = clonedYogaNode.mChildren =
mChildren != null ? (List<YogaNode>) ((ArrayList) mChildren).clone() : null; mChildren != null ? (List<YogaNode>) ((ArrayList) mChildren).clone() : null;
return clonedYogaNode; return clonedYogaNode;
} catch (CloneNotSupportedException ex) {
// This class implements Cloneable, this should not happen
throw new RuntimeException(ex);
}
}
public YogaNode cloneWithNewChildren() {
try {
YogaNode clonedYogaNode = (YogaNode) super.clone();
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
clonedYogaNode.mOwner = null;
clonedYogaNode.mNativePointer = clonedNativePointer;
clonedYogaNode.clearChildren();
return clonedYogaNode;
} catch (CloneNotSupportedException ex) {
// This class implements Cloneable, this should not happen
throw new RuntimeException(ex);
}
}
private native void jni_YGNodeClearChildren(long nativePointer);
private void clearChildren() {
mChildren = null;
jni_YGNodeClearChildren(mNativePointer);
} }
private native void jni_YGNodeRemoveChild(long nativePointer, long childPointer); private native void jni_YGNodeRemoveChild(long nativePointer, long childPointer);
public YogaNode removeChildAt(int i) { public YogaNode removeChildAt(int i) {
if (mChildren == null) {
throw new IllegalStateException(
"Trying to remove a child of a YogaNode that does not have children");
}
final YogaNode child = mChildren.remove(i); final YogaNode child = mChildren.remove(i);
child.mOwner = null; child.mParent = null;
jni_YGNodeRemoveChild(mNativePointer, child.mNativePointer); jni_YGNodeRemoveChild(mNativePointer, child.mNativePointer);
return child; return child;
} }
/**
* @returns the {@link YogaNode} that owns this {@link YogaNode}.
* The owner is used to identify the YogaTree that a {@link YogaNode} belongs
* to.
* This method will return the parent of the {@link YogaNode} when the
* {@link YogaNode} only belongs to one YogaTree or null when the
* {@link YogaNode} is shared between two or more YogaTrees.
*/
@Nullable @Nullable
public public
YogaNode getOwner() { YogaNode getParent() {
return mOwner; return mParent;
} }
public int indexOf(YogaNode child) { public int indexOf(YogaNode child) {
@@ -745,22 +697,4 @@ public class YogaNode implements Cloneable {
public void print() { public void print() {
jni_YGNodePrint(mNativePointer); jni_YGNodePrint(mNativePointer);
} }
/**
* This method replaces the child at childIndex position with the newNode received by parameter.
* This is different than calling removeChildAt and addChildAt because this method ONLY replaces
* the child in the mChildren datastructure. @DoNotStrip: called from JNI
*
* @return the nativePointer of the newNode {@linl YogaNode}
*/
@DoNotStrip
private final long replaceChild(YogaNode newNode, int childIndex) {
if (mChildren == null) {
throw new IllegalStateException("Cannot replace child. YogaNode does not have children");
}
mChildren.remove(childIndex);
mChildren.add(childIndex, newNode);
newNode.mOwner = this;
return newNode.mNativePointer;
}
} }

View File

@@ -10,8 +10,8 @@ package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip; import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip @DoNotStrip
public interface YogaNodeCloneFunction { public interface YogaNodeClonedFunction {
@DoNotStrip @DoNotStrip
YogaNode cloneNode(YogaNode oldNode, YogaNode parent, int childIndex); void onNodeCloned(YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex);
} }

View File

@@ -142,49 +142,31 @@ static float YGJNIBaselineFunc(YGNodeRef node, float width, float height) {
} }
} }
static inline YGNodeRef _jlong2YGNodeRef(jlong addr) { static void YGJNIOnNodeClonedFunc(
return reinterpret_cast<YGNodeRef>(static_cast<intptr_t>(addr));
}
static inline YGConfigRef _jlong2YGConfigRef(jlong addr) {
return reinterpret_cast<YGConfigRef>(static_cast<intptr_t>(addr));
}
static YGNodeRef YGJNIOnNodeClonedFunc(
YGNodeRef oldNode, YGNodeRef oldNode,
YGNodeRef owner, YGNodeRef newNode,
YGNodeRef parent,
int childIndex) { int childIndex) {
auto config = oldNode->getConfig(); auto config = oldNode->getConfig();
if (!config) { if (!config) {
return nullptr; return;
} }
static auto onNodeClonedFunc = findClassStatic("com/facebook/yoga/YogaConfig") static auto onNodeClonedFunc = findClassStatic("com/facebook/yoga/YogaConfig")
->getMethod<alias_ref<JYogaNode>( ->getMethod<void(
local_ref<JYogaNode>, local_ref<JYogaNode>,
local_ref<JYogaNode>, local_ref<JYogaNode>,
jint)>("cloneNode"); local_ref<JYogaNode>,
jint)>("onNodeCloned");
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config)); auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
auto javaConfig = context->config; auto javaConfig = context->config;
auto newNode = onNodeClonedFunc( onNodeClonedFunc(
javaConfig->get(), javaConfig->get(),
YGNodeJobject(oldNode)->lockLocal(), YGNodeJobject(oldNode)->lockLocal(),
YGNodeJobject(owner)->lockLocal(), YGNodeJobject(newNode)->lockLocal(),
YGNodeJobject(parent)->lockLocal(),
childIndex); childIndex);
static auto replaceChild = findClassStatic("com/facebook/yoga/YogaNode")
->getMethod<jlong(
local_ref<JYogaNode>,
jint)>("replaceChild");
jlong newNodeNativePointer = replaceChild(
YGNodeJobject(owner)->lockLocal(),
newNode,
childIndex);
return _jlong2YGNodeRef(newNodeNativePointer);
} }
static YGSize YGJNIMeasureFunc( static YGSize YGJNIMeasureFunc(
@@ -252,6 +234,14 @@ static int YGJNILogFunc(const YGConfigRef config,
return result; return result;
} }
static inline YGNodeRef _jlong2YGNodeRef(jlong addr) {
return reinterpret_cast<YGNodeRef>(static_cast<intptr_t>(addr));
}
static inline YGConfigRef _jlong2YGConfigRef(jlong addr) {
return reinterpret_cast<YGConfigRef>(static_cast<intptr_t>(addr));
}
jlong jni_YGNodeNew(alias_ref<jobject> thiz) { jlong jni_YGNodeNew(alias_ref<jobject> thiz) {
const YGNodeRef node = YGNodeNew(); const YGNodeRef node = YGNodeNew();
node->setContext(new weak_ref<jobject>(make_weak(thiz))); node->setContext(new weak_ref<jobject>(make_weak(thiz)));
@@ -284,11 +274,6 @@ void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
YGNodeFree(node); YGNodeFree(node);
} }
void jni_YGNodeClearChildren(alias_ref<jobject> thiz, jlong nativePointer) {
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
node->clearChildren();
}
void jni_YGNodeReset(alias_ref<jobject> thiz, jlong nativePointer) { void jni_YGNodeReset(alias_ref<jobject> thiz, jlong nativePointer) {
const YGNodeRef node = _jlong2YGNodeRef(nativePointer); const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
void* context = node->getContext(); void* context = node->getContext();
@@ -308,15 +293,6 @@ void jni_YGNodeInsertChild(alias_ref<jobject>, jlong nativePointer, jlong childP
YGNodeInsertChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index); YGNodeInsertChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index);
} }
void jni_YGNodeInsertSharedChild(
alias_ref<jobject>,
jlong nativePointer,
jlong childPointer,
jint index) {
YGNodeInsertSharedChild(
_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer), index);
}
void jni_YGNodeRemoveChild(alias_ref<jobject>, jlong nativePointer, jlong childPointer) { void jni_YGNodeRemoveChild(alias_ref<jobject>, jlong nativePointer, jlong childPointer) {
YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer)); YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
} }
@@ -530,10 +506,10 @@ void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref<jobject>,
YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour); YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour);
} }
void jni_YGConfigSetHasCloneNodeFunc( void jni_YGConfigSetHasNodeClonedFunc(
alias_ref<jobject> thiz, alias_ref<jobject> thiz,
jlong nativePointer, jlong nativePointer,
jboolean hasCloneNodeFunc) { jboolean hasNodeClonedFunc) {
const YGConfigRef config = _jlong2YGConfigRef(nativePointer); const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config)); auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
if (context && context->config) { if (context && context->config) {
@@ -541,15 +517,15 @@ void jni_YGConfigSetHasCloneNodeFunc(
context->config = nullptr; context->config = nullptr;
} }
if (hasCloneNodeFunc) { if (hasNodeClonedFunc) {
if (!context) { if (!context) {
context = new YGConfigContext(); context = new YGConfigContext();
YGConfigSetContext(config, context); YGConfigSetContext(config, context);
} }
context->config = new global_ref<jobject>(make_global(thiz)); context->config = new global_ref<jobject>(make_global(thiz));
YGConfigSetCloneNodeFunc(config, YGJNIOnNodeClonedFunc); YGConfigSetNodeClonedFunc(config, YGJNIOnNodeClonedFunc);
} else { } else {
YGConfigSetCloneNodeFunc(config, nullptr); YGConfigSetNodeClonedFunc(config, nullptr);
} }
} }
@@ -591,9 +567,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGNodeNewWithConfig), YGMakeNativeMethod(jni_YGNodeNewWithConfig),
YGMakeNativeMethod(jni_YGNodeFree), YGMakeNativeMethod(jni_YGNodeFree),
YGMakeNativeMethod(jni_YGNodeReset), YGMakeNativeMethod(jni_YGNodeReset),
YGMakeNativeMethod(jni_YGNodeClearChildren),
YGMakeNativeMethod(jni_YGNodeInsertChild), YGMakeNativeMethod(jni_YGNodeInsertChild),
YGMakeNativeMethod(jni_YGNodeInsertSharedChild),
YGMakeNativeMethod(jni_YGNodeRemoveChild), YGMakeNativeMethod(jni_YGNodeRemoveChild),
YGMakeNativeMethod(jni_YGNodeCalculateLayout), YGMakeNativeMethod(jni_YGNodeCalculateLayout),
YGMakeNativeMethod(jni_YGNodeMarkDirty), YGMakeNativeMethod(jni_YGNodeMarkDirty),
@@ -678,7 +652,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor), YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour), YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
YGMakeNativeMethod(jni_YGConfigSetLogger), YGMakeNativeMethod(jni_YGConfigSetLogger),
YGMakeNativeMethod(jni_YGConfigSetHasCloneNodeFunc), YGMakeNativeMethod(jni_YGConfigSetHasNodeClonedFunc),
YGMakeNativeMethod( YGMakeNativeMethod(
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour), jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour),
}); });

View File

@@ -101,4 +101,56 @@ public class YGDimensionTest {
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f); assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
} }
@Test
public void test_zero_size_with_child() {
YogaConfig config = new YogaConfig();
final YogaNode root = new YogaNode(config);
final YogaNode root_child0 = new YogaNode(config);
root_child0.setWidth(0f);
root_child0.setHeight(0f);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = new YogaNode(config);
root_child0_child0.setWidth(100f);
root_child0_child0.setHeight(100f);
root_child0.addChildAt(root_child0_child0, 0);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(0f, root.getLayoutWidth(), 0.0f);
assertEquals(0f, 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(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(100f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
root.setDirection(YogaDirection.RTL);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(0f, root.getLayoutWidth(), 0.0f);
assertEquals(0f, 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(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(-100f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(100f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
}
} }

View File

@@ -10,7 +10,6 @@ package com.facebook.yoga;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@@ -252,58 +251,16 @@ public class YogaNodeTest {
assertEquals(1, clonedChild.getChildCount()); assertEquals(1, clonedChild.getChildCount());
} }
@Test
public void testCloneWithNewChildren() throws Exception {
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
YogaNode child = new YogaNode(config);
YogaNode grandChild = new YogaNode(config);
root.addChildAt(child, 0);
child.addChildAt(grandChild, 0);
child.setFlexDirection(YogaFlexDirection.ROW);
YogaNode clonedChild = child.cloneWithNewChildren();
assertNotSame(clonedChild, child);
assertEquals(YogaFlexDirection.ROW, clonedChild.getFlexDirection());
assertEquals(child.getFlexDirection(), clonedChild.getFlexDirection());
assertEquals(0, clonedChild.getChildCount());
assertEquals(1, child.getChildCount());
}
@Test
public void testAddSharedChildCloneWithNewChildren() throws Exception {
YogaConfig config = new YogaConfig();
YogaNode root = new YogaNode(config);
YogaNode child = new YogaNode(config);
YogaNode grandChild = new YogaNode(config);
root.addChildAt(child, 0);
child.addChildAt(grandChild, 0);
child.setFlexDirection(YogaFlexDirection.ROW);
YogaNode clonedChild = child.cloneWithNewChildren();
assertNotSame(clonedChild, child);
assertEquals(YogaFlexDirection.ROW, clonedChild.getFlexDirection());
assertEquals(child.getFlexDirection(), clonedChild.getFlexDirection());
assertEquals(0, clonedChild.getChildCount());
assertEquals(1, child.getChildCount());
clonedChild.addSharedChildAt(grandChild, 0);
assertEquals(1, clonedChild.getChildCount());
assertNull(grandChild.getOwner());
}
@Test @Test
public void testCloneNodeListener() throws Exception { public void testCloneNodeListener() throws Exception {
final AtomicBoolean onNodeClonedExecuted = new AtomicBoolean(false); final AtomicBoolean onNodeClonedExecuted = new AtomicBoolean(false);
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.setOnCloneNode( config.setOnNodeCloned(
new YogaNodeCloneFunction() { new YogaNodeClonedFunction() {
@Override @Override
public YogaNode cloneNode(YogaNode oldNode, YogaNode owner, int childIndex) { public void onNodeCloned(
YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
onNodeClonedExecuted.set(true); onNodeClonedExecuted.set(true);
return oldNode.clone();
} }
}); });
YogaNode root = new YogaNode(config); YogaNode root = new YogaNode(config);
@@ -311,7 +268,6 @@ public class YogaNodeTest {
root.setHeight(100f); root.setHeight(100f);
YogaNode child0 = new YogaNode(config); YogaNode child0 = new YogaNode(config);
root.addChildAt(child0, 0); root.addChildAt(child0, 0);
child0.setWidth(50f);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
// Force a clone to happen. // Force a clone to happen.
@@ -320,24 +276,20 @@ public class YogaNodeTest {
root2.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); root2.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertTrue(onNodeClonedExecuted.get()); assertTrue(onNodeClonedExecuted.get());
assertEquals(1, root2.getChildCount());
YogaNode clonedNode = root2.getChildAt(0);
assertNotSame(child0, clonedNode);
assertEquals(child0.getWidth(), clonedNode.getWidth());
assertEquals(50f, clonedNode.getWidth().value, 0.01f);
} }
@Test @Test
public void testOnNodeClonedLeak() throws Exception { public void testOnNodeClonedLeak() throws Exception {
YogaConfig config = new YogaConfig(); YogaConfig config = new YogaConfig();
config.setOnCloneNode( config.setOnNodeCloned(
new YogaNodeCloneFunction() { new YogaNodeClonedFunction() {
@Override @Override
public YogaNode cloneNode(YogaNode oldNode, YogaNode owner, int childIndex) { public void onNodeCloned(
return oldNode.clone(); YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
// Do nothing
} }
}); });
config.setOnCloneNode(null); config.setOnNodeCloned(null);
WeakReference<Object> ref = new WeakReference<Object>(config); WeakReference<Object> ref = new WeakReference<Object>(config);
// noinspection UnusedAssignment // noinspection UnusedAssignment
config = null; config = null;

View File

@@ -104,3 +104,59 @@ it("wrap_grandchild", function () {
config.free(); config.free();
} }
}); });
it("zero_size_with_child", function () {
var config = Yoga.Config.create();
try {
var root = Yoga.Node.create(config);
var root_child0 = Yoga.Node.create(config);
root_child0.setWidth(0);
root_child0.setHeight(0);
root.insertChild(root_child0, 0);
var root_child0_child0 = Yoga.Node.create(config);
root_child0_child0.setWidth(100);
root_child0_child0.setHeight(100);
root_child0.insertChild(root_child0_child0, 0);
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
console.assert(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
console.assert(0 === root.getComputedHeight(), "0 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")");
console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")");
console.assert(100 === root_child0_child0.getComputedWidth(), "100 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")");
console.assert(100 === root_child0_child0.getComputedHeight(), "100 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")");
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL);
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
console.assert(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
console.assert(0 === root.getComputedHeight(), "0 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
console.assert(-100 === root_child0_child0.getComputedLeft(), "-100 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")");
console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")");
console.assert(100 === root_child0_child0.getComputedWidth(), "100 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")");
console.assert(100 === root_child0_child0.getComputedHeight(), "100 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")");
} finally {
if (typeof root !== "undefined") {
root.freeRecursive();
}
config.free();
}
});

View File

@@ -98,3 +98,56 @@ TEST(YogaTest, wrap_grandchild) {
YGConfigFree(config); YGConfigFree(config);
} }
TEST(YogaTest, zero_size_with_child) {
const YGConfigRef config = YGConfigNew();
const YGNodeRef root = YGNodeNewWithConfig(config);
const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetWidth(root_child0, 0);
YGNodeStyleSetHeight(root_child0, 0);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
YGNodeStyleSetWidth(root_child0_child0, 100);
YGNodeStyleSetHeight(root_child0_child0, 100);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(-100, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
YGNodeFreeRecursive(root);
YGConfigFree(config);
}

View File

@@ -30,9 +30,9 @@ TEST(YogaTest, set_children_adds_children_to_parent) {
const std::vector<YGNodeRef> expectedChildren = {root_child0, root_child1}; const std::vector<YGNodeRef> expectedChildren = {root_child0, root_child1};
ASSERT_EQ(children, expectedChildren); ASSERT_EQ(children, expectedChildren);
const std::vector<YGNodeRef> owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
const std::vector<YGNodeRef> expectedOwners = {root, root}; const std::vector<YGNodeRef> expectedParents = {root, root};
ASSERT_EQ(owners, expectedOwners); ASSERT_EQ(parents, expectedParents);
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
@@ -49,9 +49,9 @@ TEST(YogaTest, set_children_to_empty_removes_old_children) {
const std::vector<YGNodeRef> expectedChildren = {}; const std::vector<YGNodeRef> expectedChildren = {};
ASSERT_EQ(children, expectedChildren); ASSERT_EQ(children, expectedChildren);
const std::vector<YGNodeRef> owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
const std::vector<YGNodeRef> expectedOwners = {nullptr, nullptr}; const std::vector<YGNodeRef> expectedParents = {nullptr, nullptr};
ASSERT_EQ(owners, expectedOwners); ASSERT_EQ(parents, expectedParents);
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
@@ -72,9 +72,9 @@ TEST(YogaTest, set_children_replaces_non_common_children) {
const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child3}; const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child3};
ASSERT_EQ(children, expectedChildren); ASSERT_EQ(children, expectedChildren);
const std::vector<YGNodeRef> owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)}; const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
const std::vector<YGNodeRef> expectedOwners = {nullptr, nullptr}; const std::vector<YGNodeRef> expectedParents = {nullptr, nullptr};
ASSERT_EQ(owners, expectedOwners); ASSERT_EQ(parents, expectedParents);
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
YGNodeFree(root_child0); YGNodeFree(root_child0);
@@ -97,14 +97,14 @@ TEST(YogaTest, set_children_keeps_and_reorders_common_children) {
const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child1, root_child3}; const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child1, root_child3};
ASSERT_EQ(children, expectedChildren); ASSERT_EQ(children, expectedChildren);
const std::vector<YGNodeRef> owners = { const std::vector<YGNodeRef> parents = {
YGNodeGetOwner(root_child0), YGNodeGetParent(root_child0),
YGNodeGetOwner(root_child1), YGNodeGetParent(root_child1),
YGNodeGetOwner(root_child2), YGNodeGetParent(root_child2),
YGNodeGetOwner(root_child3) YGNodeGetParent(root_child3)
}; };
const std::vector<YGNodeRef> expectedOwners = {nullptr, root, root, root}; const std::vector<YGNodeRef> expectedParents = {nullptr, root, root, root};
ASSERT_EQ(owners, expectedOwners); ASSERT_EQ(parents, expectedParents);
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
YGNodeFree(root_child0); YGNodeFree(root_child0);

View File

@@ -58,11 +58,8 @@ float YGUnwrapFloatOptional(const YGFloatOptional& op) {
return op.isUndefined() ? YGUndefined : op.getValue(); return op.isUndefined() ? YGUndefined : op.getValue();
} }
YGFloatOptional YGFloatOptionalMax( bool YGFloatOptionalFloatEquals(
const YGFloatOptional& op1, const YGFloatOptional& optional,
const YGFloatOptional& op2) { const float& val) {
if (!op1.isUndefined() && !op2.isUndefined()) { return YGUnwrapFloatOptional(optional) == val;
return op1.getValue() > op2.getValue() ? op1 : op2;
}
return op1.isUndefined() ? op2 : op1;
} }

View File

@@ -40,12 +40,12 @@ struct YGCollectFlexItemsRowValues {
float sizeConsumedOnCurrentLine; float sizeConsumedOnCurrentLine;
float totalFlexGrowFactors; float totalFlexGrowFactors;
float totalFlexShrinkScaledFactors; float totalFlexShrinkScaledFactors;
uint32_t endOfLineIndex; float endOfLineIndex;
std::vector<YGNodeRef> relativeChildren; std::vector<YGNodeRef> relativeChildren;
float remainingFreeSpace; float remainingFreeSpace;
// The size of the mainDim for the row after considering size, padding, margin // The size of the mainDim for the row after considering size, padding, margin
// and border of flex items. This is used to calculate maxLineDim after going // and border of flex items. This is used to calculate maxLineDim after going
// through all the rows to decide on the main axis size of owner. // through all the rows to decide on the main axis size of parent.
float mainDim; float mainDim;
// The size of the crossDim for the row after considering size, padding, // The size of the crossDim for the row after considering size, padding,
// margin and border of flex items. Used for calculating containers crossSize. // margin and border of flex items. Used for calculating containers crossSize.
@@ -65,10 +65,6 @@ bool YGFloatsEqual(const float a, const float b);
// compiler flag. // compiler flag.
float YGFloatMax(const float a, const float b); float YGFloatMax(const float a, const float b);
YGFloatOptional YGFloatOptionalMax(
const YGFloatOptional& op1,
const YGFloatOptional& op2);
// We need custom min function, since we want that, if one argument is // We need custom min function, since we want that, if one argument is
// YGUndefined then the min funtion should return the other argument as the min // YGUndefined then the min funtion should return the other argument as the min
// value. We wouldn't have needed a custom min function if YGUndefined was NAN // value. We wouldn't have needed a custom min function if YGUndefined was NAN
@@ -98,6 +94,12 @@ float YGFloatSanitize(const float& val);
// TODO: Get rid off this function // TODO: Get rid off this function
float YGUnwrapFloatOptional(const YGFloatOptional& op); float YGUnwrapFloatOptional(const YGFloatOptional& op);
// This function returns true if val and optional both are undefined or if val
// and optional.val is true, otherwise its false.
bool YGFloatOptionalFloatEquals(
const YGFloatOptional& optional,
const float& val);
YGFlexDirection YGFlexDirectionCross( YGFlexDirection YGFlexDirectionCross(
const YGFlexDirection flexDirection, const YGFlexDirection flexDirection,
const YGDirection direction); const YGDirection direction);
@@ -107,7 +109,7 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
flexDirection == YGFlexDirectionRowReverse; flexDirection == YGFlexDirectionRowReverse;
} }
inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) { inline YGFloatOptional YGResolveValue(const YGValue value, const float parentSize) {
switch (value.unit) { switch (value.unit) {
case YGUnitUndefined: case YGUnitUndefined:
case YGUnitAuto: case YGUnitAuto:
@@ -116,7 +118,7 @@ inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize
return YGFloatOptional(value.value); return YGFloatOptional(value.value);
case YGUnitPercent: case YGUnitPercent:
return YGFloatOptional( return YGFloatOptional(
static_cast<float>(value.value * ownerSize * 0.01)); static_cast<float>(value.value * parentSize * 0.01));
} }
return YGFloatOptional(); return YGFloatOptional();
} }
@@ -140,9 +142,8 @@ inline YGFlexDirection YGResolveFlexDirection(
return flexDirection; return flexDirection;
} }
static inline YGFloatOptional YGResolveValueMargin( static inline float YGResolveValueMargin(
const YGValue value, const YGValue value,
const float ownerSize) { const float parentSize) {
return value.unit == YGUnitAuto ? YGFloatOptional(0) return value.unit == YGUnitAuto ? 0 : YGUnwrapFloatOptional(YGResolveValue(value, parentSize));
: YGResolveValue(value, ownerSize);
} }

View File

@@ -1,19 +0,0 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "YGConfig.h"
const std::array<bool, YGExperimentalFeatureCount>
kYGDefaultExperimentalFeatures = {{false}};
YGConfig::YGConfig(YGLogger logger)
: experimentalFeatures(kYGDefaultExperimentalFeatures),
useWebDefaults(false),
useLegacyStretchBehaviour(false),
shouldDiffLayoutWithoutLegacyStretchBehaviour(false),
pointScaleFactor(1.0f), logger(logger), cloneNodeCallback(nullptr),
context(nullptr) {}

View File

@@ -1,23 +0,0 @@
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include "Yoga-internal.h"
#include "Yoga.h"
struct YGConfig {
std::array<bool, YGExperimentalFeatureCount> experimentalFeatures;
bool useWebDefaults;
bool useLegacyStretchBehaviour;
bool shouldDiffLayoutWithoutLegacyStretchBehaviour;
float pointScaleFactor;
YGLogger logger;
YGCloneNodeFunc cloneNodeCallback;
void* context;
YGConfig(YGLogger logger);
};

View File

@@ -8,21 +8,12 @@
#include "YGFloatOptional.h" #include "YGFloatOptional.h"
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include "Yoga.h"
YGFloatOptional::YGFloatOptional(const float& value) {
if (YGFloatIsUndefined(value)) {
isUndefined_ = true;
value_ = 0;
} else {
value_ = value;
isUndefined_ = false;
}
}
YGFloatOptional::YGFloatOptional(const float& value)
: value_(value), isUndefined_(false) {}
YGFloatOptional::YGFloatOptional() : value_(0), isUndefined_(true) {} YGFloatOptional::YGFloatOptional() : value_(0), isUndefined_(true) {}
const float& YGFloatOptional::getValue() const { float YGFloatOptional::getValue() const {
if (isUndefined_) { if (isUndefined_) {
// Abort, accessing a value of an undefined float optional // Abort, accessing a value of an undefined float optional
std::cerr << "Tried to get value of an undefined YGFloatOptional\n"; std::cerr << "Tried to get value of an undefined YGFloatOptional\n";
@@ -36,57 +27,6 @@ void YGFloatOptional::setValue(const float& val) {
isUndefined_ = false; isUndefined_ = false;
} }
const bool& YGFloatOptional::isUndefined() const { bool YGFloatOptional::isUndefined() const {
return isUndefined_; return isUndefined_;
} }
bool YGFloatOptional::operator==(const YGFloatOptional& op) const {
if (isUndefined_ == op.isUndefined()) {
return isUndefined_ ? true : value_ == op.getValue();
}
return false;
}
bool YGFloatOptional::operator!=(const YGFloatOptional& op) const {
return !(*this == op);
}
bool YGFloatOptional::operator==(const float& val) const {
if (YGFloatIsUndefined(val) == isUndefined_) {
return isUndefined_ ? true : val == value_;
}
return false;
}
bool YGFloatOptional::operator!=(const float& val) const {
return !(*this == val);
}
YGFloatOptional YGFloatOptional::operator+(const YGFloatOptional& op) {
if (!isUndefined_ && !op.isUndefined_) {
return YGFloatOptional(value_ + op.value_);
}
return YGFloatOptional();
}
bool YGFloatOptional::operator>(const YGFloatOptional& op) const {
if (isUndefined_ || op.isUndefined_) {
return false;
}
return value_ > op.value_;
}
bool YGFloatOptional::operator<(const YGFloatOptional& op) const {
if (isUndefined_ || op.isUndefined_) {
return false;
}
return value_ < op.value_;
}
bool YGFloatOptional::operator>=(const YGFloatOptional& op) const {
return *this == op ? true : *this > op;
}
bool YGFloatOptional::operator<=(const YGFloatOptional& op) const {
return *this == op ? true : *this < op;
}

View File

@@ -5,35 +5,22 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#pragma once
struct YGFloatOptional { struct YGFloatOptional {
private: private:
float value_; float value_;
bool isUndefined_; bool isUndefined_;
public: public:
explicit YGFloatOptional(const float& value); YGFloatOptional(const float& value);
explicit YGFloatOptional(); YGFloatOptional();
// Program will terminate if the value of an undefined is accessed. Please // Program will terminate if the value of an undefined is accessed. Please
// make sure to check if the optional is defined before calling this function. // make sure to check if the optional is defined before calling this function.
// To check if float optional is defined, use `isUndefined()`. // To check if float optional is defined, use `isUndefined()`.
const float& getValue() const; float getValue() const;
// Sets the value of float optional, and thus isUndefined is assigned false. // Sets the value of float optional, and thus isUndefined is assigned false.
void setValue(const float& val); void setValue(const float& val);
const bool& isUndefined() const; bool isUndefined() const;
YGFloatOptional operator+(const YGFloatOptional& op);
bool operator>(const YGFloatOptional& op) const;
bool operator<(const YGFloatOptional& op) const;
bool operator>=(const YGFloatOptional& op) const;
bool operator<=(const YGFloatOptional& op) const;
bool operator==(const YGFloatOptional& op) const;
bool operator!=(const YGFloatOptional& op) const;
bool operator==(const float& val) const;
bool operator!=(const float& val) const;
}; };

View File

@@ -19,10 +19,10 @@ YGLayout::YGLayout()
padding(), padding(),
direction(YGDirectionInherit), direction(YGDirectionInherit),
computedFlexBasisGeneration(0), computedFlexBasisGeneration(0),
computedFlexBasis(YGFloatOptional()), computedFlexBasis(YGUndefined),
hadOverflow(false), hadOverflow(false),
generationCount(0), generationCount(0),
lastOwnerDirection((YGDirection)-1), lastParentDirection((YGDirection)-1),
nextCachedMeasurementsIndex(0), nextCachedMeasurementsIndex(0),
cachedMeasurements(), cachedMeasurements(),
measuredDimensions(kYGDefaultDimensionValues), measuredDimensions(kYGDefaultDimensionValues),
@@ -37,15 +37,18 @@ bool YGLayout::operator==(YGLayout layout) const {
YGFloatArrayEqual(border, layout.border) && YGFloatArrayEqual(border, layout.border) &&
YGFloatArrayEqual(padding, layout.padding) && YGFloatArrayEqual(padding, layout.padding) &&
direction == layout.direction && hadOverflow == layout.hadOverflow && direction == layout.direction && hadOverflow == layout.hadOverflow &&
lastOwnerDirection == layout.lastOwnerDirection && lastParentDirection == layout.lastParentDirection &&
nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex && nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex &&
cachedLayout == layout.cachedLayout && cachedLayout == layout.cachedLayout;
computedFlexBasis == layout.computedFlexBasis;
for (uint32_t i = 0; i < YG_MAX_CACHED_RESULT_COUNT && isEqual; ++i) { for (uint32_t i = 0; i < YG_MAX_CACHED_RESULT_COUNT && isEqual; ++i) {
isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i]; isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i];
} }
if (!YGFloatIsUndefined(computedFlexBasis) ||
!YGFloatIsUndefined(layout.computedFlexBasis)) {
isEqual = isEqual && (computedFlexBasis == layout.computedFlexBasis);
}
if (!YGFloatIsUndefined(measuredDimensions[0]) || if (!YGFloatIsUndefined(measuredDimensions[0]) ||
!YGFloatIsUndefined(layout.measuredDimensions[0])) { !YGFloatIsUndefined(layout.measuredDimensions[0])) {
isEqual = isEqual =

View File

@@ -6,7 +6,6 @@
*/ */
#pragma once #pragma once
#include "YGFloatOptional.h"
#include "Yoga-internal.h" #include "Yoga-internal.h"
struct YGLayout { struct YGLayout {
@@ -18,13 +17,13 @@ struct YGLayout {
YGDirection direction; YGDirection direction;
uint32_t computedFlexBasisGeneration; uint32_t computedFlexBasisGeneration;
YGFloatOptional computedFlexBasis; float computedFlexBasis;
bool hadOverflow; bool hadOverflow;
// Instead of recomputing the entire layout every single time, we // Instead of recomputing the entire layout every single time, we
// cache some information to break early when nothing changed // cache some information to break early when nothing changed
uint32_t generationCount; uint32_t generationCount;
YGDirection lastOwnerDirection; YGDirection lastParentDirection;
uint32_t nextCachedMeasurementsIndex; uint32_t nextCachedMeasurementsIndex;
std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT> std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>

View File

@@ -49,8 +49,8 @@ uint32_t YGNode::getLineIndex() const {
return lineIndex_; return lineIndex_;
} }
YGNodeRef YGNode::getOwner() const { YGNodeRef YGNode::getParent() const {
return owner_; return parent_;
} }
YGVector YGNode::getChildren() const { YGVector YGNode::getChildren() const {
@@ -85,14 +85,14 @@ std::array<YGValue, 2> YGNode::getResolvedDimensions() const {
return resolvedDimensions_; return resolvedDimensions_;
} }
YGFloatOptional YGNode::getLeadingPosition( float YGNode::getLeadingPosition(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& axisSize) const { const float axisSize) const {
if (YGFlexDirectionIsRow(axis)) { if (YGFlexDirectionIsRow(axis)) {
const YGValue* leadingPosition = const YGValue* leadingPosition =
YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined); YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined);
if (leadingPosition->unit != YGUnitUndefined) { if (leadingPosition->unit != YGUnitUndefined) {
return YGResolveValue(*leadingPosition, axisSize); return YGUnwrapFloatOptional(YGResolveValue(*leadingPosition, axisSize));
} }
} }
@@ -100,18 +100,18 @@ YGFloatOptional YGNode::getLeadingPosition(
YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined); YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined);
return leadingPosition->unit == YGUnitUndefined return leadingPosition->unit == YGUnitUndefined
? YGFloatOptional(0) ? 0.0f
: YGResolveValue(*leadingPosition, axisSize); : YGUnwrapFloatOptional(YGResolveValue(*leadingPosition, axisSize));
} }
YGFloatOptional YGNode::getTrailingPosition( float YGNode::getTrailingPosition(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& axisSize) const { const float axisSize) const {
if (YGFlexDirectionIsRow(axis)) { if (YGFlexDirectionIsRow(axis)) {
const YGValue* trailingPosition = const YGValue* trailingPosition =
YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined); YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined);
if (trailingPosition->unit != YGUnitUndefined) { if (trailingPosition->unit != YGUnitUndefined) {
return YGResolveValue(*trailingPosition, axisSize); return YGUnwrapFloatOptional(YGResolveValue(*trailingPosition, axisSize));
} }
} }
@@ -119,11 +119,11 @@ YGFloatOptional YGNode::getTrailingPosition(
YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined); YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined);
return trailingPosition->unit == YGUnitUndefined return trailingPosition->unit == YGUnitUndefined
? YGFloatOptional(0) ? 0.0f
: YGResolveValue(*trailingPosition, axisSize); : YGUnwrapFloatOptional(YGResolveValue(*trailingPosition, axisSize));
} }
bool YGNode::isLeadingPositionDefined(const YGFlexDirection& axis) const { bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
return (YGFlexDirectionIsRow(axis) && return (YGFlexDirectionIsRow(axis) &&
YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined) YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined)
->unit != YGUnitUndefined) || ->unit != YGUnitUndefined) ||
@@ -131,7 +131,7 @@ bool YGNode::isLeadingPositionDefined(const YGFlexDirection& axis) const {
->unit != YGUnitUndefined; ->unit != YGUnitUndefined;
} }
bool YGNode::isTrailingPosDefined(const YGFlexDirection& axis) const { bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
return (YGFlexDirectionIsRow(axis) && return (YGFlexDirectionIsRow(axis) &&
YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined) YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined)
->unit != YGUnitUndefined) || ->unit != YGUnitUndefined) ||
@@ -139,9 +139,9 @@ bool YGNode::isTrailingPosDefined(const YGFlexDirection& axis) const {
->unit != YGUnitUndefined; ->unit != YGUnitUndefined;
} }
YGFloatOptional YGNode::getLeadingMargin( float YGNode::getLeadingMargin(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
if (YGFlexDirectionIsRow(axis) && if (YGFlexDirectionIsRow(axis) &&
style_.margin[YGEdgeStart].unit != YGUnitUndefined) { style_.margin[YGEdgeStart].unit != YGUnitUndefined) {
return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize); return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize);
@@ -152,9 +152,9 @@ YGFloatOptional YGNode::getLeadingMargin(
widthSize); widthSize);
} }
YGFloatOptional YGNode::getTrailingMargin( float YGNode::getTrailingMargin(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
if (YGFlexDirectionIsRow(axis) && if (YGFlexDirectionIsRow(axis) &&
style_.margin[YGEdgeEnd].unit != YGUnitUndefined) { style_.margin[YGEdgeEnd].unit != YGUnitUndefined) {
return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize); return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize);
@@ -165,9 +165,9 @@ YGFloatOptional YGNode::getTrailingMargin(
widthSize); widthSize);
} }
YGFloatOptional YGNode::getMarginForAxis( float YGNode::getMarginForAxis(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize);
} }
@@ -237,8 +237,8 @@ void YGNode::setLineIndex(uint32_t lineIndex) {
lineIndex_ = lineIndex; lineIndex_ = lineIndex;
} }
void YGNode::setOwner(YGNodeRef owner) { void YGNode::setParent(YGNodeRef parent) {
owner_ = owner; parent_ = parent;
} }
void YGNode::setChildren(const YGVector& children) { void YGNode::setChildren(const YGVector& children) {
@@ -305,12 +305,11 @@ void YGNode::setLayoutPadding(float padding, int index) {
layout_.padding[index] = padding; layout_.padding[index] = padding;
} }
void YGNode::setLayoutLastOwnerDirection(YGDirection direction) { void YGNode::setLayoutLastParentDirection(YGDirection direction) {
layout_.lastOwnerDirection = direction; layout_.lastParentDirection = direction;
} }
void YGNode::setLayoutComputedFlexBasis( void YGNode::setLayoutComputedFlexBasis(float computedFlexBasis) {
const YGFloatOptional& computedFlexBasis) {
layout_.computedFlexBasis = computedFlexBasis; layout_.computedFlexBasis = computedFlexBasis;
} }
@@ -337,54 +336,41 @@ void YGNode::setLayoutDimension(float dimension, int index) {
// If both left and right are defined, then use left. Otherwise return // If both left and right are defined, then use left. Otherwise return
// +left or -right depending on which is defined. // +left or -right depending on which is defined.
YGFloatOptional YGNode::relativePosition( float YGNode::relativePosition(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& axisSize) const { const float axisSize) {
if (isLeadingPositionDefined(axis)) { return isLeadingPositionDefined(axis) ? getLeadingPosition(axis, axisSize)
return getLeadingPosition(axis, axisSize); : -getTrailingPosition(axis, axisSize);
}
YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize);
if (!trailingPosition.isUndefined()) {
trailingPosition.setValue(-1 * trailingPosition.getValue());
}
return trailingPosition;
} }
void YGNode::setPosition( void YGNode::setPosition(
const YGDirection direction, const YGDirection direction,
const float mainSize, const float mainSize,
const float crossSize, const float crossSize,
const float ownerWidth) { const float parentWidth) {
/* Root nodes should be always layouted as LTR, so we don't return negative /* Root nodes should be always layouted as LTR, so we don't return negative
* values. */ * values. */
const YGDirection directionRespectingRoot = const YGDirection directionRespectingRoot =
owner_ != nullptr ? direction : YGDirectionLTR; parent_ != nullptr ? direction : YGDirectionLTR;
const YGFlexDirection mainAxis = const YGFlexDirection mainAxis =
YGResolveFlexDirection(style_.flexDirection, directionRespectingRoot); YGResolveFlexDirection(style_.flexDirection, directionRespectingRoot);
const YGFlexDirection crossAxis = const YGFlexDirection crossAxis =
YGFlexDirectionCross(mainAxis, directionRespectingRoot); YGFlexDirectionCross(mainAxis, directionRespectingRoot);
const YGFloatOptional relativePositionMain = const float relativePositionMain = relativePosition(mainAxis, mainSize);
relativePosition(mainAxis, mainSize); const float relativePositionCross = relativePosition(crossAxis, crossSize);
const YGFloatOptional relativePositionCross =
relativePosition(crossAxis, crossSize);
setLayoutPosition( setLayoutPosition(
YGUnwrapFloatOptional( getLeadingMargin(mainAxis, parentWidth) + relativePositionMain,
getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain),
leading[mainAxis]); leading[mainAxis]);
setLayoutPosition( setLayoutPosition(
YGUnwrapFloatOptional( getTrailingMargin(mainAxis, parentWidth) + relativePositionMain,
getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain),
trailing[mainAxis]); trailing[mainAxis]);
setLayoutPosition( setLayoutPosition(
YGUnwrapFloatOptional( getLeadingMargin(crossAxis, parentWidth) + relativePositionCross,
getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross),
leading[crossAxis]); leading[crossAxis]);
setLayoutPosition( setLayoutPosition(
YGUnwrapFloatOptional( getTrailingMargin(crossAxis, parentWidth) + relativePositionCross,
getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross),
trailing[crossAxis]); trailing[crossAxis]);
} }
@@ -399,7 +385,7 @@ YGNode::YGNode()
style_(YGStyle()), style_(YGStyle()),
layout_(YGLayout()), layout_(YGLayout()),
lineIndex_(0), lineIndex_(0),
owner_(nullptr), parent_(nullptr),
children_(YGVector()), children_(YGVector()),
nextChild_(nullptr), nextChild_(nullptr),
config_(nullptr), config_(nullptr),
@@ -417,7 +403,7 @@ YGNode::YGNode(const YGNode& node)
style_(node.style_), style_(node.style_),
layout_(node.layout_), layout_(node.layout_),
lineIndex_(node.lineIndex_), lineIndex_(node.lineIndex_),
owner_(node.owner_), parent_(node.parent_),
children_(node.children_), children_(node.children_),
nextChild_(node.nextChild_), nextChild_(node.nextChild_),
config_(node.config_), config_(node.config_),
@@ -439,7 +425,7 @@ YGNode::YGNode(
YGStyle style, YGStyle style,
const YGLayout& layout, const YGLayout& layout,
uint32_t lineIndex, uint32_t lineIndex,
YGNodeRef owner, YGNodeRef parent,
const YGVector& children, const YGVector& children,
YGNodeRef nextChild, YGNodeRef nextChild,
YGConfigRef config, YGConfigRef config,
@@ -455,7 +441,7 @@ YGNode::YGNode(
style_(style), style_(style),
layout_(layout), layout_(layout),
lineIndex_(lineIndex), lineIndex_(lineIndex),
owner_(owner), parent_(parent),
children_(children), children_(children),
nextChild_(nextChild), nextChild_(nextChild),
config_(config), config_(config),
@@ -481,7 +467,7 @@ YGNode& YGNode::operator=(const YGNode& node) {
style_ = node.style_; style_ = node.style_;
layout_ = node.layout_; layout_ = node.layout_;
lineIndex_ = node.getLineIndex(); lineIndex_ = node.getLineIndex();
owner_ = node.getOwner(); parent_ = node.getParent();
children_ = node.getChildren(); children_ = node.getChildren();
nextChild_ = node.getNextChild(); nextChild_ = node.getNextChild();
config_ = node.getConfig(); config_ = node.getConfig();
@@ -532,9 +518,9 @@ void YGNode::resolveDimension() {
} }
} }
YGDirection YGNode::resolveDirection(const YGDirection ownerDirection) { YGDirection YGNode::resolveDirection(const YGDirection parentDirection) {
if (style_.direction == YGDirectionInherit) { if (style_.direction == YGDirectionInherit) {
return ownerDirection > YGDirectionInherit ? ownerDirection return parentDirection > YGDirectionInherit ? parentDirection
: YGDirectionLTR; : YGDirectionLTR;
} else { } else {
return style_.direction; return style_.direction;
@@ -564,35 +550,32 @@ void YGNode::cloneChildrenIfNeeded() {
} }
const YGNodeRef firstChild = children_.front(); const YGNodeRef firstChild = children_.front();
if (firstChild->getOwner() == this) { if (firstChild->getParent() == this) {
// If the first child has this node as its owner, we assume that it is // If the first child has this node as its parent, we assume that it is
// already unique. We can do this because if we have it has a child, that // already unique. We can do this because if we have it has a child, that
// means that its owner was at some point cloned which made that subtree // means that its parent was at some point cloned which made that subtree
// immutable. We also assume that all its sibling are cloned as well. // immutable. We also assume that all its sibling are cloned as well.
return; return;
} }
const YGCloneNodeFunc cloneNodeCallback = config_->cloneNodeCallback; const YGNodeClonedFunc cloneNodeCallback = config_->cloneNodeCallback;
for (uint32_t i = 0; i < childCount; ++i) { for (uint32_t i = 0; i < childCount; ++i) {
const YGNodeRef oldChild = children_[i]; const YGNodeRef oldChild = children_[i];
YGNodeRef newChild = nullptr; const YGNodeRef newChild = YGNodeClone(oldChild);
if (cloneNodeCallback) {
newChild = cloneNodeCallback(oldChild, this, i);
}
if (newChild == nullptr) {
newChild = YGNodeClone(oldChild);
}
replaceChild(newChild, i); replaceChild(newChild, i);
newChild->setOwner(this); newChild->setParent(this);
if (cloneNodeCallback) {
cloneNodeCallback(oldChild, newChild, this, i);
}
} }
} }
void YGNode::markDirtyAndPropogate() { void YGNode::markDirtyAndPropogate() {
if (!isDirty_) { if (!isDirty_) {
setDirty(true); setDirty(true);
setLayoutComputedFlexBasis(YGFloatOptional()); setLayoutComputedFlexBasis(YGUndefined);
if (owner_) { if (parent_) {
owner_->markDirtyAndPropogate(); parent_->markDirtyAndPropogate();
} }
} }
} }
@@ -606,7 +589,7 @@ void YGNode::markDirtyAndPropogateDownwards() {
float YGNode::resolveFlexGrow() { float YGNode::resolveFlexGrow() {
// Root nodes flexGrow should always be 0 // Root nodes flexGrow should always be 0
if (owner_ == nullptr) { if (parent_ == nullptr) {
return 0.0; return 0.0;
} }
if (!style_.flexGrow.isUndefined()) { if (!style_.flexGrow.isUndefined()) {
@@ -619,7 +602,7 @@ float YGNode::resolveFlexGrow() {
} }
float YGNode::resolveFlexShrink() { float YGNode::resolveFlexShrink() {
if (owner_ == nullptr) { if (parent_ == nullptr) {
return 0.0; return 0.0;
} }
if (!style_.flexShrink.isUndefined()) { if (!style_.flexShrink.isUndefined()) {
@@ -638,7 +621,7 @@ bool YGNode::isNodeFlexible() {
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); (resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
} }
float YGNode::getLeadingBorder(const YGFlexDirection& axis) const { float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
if (YGFlexDirectionIsRow(axis) && if (YGFlexDirectionIsRow(axis) &&
style_.border[YGEdgeStart].unit != YGUnitUndefined && style_.border[YGEdgeStart].unit != YGUnitUndefined &&
!YGFloatIsUndefined(style_.border[YGEdgeStart].value) && !YGFloatIsUndefined(style_.border[YGEdgeStart].value) &&
@@ -651,7 +634,7 @@ float YGNode::getLeadingBorder(const YGFlexDirection& axis) const {
return YGFloatMax(computedEdgeValue, 0.0f); return YGFloatMax(computedEdgeValue, 0.0f);
} }
float YGNode::getTrailingBorder(const YGFlexDirection& flexDirection) const { float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
if (YGFlexDirectionIsRow(flexDirection) && if (YGFlexDirectionIsRow(flexDirection) &&
style_.border[YGEdgeEnd].unit != YGUnitUndefined && style_.border[YGEdgeEnd].unit != YGUnitUndefined &&
!YGFloatIsUndefined(style_.border[YGEdgeEnd].value) && !YGFloatIsUndefined(style_.border[YGEdgeEnd].value) &&
@@ -665,52 +648,51 @@ float YGNode::getTrailingBorder(const YGFlexDirection& flexDirection) const {
return YGFloatMax(computedEdgeValue, 0.0f); return YGFloatMax(computedEdgeValue, 0.0f);
} }
YGFloatOptional YGNode::getLeadingPadding( float YGNode::getLeadingPadding(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
const YGFloatOptional& paddingEdgeStart =
YGResolveValue(style_.padding[YGEdgeStart], widthSize);
if (YGFlexDirectionIsRow(axis) && if (YGFlexDirectionIsRow(axis) &&
style_.padding[YGEdgeStart].unit != YGUnitUndefined && style_.padding[YGEdgeStart].unit != YGUnitUndefined &&
!paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() > 0.0f) { !YGResolveValue(style_.padding[YGEdgeStart], widthSize).isUndefined() &&
return paddingEdgeStart; YGUnwrapFloatOptional(
YGResolveValue(style_.padding[YGEdgeStart], widthSize)) > 0.0f) {
return YGUnwrapFloatOptional(YGResolveValue(style_.padding[YGEdgeStart], widthSize));
} }
YGFloatOptional resolvedValue = YGResolveValue( float resolvedValue = YGUnwrapFloatOptional(YGResolveValue(
*YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero), *YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero),
widthSize); widthSize));
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); return YGFloatMax(resolvedValue, 0.0f);
} }
YGFloatOptional YGNode::getTrailingPadding( float YGNode::getTrailingPadding(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
if (YGFlexDirectionIsRow(axis) && if (YGFlexDirectionIsRow(axis) &&
style_.padding[YGEdgeEnd].unit != YGUnitUndefined && style_.padding[YGEdgeEnd].unit != YGUnitUndefined &&
!YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() && !YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() &&
YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) { YGUnwrapFloatOptional(
return YGResolveValue(style_.padding[YGEdgeEnd], widthSize); YGResolveValue(style_.padding[YGEdgeEnd], widthSize)) >= 0.0f) {
return YGUnwrapFloatOptional(YGResolveValue(style_.padding[YGEdgeEnd], widthSize));
} }
YGFloatOptional resolvedValue = YGResolveValue( float resolvedValue = YGUnwrapFloatOptional(YGResolveValue(
*YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero), *YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero),
widthSize); widthSize));
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); return YGFloatMax(resolvedValue, 0.0f);
} }
YGFloatOptional YGNode::getLeadingPaddingAndBorder( float YGNode::getLeadingPaddingAndBorder(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
return getLeadingPadding(axis, widthSize) + return getLeadingPadding(axis, widthSize) + getLeadingBorder(axis);
YGFloatOptional(getLeadingBorder(axis));
} }
YGFloatOptional YGNode::getTrailingPaddingAndBorder( float YGNode::getTrailingPaddingAndBorder(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const { const float widthSize) const {
return getTrailingPadding(axis, widthSize) + return getTrailingPadding(axis, widthSize) + getTrailingBorder(axis);
YGFloatOptional(getTrailingBorder(axis));
} }
bool YGNode::didUseLegacyFlag() { bool YGNode::didUseLegacyFlag() {

View File

@@ -7,7 +7,6 @@
#pragma once #pragma once
#include <stdio.h> #include <stdio.h>
#include "YGConfig.h"
#include "YGLayout.h" #include "YGLayout.h"
#include "YGStyle.h" #include "YGStyle.h"
#include "Yoga-internal.h" #include "Yoga-internal.h"
@@ -24,16 +23,14 @@ struct YGNode {
YGStyle style_; YGStyle style_;
YGLayout layout_; YGLayout layout_;
uint32_t lineIndex_; uint32_t lineIndex_;
YGNodeRef owner_; YGNodeRef parent_;
YGVector children_; YGVector children_;
YGNodeRef nextChild_; YGNodeRef nextChild_;
YGConfigRef config_; YGConfigRef config_;
bool isDirty_; bool isDirty_;
std::array<YGValue, 2> resolvedDimensions_; std::array<YGValue, 2> resolvedDimensions_;
YGFloatOptional relativePosition( float relativePosition(const YGFlexDirection axis, const float axisSize);
const YGFlexDirection& axis,
const float& axisSize) const;
public: public:
YGNode(); YGNode();
@@ -52,7 +49,7 @@ struct YGNode {
YGStyle style, YGStyle style,
const YGLayout& layout, const YGLayout& layout,
uint32_t lineIndex, uint32_t lineIndex,
YGNodeRef owner, YGNodeRef parent,
const YGVector& children, const YGVector& children,
YGNodeRef nextChild, YGNodeRef nextChild,
YGConfigRef config, YGConfigRef config,
@@ -72,12 +69,7 @@ struct YGNode {
// For Performance reasons passing as reference. // For Performance reasons passing as reference.
YGLayout& getLayout(); YGLayout& getLayout();
uint32_t getLineIndex() const; uint32_t getLineIndex() const;
// returns the YGNodeRef that owns this YGNode. An owner is used to identify YGNodeRef getParent() const;
// the YogaTree that a YGNode belongs to.
// This method will return the parent of the YGNode when a YGNode only belongs
// to one YogaTree or nullptr when the YGNode is shared between two or more
// YogaTrees.
YGNodeRef getOwner() const;
YGVector getChildren() const; YGVector getChildren() const;
uint32_t getChildrenCount() const; uint32_t getChildrenCount() const;
YGNodeRef getChild(uint32_t index) const; YGNodeRef getChild(uint32_t index) const;
@@ -88,36 +80,23 @@ struct YGNode {
YGValue getResolvedDimension(int index); YGValue getResolvedDimension(int index);
// Methods related to positions, margin, padding and border // Methods related to positions, margin, padding and border
YGFloatOptional getLeadingPosition(const YGFlexDirection& axis, float getLeadingPosition(const YGFlexDirection axis, const float axisSize) const;
const float& axisSize) const; bool isLeadingPositionDefined(const YGFlexDirection axis) const;
bool isLeadingPositionDefined(const YGFlexDirection& axis) const; bool isTrailingPosDefined(const YGFlexDirection axis) const;
bool isTrailingPosDefined(const YGFlexDirection& axis) const; float getTrailingPosition(const YGFlexDirection axis, const float axisSize) const;
YGFloatOptional getTrailingPosition( float getLeadingMargin(const YGFlexDirection axis, const float widthSize) const;
const YGFlexDirection& axis, float getTrailingMargin(const YGFlexDirection axis, const float widthSize) const;
const float& axisSize) const; float getLeadingBorder(const YGFlexDirection flexDirection) const;
YGFloatOptional getLeadingMargin( float getTrailingBorder(const YGFlexDirection flexDirection) const;
const YGFlexDirection& axis, float getLeadingPadding(const YGFlexDirection axis, const float widthSize) const;
const float& widthSize) const; float getTrailingPadding(const YGFlexDirection axis, const float widthSize) const;
YGFloatOptional getTrailingMargin( float getLeadingPaddingAndBorder(
const YGFlexDirection& axis, const YGFlexDirection axis,
const float& widthSize) const; const float widthSize) const;
float getLeadingBorder(const YGFlexDirection& flexDirection) const; float getTrailingPaddingAndBorder(
float getTrailingBorder(const YGFlexDirection& flexDirection) const; const YGFlexDirection axis,
YGFloatOptional getLeadingPadding( const float widthSize) const;
const YGFlexDirection& axis, float getMarginForAxis(const YGFlexDirection axis, const float widthSize) const;
const float& widthSize) const;
YGFloatOptional getTrailingPadding(
const YGFlexDirection& axis,
const float& widthSize) const;
YGFloatOptional getLeadingPaddingAndBorder(
const YGFlexDirection& axis,
const float& widthSize) const;
YGFloatOptional getTrailingPaddingAndBorder(
const YGFlexDirection& axis,
const float& widthSize) const;
YGFloatOptional getMarginForAxis(
const YGFlexDirection& axis,
const float& widthSize) const;
// Setters // Setters
void setContext(void* context); void setContext(void* context);
@@ -132,13 +111,13 @@ struct YGNode {
void setStyleAlignContent(YGAlign alignContent); void setStyleAlignContent(YGAlign alignContent);
void setLayout(const YGLayout& layout); void setLayout(const YGLayout& layout);
void setLineIndex(uint32_t lineIndex); void setLineIndex(uint32_t lineIndex);
void setOwner(YGNodeRef owner); void setParent(YGNodeRef parent);
void setChildren(const YGVector& children); void setChildren(const YGVector& children);
void setNextChild(YGNodeRef nextChild); void setNextChild(YGNodeRef nextChild);
void setConfig(YGConfigRef config); void setConfig(YGConfigRef config);
void setDirty(bool isDirty); void setDirty(bool isDirty);
void setLayoutLastOwnerDirection(YGDirection direction); void setLayoutLastParentDirection(YGDirection direction);
void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis); void setLayoutComputedFlexBasis(float computedFlexBasis);
void setLayoutComputedFlexBasisGeneration( void setLayoutComputedFlexBasisGeneration(
uint32_t computedFlexBasisGeneration); uint32_t computedFlexBasisGeneration);
void setLayoutMeasuredDimension(float measuredDimension, int index); void setLayoutMeasuredDimension(float measuredDimension, int index);
@@ -153,7 +132,7 @@ struct YGNode {
const YGDirection direction, const YGDirection direction,
const float mainSize, const float mainSize,
const float crossSize, const float crossSize,
const float ownerWidth); const float parentWidth);
void setAndPropogateUseLegacyFlag(bool useLegacyFlag); void setAndPropogateUseLegacyFlag(bool useLegacyFlag);
void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout); void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout);
void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag); void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag);
@@ -164,7 +143,7 @@ struct YGNode {
YGValue marginTrailingValue(const YGFlexDirection axis) const; YGValue marginTrailingValue(const YGFlexDirection axis) const;
YGValue resolveFlexBasisPtr() const; YGValue resolveFlexBasisPtr() const;
void resolveDimension(); void resolveDimension();
YGDirection resolveDirection(const YGDirection ownerDirection); YGDirection resolveDirection(const YGDirection parentDirection);
void clearChildren(); void clearChildren();
/// Replaces the occurrences of oldChild with newChild /// Replaces the occurrences of oldChild with newChild
void replaceChild(YGNodeRef oldChild, YGNodeRef newChild); void replaceChild(YGNodeRef oldChild, YGNodeRef newChild);

View File

@@ -9,7 +9,7 @@
const YGValue kYGValueUndefined = {0, YGUnitUndefined}; const YGValue kYGValueUndefined = {0, YGUnitUndefined};
const YGValue kYGValueAuto = {0, YGUnitAuto}; const YGValue kYGValueAuto = {YGUndefined, YGUnitAuto};
const std::array<YGValue, YGEdgeCount> kYGDefaultEdgeValuesUnit = { const std::array<YGValue, YGEdgeCount> kYGDefaultEdgeValuesUnit = {
{kYGValueUndefined, {kYGValueUndefined,
@@ -42,7 +42,7 @@ YGStyle::YGStyle()
flex(YGFloatOptional()), flex(YGFloatOptional()),
flexGrow(YGFloatOptional()), flexGrow(YGFloatOptional()),
flexShrink(YGFloatOptional()), flexShrink(YGFloatOptional()),
flexBasis(kYGValueAuto), flexBasis({0, YGUnitAuto}),
margin(kYGDefaultEdgeValuesUnit), margin(kYGDefaultEdgeValuesUnit),
position(kYGDefaultEdgeValuesUnit), position(kYGDefaultEdgeValuesUnit),
padding(kYGDefaultEdgeValuesUnit), padding(kYGDefaultEdgeValuesUnit),
@@ -50,7 +50,7 @@ YGStyle::YGStyle()
dimensions(kYGDefaultDimensionValuesAutoUnit), dimensions(kYGDefaultDimensionValuesAutoUnit),
minDimensions(kYGDefaultDimensionValuesUnit), minDimensions(kYGDefaultDimensionValuesUnit),
maxDimensions(kYGDefaultDimensionValuesUnit), maxDimensions(kYGDefaultDimensionValuesUnit),
aspectRatio(YGFloatOptional()) {} aspectRatio(YGUndefined) {}
// Yoga specific properties, not compatible with flexbox specification // Yoga specific properties, not compatible with flexbox specification
bool YGStyle::operator==(const YGStyle& style) { bool YGStyle::operator==(const YGStyle& style) {
@@ -91,9 +91,10 @@ bool YGStyle::operator==(const YGStyle& style) {
flexShrink.getValue() == style.flexShrink.getValue(); flexShrink.getValue() == style.flexShrink.getValue();
} }
if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) { if (!(YGFloatIsUndefined(aspectRatio) &&
areNonFloatValuesEqual = areNonFloatValuesEqual && YGFloatIsUndefined(style.aspectRatio))) {
aspectRatio.getValue() == style.aspectRatio.getValue(); areNonFloatValuesEqual =
areNonFloatValuesEqual && aspectRatio == style.aspectRatio;
} }
return areNonFloatValuesEqual; return areNonFloatValuesEqual;

View File

@@ -32,7 +32,7 @@ struct YGStyle {
std::array<YGValue, 2> dimensions; std::array<YGValue, 2> dimensions;
std::array<YGValue, 2> minDimensions; std::array<YGValue, 2> minDimensions;
std::array<YGValue, 2> maxDimensions; std::array<YGValue, 2> maxDimensions;
YGFloatOptional aspectRatio; float aspectRatio;
YGStyle(); YGStyle();
// Yoga specific properties, not compatible with flexbox specification // Yoga specific properties, not compatible with flexbox specification

View File

@@ -87,6 +87,16 @@ struct YGCachedMeasurement {
// 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.
#define YG_MAX_CACHED_RESULT_COUNT 16 #define YG_MAX_CACHED_RESULT_COUNT 16
struct YGConfig {
bool experimentalFeatures[YGExperimentalFeatureCount + 1];
bool useWebDefaults;
bool useLegacyStretchBehaviour;
bool shouldDiffLayoutWithoutLegacyStretchBehaviour;
float pointScaleFactor;
YGLogger logger;
YGNodeClonedFunc cloneNodeCallback;
void* context;
};
static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexGrow = 0.0f;
static const float kDefaultFlexShrink = 0.0f; static const float kDefaultFlexShrink = 0.0f;

File diff suppressed because it is too large Load Diff

View File

@@ -62,8 +62,10 @@ typedef int (*YGLogger)(const YGConfigRef config,
YGLogLevel level, YGLogLevel level,
const char *format, const char *format,
va_list args); va_list args);
typedef YGNodeRef ( typedef void (*YGNodeClonedFunc)(YGNodeRef oldNode,
*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex); YGNodeRef newNode,
YGNodeRef parent,
int childIndex);
// YGNode // YGNode
WIN_EXPORT YGNodeRef YGNodeNew(void); WIN_EXPORT YGNodeRef YGNodeNew(void);
@@ -77,31 +79,17 @@ WIN_EXPORT int32_t YGNodeGetInstanceCount(void);
WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node, WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
const YGNodeRef child, const YGNodeRef child,
const uint32_t index); const uint32_t index);
// This function inserts the child YGNodeRef as a children of the node received
// by parameter and set the Owner of the child object to null. This function is
// expected to be called when using Yoga in persistent mode in order to share a
// YGNodeRef object as a child of two different Yoga trees. The child YGNodeRef
// is expected to be referenced from its original owner and from a clone of its
// original owner.
WIN_EXPORT void YGNodeInsertSharedChild(
const YGNodeRef node,
const YGNodeRef child,
const uint32_t index);
WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child); WIN_EXPORT void YGNodeRemoveChild(const YGNodeRef node, const YGNodeRef child);
WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node); WIN_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef node);
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index); WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
WIN_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node); WIN_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node);
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node); WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
WIN_EXPORT void YGNodeSetChildren( WIN_EXPORT void YGNodeSetChildren(YGNodeRef const parent, const YGNodeRef children[], const uint32_t count);
YGNodeRef const owner,
const YGNodeRef children[],
const uint32_t count);
WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node, WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
const float availableWidth, const float availableWidth,
const float availableHeight, const float availableHeight,
const YGDirection ownerDirection); const YGDirection parentDirection);
// Mark a node as dirty. Only valid for nodes with a custom measure function // Mark a node as dirty. Only valid for nodes with a custom measure function
// set. // set.
@@ -295,8 +283,8 @@ WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config,
WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled); WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled);
WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config); WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config);
WIN_EXPORT void YGConfigSetCloneNodeFunc(const YGConfigRef config, WIN_EXPORT void YGConfigSetNodeClonedFunc(const YGConfigRef config,
const YGCloneNodeFunc callback); const YGNodeClonedFunc callback);
// Export only for C# // Export only for C#
WIN_EXPORT YGConfigRef YGConfigGetDefault(void); WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
@@ -320,8 +308,6 @@ YG_EXTERN_C_END
// Calls f on each node in the tree including the given node argument. // Calls f on each node in the tree including the given node argument.
extern void YGTraversePreOrder(YGNodeRef const node, std::function<void(YGNodeRef node)>&& f); extern void YGTraversePreOrder(YGNodeRef const node, std::function<void(YGNodeRef node)>&& f);
extern void YGNodeSetChildren( extern void YGNodeSetChildren(YGNodeRef const parent, const std::vector<YGNodeRef> &children);
YGNodeRef const owner,
const std::vector<YGNodeRef>& children);
#endif #endif

View File

@@ -32,7 +32,6 @@ BASE_COMPILER_FLAGS = [
'-Wall', '-Wall',
'-Werror', '-Werror',
'-O3', '-O3',
'-ffast-math',
] ]
LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [ LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [
@@ -113,3 +112,4 @@ def prebuilt_jar(*args, **kwargs):
def is_apple_platform(): def is_apple_platform():
return True return True