Compare commits
25 Commits
yxping/mas
...
v1.8.0
Author | SHA1 | Date | |
---|---|---|---|
|
adb1b11055 | ||
|
2e234473ca | ||
|
6b08db68bb | ||
|
9550126f76 | ||
|
bad262b961 | ||
|
3c6c10075a | ||
|
6a77a6939e | ||
|
b725a4a140 | ||
|
2b714a5b5d | ||
|
572546088f | ||
|
5b109578d3 | ||
|
77b720f9a5 | ||
|
de954eb9cc | ||
|
3e322e60e4 | ||
|
a3642541d0 | ||
|
bb139d3f91 | ||
|
08743a42e2 | ||
|
cb6e76973d | ||
|
4b760fa9bc | ||
|
5730be093e | ||
|
d85e2ee9c3 | ||
|
fe433b012f | ||
|
5e3ffb39a2 | ||
|
f0edefdbb7 | ||
|
17901ea5c2 |
14
BUCK
14
BUCK
@@ -32,20 +32,6 @@ 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(
|
||||
name = "YogaTests",
|
||||
srcs = glob(["tests/*.cpp"]),
|
||||
|
@@ -46,14 +46,14 @@ import java.util.Map;
|
||||
* <YogaLayout
|
||||
* xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
* xmlns:yoga="http://schemas.android.com/apk/com.facebook.yoga.android"
|
||||
* android:layout_width="match_parent"
|
||||
* android:layout_height="match_parent"
|
||||
* android:layout_width="match_owner"
|
||||
* android:layout_height="match_owner"
|
||||
* yoga:flex_direction="row"
|
||||
* yoga:padding_all="10dp"
|
||||
* >
|
||||
* <TextView
|
||||
* android:layout_width="match_parent"
|
||||
* android:layout_height="match_parent"
|
||||
* android:layout_width="match_owner"
|
||||
* android:layout_height="match_owner"
|
||||
* android:text="Hello, World!"
|
||||
* yoga:flex="1"
|
||||
* />
|
||||
@@ -262,11 +262,11 @@ public class YogaLayout extends ViewGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
final YogaNode parent = node.getParent();
|
||||
final YogaNode owner = node.getOwner();
|
||||
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
if (parent.getChildAt(i).equals(node)) {
|
||||
parent.removeChildAt(i);
|
||||
for (int i = 0; i < owner.getChildCount(); i++) {
|
||||
if (owner.getChildAt(i).equals(node)) {
|
||||
owner.removeChildAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -315,7 +315,7 @@ public class YogaLayout extends ViewGroup {
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
// Either we are a root of a tree, or this function is called by our parent's onLayout, in which
|
||||
// Either we are a root of a tree, or this function is called by our owner's onLayout, in which
|
||||
// case our r-l and b-t are the size of our node.
|
||||
if (!(getParent() instanceof YogaLayout)) {
|
||||
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
|
||||
* the {@code yoga:width} and {@code yoga:height} if we are given them explicitly. If other
|
||||
* options (such as {@code match_parent} or {@code wrap_content} are given, then the parent
|
||||
* options (such as {@code match_owner} or {@code wrap_content} are given, then the owner
|
||||
* LayoutParams will store them, and we deal with them during layout. (see
|
||||
* {@link YogaLayout#createLayout})
|
||||
*
|
||||
@@ -773,9 +773,9 @@ public class YogaLayout extends ViewGroup {
|
||||
* {@code View}'s measure function.
|
||||
*
|
||||
* @param node The yoga node to measure
|
||||
* @param width The suggested width from the parent
|
||||
* @param width The suggested width from the owner
|
||||
* @param widthMode The type of suggestion for the width
|
||||
* @param height The suggested height from the parent
|
||||
* @param height The suggested height from the owner
|
||||
* @param heightMode The type of suggestion for the height
|
||||
* @return A measurement output ({@code YogaMeasureOutput}) for the node
|
||||
*/
|
||||
|
@@ -227,19 +227,31 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\yoga\Yoga.h" />
|
||||
<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\YGNodeList.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="resource.h" />
|
||||
<ClInclude Include="YGInterop.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\yoga\Yoga.c" />
|
||||
<ClCompile Include="..\..\yoga\YGEnums.c" />
|
||||
<ClCompile Include="..\..\yoga\YGNodeList.c" />
|
||||
<ClCompile Include="..\..\yoga\Utils.cpp" />
|
||||
<ClCompile Include="..\..\yoga\YGConfig.cpp" />
|
||||
<ClCompile Include="..\..\yoga\YGEnums.cpp" />
|
||||
<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="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
|
@@ -21,19 +21,40 @@
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\yoga\Yoga.h">
|
||||
<ClInclude Include="resource.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>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\yoga\YGMacros.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\yoga\YGNodeList.h">
|
||||
<ClInclude Include="..\..\yoga\YGNode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="YGInterop.h">
|
||||
<ClInclude Include="..\..\yoga\YGNodePrint.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<ClInclude Include="..\..\yoga\YGStyle.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>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
@@ -44,15 +65,36 @@
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</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">
|
||||
<Filter>Source Files</Filter>
|
||||
</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>
|
||||
<ResourceCompile Include="Yoga.rc">
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
|
||||
VERSION_NAME=1.7.1-SNAPSHOT
|
||||
VERSION_NAME=1.8.0
|
||||
POM_URL=https://github.com/facebook/yoga
|
||||
POM_SCM_URL=https://github.com/facebook/yoga.git
|
||||
POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git
|
||||
|
24
java/BUCK
24
java/BUCK
@@ -28,29 +28,6 @@ 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(
|
||||
name = "java",
|
||||
srcs = glob(["com/facebook/yoga/*.java"]),
|
||||
@@ -63,7 +40,6 @@ java_library(
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":jni",
|
||||
":jniFastMath",
|
||||
INFER_ANNOTATIONS_TARGET,
|
||||
JSR_305_TARGET,
|
||||
PROGRUARD_ANNOTATIONS_TARGET,
|
||||
|
@@ -16,16 +16,12 @@ public class YogaConfig {
|
||||
public static int SPACING_TYPE = 1;
|
||||
|
||||
static {
|
||||
if (YogaConstants.shouldUseFastMath) {
|
||||
SoLoader.loadLibrary("yogafastmath");
|
||||
} else {
|
||||
SoLoader.loadLibrary("yoga");
|
||||
}
|
||||
}
|
||||
|
||||
long mNativePointer;
|
||||
private YogaLogger mLogger;
|
||||
private YogaNodeClonedFunction mNodeClonedFunction;
|
||||
private YogaNodeCloneFunction mYogaNodeCloneFunction;
|
||||
|
||||
private native long jni_YGConfigNew();
|
||||
public YogaConfig() {
|
||||
@@ -97,16 +93,15 @@ public class YogaConfig {
|
||||
return mLogger;
|
||||
}
|
||||
|
||||
private native void jni_YGConfigSetHasNodeClonedFunc(long nativePointer, boolean hasClonedFunc);
|
||||
private native void jni_YGConfigSetHasCloneNodeFunc(long nativePointer, boolean hasClonedFunc);
|
||||
|
||||
public void setOnNodeCloned(YogaNodeClonedFunction nodeClonedFunction) {
|
||||
mNodeClonedFunction = nodeClonedFunction;
|
||||
jni_YGConfigSetHasNodeClonedFunc(mNativePointer, nodeClonedFunction != null);
|
||||
public void setOnCloneNode(YogaNodeCloneFunction cloneYogaNodeFunction) {
|
||||
mYogaNodeCloneFunction = cloneYogaNodeFunction;
|
||||
jni_YGConfigSetHasCloneNodeFunc(mNativePointer, cloneYogaNodeFunction != null);
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
public final void onNodeCloned(
|
||||
YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
|
||||
mNodeClonedFunction.onNodeCloned(oldNode, newNode, parent, childIndex);
|
||||
private final YogaNode cloneNode(YogaNode oldNode, YogaNode parent, int childIndex) {
|
||||
return mYogaNodeCloneFunction.cloneNode(oldNode, parent, childIndex);
|
||||
}
|
||||
}
|
||||
|
@@ -18,8 +18,6 @@ public class YogaConstants {
|
||||
*/
|
||||
public static final float UNDEFINED = (float) (10E20);
|
||||
|
||||
public static boolean shouldUseFastMath = false;
|
||||
|
||||
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,
|
||||
// the benefit of which
|
||||
|
@@ -17,20 +17,16 @@ import javax.annotation.Nullable;
|
||||
public class YogaNode implements Cloneable {
|
||||
|
||||
static {
|
||||
if (YogaConstants.shouldUseFastMath) {
|
||||
SoLoader.loadLibrary("yogafastmath");
|
||||
} else {
|
||||
SoLoader.loadLibrary("yoga");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get native instance count. Useful for testing only.
|
||||
*/
|
||||
static native int jni_YGNodeGetInstanceCount();
|
||||
|
||||
private YogaNode mParent;
|
||||
private List<YogaNode> mChildren;
|
||||
private YogaNode mOwner;
|
||||
@Nullable private List<YogaNode> mChildren;
|
||||
private YogaMeasureFunction mMeasureFunction;
|
||||
private YogaBaselineFunction mBaselineFunction;
|
||||
private long mNativePointer;
|
||||
@@ -147,12 +143,15 @@ public class YogaNode implements Cloneable {
|
||||
}
|
||||
|
||||
public YogaNode getChildAt(int i) {
|
||||
if (mChildren == null) {
|
||||
throw new IllegalStateException("YogaNode does not have children");
|
||||
}
|
||||
return mChildren.get(i);
|
||||
}
|
||||
|
||||
private native void jni_YGNodeInsertChild(long nativePointer, long childPointer, int index);
|
||||
public void addChildAt(YogaNode child, int i) {
|
||||
if (child.mParent != null) {
|
||||
if (child.mOwner != null) {
|
||||
throw new IllegalStateException("Child already has a parent, it must be removed first.");
|
||||
}
|
||||
|
||||
@@ -160,35 +159,84 @@ public class YogaNode implements Cloneable {
|
||||
mChildren = new ArrayList<>(4);
|
||||
}
|
||||
mChildren.add(i, child);
|
||||
child.mParent = this;
|
||||
child.mOwner = this;
|
||||
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);
|
||||
|
||||
@Override
|
||||
public YogaNode clone() throws CloneNotSupportedException {
|
||||
public YogaNode clone() {
|
||||
try {
|
||||
YogaNode clonedYogaNode = (YogaNode) super.clone();
|
||||
long clonedNativePointer = jni_YGNodeClone(mNativePointer, clonedYogaNode);
|
||||
clonedYogaNode.mNativePointer = clonedNativePointer;
|
||||
clonedYogaNode.mOwner = null;
|
||||
clonedYogaNode.mChildren =
|
||||
mChildren != null ? (List<YogaNode>) ((ArrayList) mChildren).clone() : null;
|
||||
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);
|
||||
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);
|
||||
child.mParent = null;
|
||||
child.mOwner = null;
|
||||
jni_YGNodeRemoveChild(mNativePointer, child.mNativePointer);
|
||||
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
|
||||
public
|
||||
YogaNode getParent() {
|
||||
return mParent;
|
||||
YogaNode getOwner() {
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
public int indexOf(YogaNode child) {
|
||||
@@ -697,4 +745,22 @@ public class YogaNode implements Cloneable {
|
||||
public void print() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -10,8 +10,8 @@ package com.facebook.yoga;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
@DoNotStrip
|
||||
public interface YogaNodeClonedFunction {
|
||||
public interface YogaNodeCloneFunction {
|
||||
|
||||
@DoNotStrip
|
||||
void onNodeCloned(YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex);
|
||||
YogaNode cloneNode(YogaNode oldNode, YogaNode parent, int childIndex);
|
||||
}
|
@@ -142,31 +142,49 @@ static float YGJNIBaselineFunc(YGNodeRef node, float width, float height) {
|
||||
}
|
||||
}
|
||||
|
||||
static void YGJNIOnNodeClonedFunc(
|
||||
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));
|
||||
}
|
||||
|
||||
static YGNodeRef YGJNIOnNodeClonedFunc(
|
||||
YGNodeRef oldNode,
|
||||
YGNodeRef newNode,
|
||||
YGNodeRef parent,
|
||||
YGNodeRef owner,
|
||||
int childIndex) {
|
||||
auto config = oldNode->getConfig();
|
||||
if (!config) {
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static auto onNodeClonedFunc = findClassStatic("com/facebook/yoga/YogaConfig")
|
||||
->getMethod<void(
|
||||
->getMethod<alias_ref<JYogaNode>(
|
||||
local_ref<JYogaNode>,
|
||||
local_ref<JYogaNode>,
|
||||
local_ref<JYogaNode>,
|
||||
jint)>("onNodeCloned");
|
||||
jint)>("cloneNode");
|
||||
|
||||
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
|
||||
auto javaConfig = context->config;
|
||||
|
||||
onNodeClonedFunc(
|
||||
auto newNode = onNodeClonedFunc(
|
||||
javaConfig->get(),
|
||||
YGNodeJobject(oldNode)->lockLocal(),
|
||||
YGNodeJobject(newNode)->lockLocal(),
|
||||
YGNodeJobject(parent)->lockLocal(),
|
||||
YGNodeJobject(owner)->lockLocal(),
|
||||
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(
|
||||
@@ -234,14 +252,6 @@ static int YGJNILogFunc(const YGConfigRef config,
|
||||
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) {
|
||||
const YGNodeRef node = YGNodeNew();
|
||||
node->setContext(new weak_ref<jobject>(make_weak(thiz)));
|
||||
@@ -274,6 +284,11 @@ void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
|
||||
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) {
|
||||
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
|
||||
void* context = node->getContext();
|
||||
@@ -293,6 +308,15 @@ void jni_YGNodeInsertChild(alias_ref<jobject>, jlong nativePointer, jlong childP
|
||||
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) {
|
||||
YGNodeRemoveChild(_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
|
||||
}
|
||||
@@ -506,10 +530,10 @@ void jni_YGConfigSetUseLegacyStretchBehaviour(alias_ref<jobject>,
|
||||
YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour);
|
||||
}
|
||||
|
||||
void jni_YGConfigSetHasNodeClonedFunc(
|
||||
void jni_YGConfigSetHasCloneNodeFunc(
|
||||
alias_ref<jobject> thiz,
|
||||
jlong nativePointer,
|
||||
jboolean hasNodeClonedFunc) {
|
||||
jboolean hasCloneNodeFunc) {
|
||||
const YGConfigRef config = _jlong2YGConfigRef(nativePointer);
|
||||
auto context = reinterpret_cast<YGConfigContext*>(YGConfigGetContext(config));
|
||||
if (context && context->config) {
|
||||
@@ -517,15 +541,15 @@ void jni_YGConfigSetHasNodeClonedFunc(
|
||||
context->config = nullptr;
|
||||
}
|
||||
|
||||
if (hasNodeClonedFunc) {
|
||||
if (hasCloneNodeFunc) {
|
||||
if (!context) {
|
||||
context = new YGConfigContext();
|
||||
YGConfigSetContext(config, context);
|
||||
}
|
||||
context->config = new global_ref<jobject>(make_global(thiz));
|
||||
YGConfigSetNodeClonedFunc(config, YGJNIOnNodeClonedFunc);
|
||||
YGConfigSetCloneNodeFunc(config, YGJNIOnNodeClonedFunc);
|
||||
} else {
|
||||
YGConfigSetNodeClonedFunc(config, nullptr);
|
||||
YGConfigSetCloneNodeFunc(config, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,7 +591,9 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
|
||||
YGMakeNativeMethod(jni_YGNodeNewWithConfig),
|
||||
YGMakeNativeMethod(jni_YGNodeFree),
|
||||
YGMakeNativeMethod(jni_YGNodeReset),
|
||||
YGMakeNativeMethod(jni_YGNodeClearChildren),
|
||||
YGMakeNativeMethod(jni_YGNodeInsertChild),
|
||||
YGMakeNativeMethod(jni_YGNodeInsertSharedChild),
|
||||
YGMakeNativeMethod(jni_YGNodeRemoveChild),
|
||||
YGMakeNativeMethod(jni_YGNodeCalculateLayout),
|
||||
YGMakeNativeMethod(jni_YGNodeMarkDirty),
|
||||
@@ -652,7 +678,7 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
|
||||
YGMakeNativeMethod(jni_YGConfigSetPointScaleFactor),
|
||||
YGMakeNativeMethod(jni_YGConfigSetUseLegacyStretchBehaviour),
|
||||
YGMakeNativeMethod(jni_YGConfigSetLogger),
|
||||
YGMakeNativeMethod(jni_YGConfigSetHasNodeClonedFunc),
|
||||
YGMakeNativeMethod(jni_YGConfigSetHasCloneNodeFunc),
|
||||
YGMakeNativeMethod(
|
||||
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour),
|
||||
});
|
||||
|
@@ -10,6 +10,7 @@ package com.facebook.yoga;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@@ -251,16 +252,58 @@ public class YogaNodeTest {
|
||||
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
|
||||
public void testCloneNodeListener() throws Exception {
|
||||
final AtomicBoolean onNodeClonedExecuted = new AtomicBoolean(false);
|
||||
YogaConfig config = new YogaConfig();
|
||||
config.setOnNodeCloned(
|
||||
new YogaNodeClonedFunction() {
|
||||
config.setOnCloneNode(
|
||||
new YogaNodeCloneFunction() {
|
||||
@Override
|
||||
public void onNodeCloned(
|
||||
YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
|
||||
public YogaNode cloneNode(YogaNode oldNode, YogaNode owner, int childIndex) {
|
||||
onNodeClonedExecuted.set(true);
|
||||
return oldNode.clone();
|
||||
}
|
||||
});
|
||||
YogaNode root = new YogaNode(config);
|
||||
@@ -268,6 +311,7 @@ public class YogaNodeTest {
|
||||
root.setHeight(100f);
|
||||
YogaNode child0 = new YogaNode(config);
|
||||
root.addChildAt(child0, 0);
|
||||
child0.setWidth(50f);
|
||||
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
|
||||
// Force a clone to happen.
|
||||
@@ -276,20 +320,24 @@ public class YogaNodeTest {
|
||||
root2.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
|
||||
|
||||
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
|
||||
public void testOnNodeClonedLeak() throws Exception {
|
||||
YogaConfig config = new YogaConfig();
|
||||
config.setOnNodeCloned(
|
||||
new YogaNodeClonedFunction() {
|
||||
config.setOnCloneNode(
|
||||
new YogaNodeCloneFunction() {
|
||||
@Override
|
||||
public void onNodeCloned(
|
||||
YogaNode oldNode, YogaNode newNode, YogaNode parent, int childIndex) {
|
||||
// Do nothing
|
||||
public YogaNode cloneNode(YogaNode oldNode, YogaNode owner, int childIndex) {
|
||||
return oldNode.clone();
|
||||
}
|
||||
});
|
||||
config.setOnNodeCloned(null);
|
||||
config.setOnCloneNode(null);
|
||||
WeakReference<Object> ref = new WeakReference<Object>(config);
|
||||
// noinspection UnusedAssignment
|
||||
config = null;
|
||||
|
@@ -30,9 +30,9 @@ TEST(YogaTest, set_children_adds_children_to_parent) {
|
||||
const std::vector<YGNodeRef> expectedChildren = {root_child0, root_child1};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedParents = {root, root};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
const std::vector<YGNodeRef> owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedOwners = {root, root};
|
||||
ASSERT_EQ(owners, expectedOwners);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
@@ -49,9 +49,9 @@ TEST(YogaTest, set_children_to_empty_removes_old_children) {
|
||||
const std::vector<YGNodeRef> expectedChildren = {};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedParents = {nullptr, nullptr};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
const std::vector<YGNodeRef> owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedOwners = {nullptr, nullptr};
|
||||
ASSERT_EQ(owners, expectedOwners);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
}
|
||||
@@ -72,9 +72,9 @@ TEST(YogaTest, set_children_replaces_non_common_children) {
|
||||
const std::vector<YGNodeRef> expectedChildren = {root_child2, root_child3};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {YGNodeGetParent(root_child0), YGNodeGetParent(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedParents = {nullptr, nullptr};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
const std::vector<YGNodeRef> owners = {YGNodeGetOwner(root_child0), YGNodeGetOwner(root_child1)};
|
||||
const std::vector<YGNodeRef> expectedOwners = {nullptr, nullptr};
|
||||
ASSERT_EQ(owners, expectedOwners);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
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};
|
||||
ASSERT_EQ(children, expectedChildren);
|
||||
|
||||
const std::vector<YGNodeRef> parents = {
|
||||
YGNodeGetParent(root_child0),
|
||||
YGNodeGetParent(root_child1),
|
||||
YGNodeGetParent(root_child2),
|
||||
YGNodeGetParent(root_child3)
|
||||
const std::vector<YGNodeRef> owners = {
|
||||
YGNodeGetOwner(root_child0),
|
||||
YGNodeGetOwner(root_child1),
|
||||
YGNodeGetOwner(root_child2),
|
||||
YGNodeGetOwner(root_child3)
|
||||
};
|
||||
const std::vector<YGNodeRef> expectedParents = {nullptr, root, root, root};
|
||||
ASSERT_EQ(parents, expectedParents);
|
||||
const std::vector<YGNodeRef> expectedOwners = {nullptr, root, root, root};
|
||||
ASSERT_EQ(owners, expectedOwners);
|
||||
|
||||
YGNodeFreeRecursive(root);
|
||||
YGNodeFree(root_child0);
|
||||
|
@@ -58,8 +58,11 @@ float YGUnwrapFloatOptional(const YGFloatOptional& op) {
|
||||
return op.isUndefined() ? YGUndefined : op.getValue();
|
||||
}
|
||||
|
||||
bool YGFloatOptionalFloatEquals(
|
||||
const YGFloatOptional& optional,
|
||||
const float& val) {
|
||||
return YGUnwrapFloatOptional(optional) == val;
|
||||
YGFloatOptional YGFloatOptionalMax(
|
||||
const YGFloatOptional& op1,
|
||||
const YGFloatOptional& op2) {
|
||||
if (!op1.isUndefined() && !op2.isUndefined()) {
|
||||
return op1.getValue() > op2.getValue() ? op1 : op2;
|
||||
}
|
||||
return op1.isUndefined() ? op2 : op1;
|
||||
}
|
||||
|
25
yoga/Utils.h
25
yoga/Utils.h
@@ -40,12 +40,12 @@ struct YGCollectFlexItemsRowValues {
|
||||
float sizeConsumedOnCurrentLine;
|
||||
float totalFlexGrowFactors;
|
||||
float totalFlexShrinkScaledFactors;
|
||||
float endOfLineIndex;
|
||||
uint32_t endOfLineIndex;
|
||||
std::vector<YGNodeRef> relativeChildren;
|
||||
float remainingFreeSpace;
|
||||
// The size of the mainDim for the row after considering size, padding, margin
|
||||
// and border of flex items. This is used to calculate maxLineDim after going
|
||||
// through all the rows to decide on the main axis size of parent.
|
||||
// through all the rows to decide on the main axis size of owner.
|
||||
float mainDim;
|
||||
// The size of the crossDim for the row after considering size, padding,
|
||||
// margin and border of flex items. Used for calculating containers crossSize.
|
||||
@@ -65,6 +65,10 @@ bool YGFloatsEqual(const float a, const float b);
|
||||
// compiler flag.
|
||||
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
|
||||
// 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
|
||||
@@ -94,12 +98,6 @@ float YGFloatSanitize(const float& val);
|
||||
// TODO: Get rid off this function
|
||||
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(
|
||||
const YGFlexDirection flexDirection,
|
||||
const YGDirection direction);
|
||||
@@ -109,7 +107,7 @@ inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
|
||||
flexDirection == YGFlexDirectionRowReverse;
|
||||
}
|
||||
|
||||
inline YGFloatOptional YGResolveValue(const YGValue value, const float parentSize) {
|
||||
inline YGFloatOptional YGResolveValue(const YGValue value, const float ownerSize) {
|
||||
switch (value.unit) {
|
||||
case YGUnitUndefined:
|
||||
case YGUnitAuto:
|
||||
@@ -118,7 +116,7 @@ inline YGFloatOptional YGResolveValue(const YGValue value, const float parentSiz
|
||||
return YGFloatOptional(value.value);
|
||||
case YGUnitPercent:
|
||||
return YGFloatOptional(
|
||||
static_cast<float>(value.value * parentSize * 0.01));
|
||||
static_cast<float>(value.value * ownerSize * 0.01));
|
||||
}
|
||||
return YGFloatOptional();
|
||||
}
|
||||
@@ -142,8 +140,9 @@ inline YGFlexDirection YGResolveFlexDirection(
|
||||
return flexDirection;
|
||||
}
|
||||
|
||||
static inline float YGResolveValueMargin(
|
||||
static inline YGFloatOptional YGResolveValueMargin(
|
||||
const YGValue value,
|
||||
const float parentSize) {
|
||||
return value.unit == YGUnitAuto ? 0 : YGUnwrapFloatOptional(YGResolveValue(value, parentSize));
|
||||
const float ownerSize) {
|
||||
return value.unit == YGUnitAuto ? YGFloatOptional(0)
|
||||
: YGResolveValue(value, ownerSize);
|
||||
}
|
||||
|
19
yoga/YGConfig.cpp
Normal file
19
yoga/YGConfig.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* 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) {}
|
23
yoga/YGConfig.h
Normal file
23
yoga/YGConfig.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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);
|
||||
};
|
@@ -8,12 +8,21 @@
|
||||
#include "YGFloatOptional.h"
|
||||
#include <cstdlib>
|
||||
#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) {}
|
||||
|
||||
float YGFloatOptional::getValue() const {
|
||||
const float& YGFloatOptional::getValue() const {
|
||||
if (isUndefined_) {
|
||||
// Abort, accessing a value of an undefined float optional
|
||||
std::cerr << "Tried to get value of an undefined YGFloatOptional\n";
|
||||
@@ -27,6 +36,57 @@ void YGFloatOptional::setValue(const float& val) {
|
||||
isUndefined_ = false;
|
||||
}
|
||||
|
||||
bool YGFloatOptional::isUndefined() const {
|
||||
const bool& YGFloatOptional::isUndefined() const {
|
||||
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;
|
||||
}
|
||||
|
@@ -5,22 +5,35 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct YGFloatOptional {
|
||||
private:
|
||||
float value_;
|
||||
bool isUndefined_;
|
||||
|
||||
public:
|
||||
YGFloatOptional(const float& value);
|
||||
YGFloatOptional();
|
||||
explicit YGFloatOptional(const float& value);
|
||||
explicit YGFloatOptional();
|
||||
|
||||
// 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.
|
||||
// To check if float optional is defined, use `isUndefined()`.
|
||||
float getValue() const;
|
||||
const float& getValue() const;
|
||||
|
||||
// Sets the value of float optional, and thus isUndefined is assigned false.
|
||||
void setValue(const float& val);
|
||||
|
||||
bool isUndefined() const;
|
||||
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;
|
||||
};
|
||||
|
@@ -19,10 +19,10 @@ YGLayout::YGLayout()
|
||||
padding(),
|
||||
direction(YGDirectionInherit),
|
||||
computedFlexBasisGeneration(0),
|
||||
computedFlexBasis(YGUndefined),
|
||||
computedFlexBasis(YGFloatOptional()),
|
||||
hadOverflow(false),
|
||||
generationCount(0),
|
||||
lastParentDirection((YGDirection)-1),
|
||||
lastOwnerDirection((YGDirection)-1),
|
||||
nextCachedMeasurementsIndex(0),
|
||||
cachedMeasurements(),
|
||||
measuredDimensions(kYGDefaultDimensionValues),
|
||||
@@ -37,18 +37,15 @@ bool YGLayout::operator==(YGLayout layout) const {
|
||||
YGFloatArrayEqual(border, layout.border) &&
|
||||
YGFloatArrayEqual(padding, layout.padding) &&
|
||||
direction == layout.direction && hadOverflow == layout.hadOverflow &&
|
||||
lastParentDirection == layout.lastParentDirection &&
|
||||
lastOwnerDirection == layout.lastOwnerDirection &&
|
||||
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) {
|
||||
isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i];
|
||||
}
|
||||
|
||||
if (!YGFloatIsUndefined(computedFlexBasis) ||
|
||||
!YGFloatIsUndefined(layout.computedFlexBasis)) {
|
||||
isEqual = isEqual && (computedFlexBasis == layout.computedFlexBasis);
|
||||
}
|
||||
if (!YGFloatIsUndefined(measuredDimensions[0]) ||
|
||||
!YGFloatIsUndefined(layout.measuredDimensions[0])) {
|
||||
isEqual =
|
||||
|
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "YGFloatOptional.h"
|
||||
#include "Yoga-internal.h"
|
||||
|
||||
struct YGLayout {
|
||||
@@ -17,13 +18,13 @@ struct YGLayout {
|
||||
YGDirection direction;
|
||||
|
||||
uint32_t computedFlexBasisGeneration;
|
||||
float computedFlexBasis;
|
||||
YGFloatOptional computedFlexBasis;
|
||||
bool hadOverflow;
|
||||
|
||||
// Instead of recomputing the entire layout every single time, we
|
||||
// cache some information to break early when nothing changed
|
||||
uint32_t generationCount;
|
||||
YGDirection lastParentDirection;
|
||||
YGDirection lastOwnerDirection;
|
||||
|
||||
uint32_t nextCachedMeasurementsIndex;
|
||||
std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>
|
||||
|
202
yoga/YGNode.cpp
202
yoga/YGNode.cpp
@@ -49,8 +49,8 @@ uint32_t YGNode::getLineIndex() const {
|
||||
return lineIndex_;
|
||||
}
|
||||
|
||||
YGNodeRef YGNode::getParent() const {
|
||||
return parent_;
|
||||
YGNodeRef YGNode::getOwner() const {
|
||||
return owner_;
|
||||
}
|
||||
|
||||
YGVector YGNode::getChildren() const {
|
||||
@@ -85,14 +85,14 @@ std::array<YGValue, 2> YGNode::getResolvedDimensions() const {
|
||||
return resolvedDimensions_;
|
||||
}
|
||||
|
||||
float YGNode::getLeadingPosition(
|
||||
const YGFlexDirection axis,
|
||||
const float axisSize) const {
|
||||
YGFloatOptional YGNode::getLeadingPosition(
|
||||
const YGFlexDirection& axis,
|
||||
const float& axisSize) const {
|
||||
if (YGFlexDirectionIsRow(axis)) {
|
||||
const YGValue* leadingPosition =
|
||||
YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined);
|
||||
if (leadingPosition->unit != YGUnitUndefined) {
|
||||
return YGUnwrapFloatOptional(YGResolveValue(*leadingPosition, axisSize));
|
||||
return YGResolveValue(*leadingPosition, axisSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,18 +100,18 @@ float YGNode::getLeadingPosition(
|
||||
YGComputedEdgeValue(style_.position, leading[axis], &YGValueUndefined);
|
||||
|
||||
return leadingPosition->unit == YGUnitUndefined
|
||||
? 0.0f
|
||||
: YGUnwrapFloatOptional(YGResolveValue(*leadingPosition, axisSize));
|
||||
? YGFloatOptional(0)
|
||||
: YGResolveValue(*leadingPosition, axisSize);
|
||||
}
|
||||
|
||||
float YGNode::getTrailingPosition(
|
||||
const YGFlexDirection axis,
|
||||
const float axisSize) const {
|
||||
YGFloatOptional YGNode::getTrailingPosition(
|
||||
const YGFlexDirection& axis,
|
||||
const float& axisSize) const {
|
||||
if (YGFlexDirectionIsRow(axis)) {
|
||||
const YGValue* trailingPosition =
|
||||
YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined);
|
||||
if (trailingPosition->unit != YGUnitUndefined) {
|
||||
return YGUnwrapFloatOptional(YGResolveValue(*trailingPosition, axisSize));
|
||||
return YGResolveValue(*trailingPosition, axisSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,11 +119,11 @@ float YGNode::getTrailingPosition(
|
||||
YGComputedEdgeValue(style_.position, trailing[axis], &YGValueUndefined);
|
||||
|
||||
return trailingPosition->unit == YGUnitUndefined
|
||||
? 0.0f
|
||||
: YGUnwrapFloatOptional(YGResolveValue(*trailingPosition, axisSize));
|
||||
? YGFloatOptional(0)
|
||||
: YGResolveValue(*trailingPosition, axisSize);
|
||||
}
|
||||
|
||||
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
|
||||
bool YGNode::isLeadingPositionDefined(const YGFlexDirection& axis) const {
|
||||
return (YGFlexDirectionIsRow(axis) &&
|
||||
YGComputedEdgeValue(style_.position, YGEdgeStart, &YGValueUndefined)
|
||||
->unit != YGUnitUndefined) ||
|
||||
@@ -131,7 +131,7 @@ bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
|
||||
->unit != YGUnitUndefined;
|
||||
}
|
||||
|
||||
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
|
||||
bool YGNode::isTrailingPosDefined(const YGFlexDirection& axis) const {
|
||||
return (YGFlexDirectionIsRow(axis) &&
|
||||
YGComputedEdgeValue(style_.position, YGEdgeEnd, &YGValueUndefined)
|
||||
->unit != YGUnitUndefined) ||
|
||||
@@ -139,9 +139,9 @@ bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
|
||||
->unit != YGUnitUndefined;
|
||||
}
|
||||
|
||||
float YGNode::getLeadingMargin(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
YGFloatOptional YGNode::getLeadingMargin(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.margin[YGEdgeStart].unit != YGUnitUndefined) {
|
||||
return YGResolveValueMargin(style_.margin[YGEdgeStart], widthSize);
|
||||
@@ -152,9 +152,9 @@ float YGNode::getLeadingMargin(
|
||||
widthSize);
|
||||
}
|
||||
|
||||
float YGNode::getTrailingMargin(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
YGFloatOptional YGNode::getTrailingMargin(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.margin[YGEdgeEnd].unit != YGUnitUndefined) {
|
||||
return YGResolveValueMargin(style_.margin[YGEdgeEnd], widthSize);
|
||||
@@ -165,9 +165,9 @@ float YGNode::getTrailingMargin(
|
||||
widthSize);
|
||||
}
|
||||
|
||||
float YGNode::getMarginForAxis(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
YGFloatOptional YGNode::getMarginForAxis(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize);
|
||||
}
|
||||
|
||||
@@ -237,8 +237,8 @@ void YGNode::setLineIndex(uint32_t lineIndex) {
|
||||
lineIndex_ = lineIndex;
|
||||
}
|
||||
|
||||
void YGNode::setParent(YGNodeRef parent) {
|
||||
parent_ = parent;
|
||||
void YGNode::setOwner(YGNodeRef owner) {
|
||||
owner_ = owner;
|
||||
}
|
||||
|
||||
void YGNode::setChildren(const YGVector& children) {
|
||||
@@ -305,11 +305,12 @@ void YGNode::setLayoutPadding(float padding, int index) {
|
||||
layout_.padding[index] = padding;
|
||||
}
|
||||
|
||||
void YGNode::setLayoutLastParentDirection(YGDirection direction) {
|
||||
layout_.lastParentDirection = direction;
|
||||
void YGNode::setLayoutLastOwnerDirection(YGDirection direction) {
|
||||
layout_.lastOwnerDirection = direction;
|
||||
}
|
||||
|
||||
void YGNode::setLayoutComputedFlexBasis(float computedFlexBasis) {
|
||||
void YGNode::setLayoutComputedFlexBasis(
|
||||
const YGFloatOptional& computedFlexBasis) {
|
||||
layout_.computedFlexBasis = computedFlexBasis;
|
||||
}
|
||||
|
||||
@@ -336,41 +337,54 @@ void YGNode::setLayoutDimension(float dimension, int index) {
|
||||
|
||||
// If both left and right are defined, then use left. Otherwise return
|
||||
// +left or -right depending on which is defined.
|
||||
float YGNode::relativePosition(
|
||||
const YGFlexDirection axis,
|
||||
const float axisSize) {
|
||||
return isLeadingPositionDefined(axis) ? getLeadingPosition(axis, axisSize)
|
||||
: -getTrailingPosition(axis, axisSize);
|
||||
YGFloatOptional YGNode::relativePosition(
|
||||
const YGFlexDirection& axis,
|
||||
const float& axisSize) const {
|
||||
if (isLeadingPositionDefined(axis)) {
|
||||
return getLeadingPosition(axis, axisSize);
|
||||
}
|
||||
|
||||
YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize);
|
||||
if (!trailingPosition.isUndefined()) {
|
||||
trailingPosition.setValue(-1 * trailingPosition.getValue());
|
||||
}
|
||||
return trailingPosition;
|
||||
}
|
||||
|
||||
void YGNode::setPosition(
|
||||
const YGDirection direction,
|
||||
const float mainSize,
|
||||
const float crossSize,
|
||||
const float parentWidth) {
|
||||
const float ownerWidth) {
|
||||
/* Root nodes should be always layouted as LTR, so we don't return negative
|
||||
* values. */
|
||||
const YGDirection directionRespectingRoot =
|
||||
parent_ != nullptr ? direction : YGDirectionLTR;
|
||||
owner_ != nullptr ? direction : YGDirectionLTR;
|
||||
const YGFlexDirection mainAxis =
|
||||
YGResolveFlexDirection(style_.flexDirection, directionRespectingRoot);
|
||||
const YGFlexDirection crossAxis =
|
||||
YGFlexDirectionCross(mainAxis, directionRespectingRoot);
|
||||
|
||||
const float relativePositionMain = relativePosition(mainAxis, mainSize);
|
||||
const float relativePositionCross = relativePosition(crossAxis, crossSize);
|
||||
const YGFloatOptional relativePositionMain =
|
||||
relativePosition(mainAxis, mainSize);
|
||||
const YGFloatOptional relativePositionCross =
|
||||
relativePosition(crossAxis, crossSize);
|
||||
|
||||
setLayoutPosition(
|
||||
getLeadingMargin(mainAxis, parentWidth) + relativePositionMain,
|
||||
YGUnwrapFloatOptional(
|
||||
getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain),
|
||||
leading[mainAxis]);
|
||||
setLayoutPosition(
|
||||
getTrailingMargin(mainAxis, parentWidth) + relativePositionMain,
|
||||
YGUnwrapFloatOptional(
|
||||
getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain),
|
||||
trailing[mainAxis]);
|
||||
setLayoutPosition(
|
||||
getLeadingMargin(crossAxis, parentWidth) + relativePositionCross,
|
||||
YGUnwrapFloatOptional(
|
||||
getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross),
|
||||
leading[crossAxis]);
|
||||
setLayoutPosition(
|
||||
getTrailingMargin(crossAxis, parentWidth) + relativePositionCross,
|
||||
YGUnwrapFloatOptional(
|
||||
getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross),
|
||||
trailing[crossAxis]);
|
||||
}
|
||||
|
||||
@@ -385,7 +399,7 @@ YGNode::YGNode()
|
||||
style_(YGStyle()),
|
||||
layout_(YGLayout()),
|
||||
lineIndex_(0),
|
||||
parent_(nullptr),
|
||||
owner_(nullptr),
|
||||
children_(YGVector()),
|
||||
nextChild_(nullptr),
|
||||
config_(nullptr),
|
||||
@@ -403,7 +417,7 @@ YGNode::YGNode(const YGNode& node)
|
||||
style_(node.style_),
|
||||
layout_(node.layout_),
|
||||
lineIndex_(node.lineIndex_),
|
||||
parent_(node.parent_),
|
||||
owner_(node.owner_),
|
||||
children_(node.children_),
|
||||
nextChild_(node.nextChild_),
|
||||
config_(node.config_),
|
||||
@@ -425,7 +439,7 @@ YGNode::YGNode(
|
||||
YGStyle style,
|
||||
const YGLayout& layout,
|
||||
uint32_t lineIndex,
|
||||
YGNodeRef parent,
|
||||
YGNodeRef owner,
|
||||
const YGVector& children,
|
||||
YGNodeRef nextChild,
|
||||
YGConfigRef config,
|
||||
@@ -441,7 +455,7 @@ YGNode::YGNode(
|
||||
style_(style),
|
||||
layout_(layout),
|
||||
lineIndex_(lineIndex),
|
||||
parent_(parent),
|
||||
owner_(owner),
|
||||
children_(children),
|
||||
nextChild_(nextChild),
|
||||
config_(config),
|
||||
@@ -467,7 +481,7 @@ YGNode& YGNode::operator=(const YGNode& node) {
|
||||
style_ = node.style_;
|
||||
layout_ = node.layout_;
|
||||
lineIndex_ = node.getLineIndex();
|
||||
parent_ = node.getParent();
|
||||
owner_ = node.getOwner();
|
||||
children_ = node.getChildren();
|
||||
nextChild_ = node.getNextChild();
|
||||
config_ = node.getConfig();
|
||||
@@ -518,9 +532,9 @@ void YGNode::resolveDimension() {
|
||||
}
|
||||
}
|
||||
|
||||
YGDirection YGNode::resolveDirection(const YGDirection parentDirection) {
|
||||
YGDirection YGNode::resolveDirection(const YGDirection ownerDirection) {
|
||||
if (style_.direction == YGDirectionInherit) {
|
||||
return parentDirection > YGDirectionInherit ? parentDirection
|
||||
return ownerDirection > YGDirectionInherit ? ownerDirection
|
||||
: YGDirectionLTR;
|
||||
} else {
|
||||
return style_.direction;
|
||||
@@ -550,32 +564,35 @@ void YGNode::cloneChildrenIfNeeded() {
|
||||
}
|
||||
|
||||
const YGNodeRef firstChild = children_.front();
|
||||
if (firstChild->getParent() == this) {
|
||||
// If the first child has this node as its parent, we assume that it is
|
||||
if (firstChild->getOwner() == this) {
|
||||
// If the first child has this node as its owner, we assume that it is
|
||||
// already unique. We can do this because if we have it has a child, that
|
||||
// means that its parent was at some point cloned which made that subtree
|
||||
// means that its owner was at some point cloned which made that subtree
|
||||
// immutable. We also assume that all its sibling are cloned as well.
|
||||
return;
|
||||
}
|
||||
|
||||
const YGNodeClonedFunc cloneNodeCallback = config_->cloneNodeCallback;
|
||||
const YGCloneNodeFunc cloneNodeCallback = config_->cloneNodeCallback;
|
||||
for (uint32_t i = 0; i < childCount; ++i) {
|
||||
const YGNodeRef oldChild = children_[i];
|
||||
const YGNodeRef newChild = YGNodeClone(oldChild);
|
||||
replaceChild(newChild, i);
|
||||
newChild->setParent(this);
|
||||
YGNodeRef newChild = nullptr;
|
||||
if (cloneNodeCallback) {
|
||||
cloneNodeCallback(oldChild, newChild, this, i);
|
||||
newChild = cloneNodeCallback(oldChild, this, i);
|
||||
}
|
||||
if (newChild == nullptr) {
|
||||
newChild = YGNodeClone(oldChild);
|
||||
}
|
||||
replaceChild(newChild, i);
|
||||
newChild->setOwner(this);
|
||||
}
|
||||
}
|
||||
|
||||
void YGNode::markDirtyAndPropogate() {
|
||||
if (!isDirty_) {
|
||||
setDirty(true);
|
||||
setLayoutComputedFlexBasis(YGUndefined);
|
||||
if (parent_) {
|
||||
parent_->markDirtyAndPropogate();
|
||||
setLayoutComputedFlexBasis(YGFloatOptional());
|
||||
if (owner_) {
|
||||
owner_->markDirtyAndPropogate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -589,7 +606,7 @@ void YGNode::markDirtyAndPropogateDownwards() {
|
||||
|
||||
float YGNode::resolveFlexGrow() {
|
||||
// Root nodes flexGrow should always be 0
|
||||
if (parent_ == nullptr) {
|
||||
if (owner_ == nullptr) {
|
||||
return 0.0;
|
||||
}
|
||||
if (!style_.flexGrow.isUndefined()) {
|
||||
@@ -602,7 +619,7 @@ float YGNode::resolveFlexGrow() {
|
||||
}
|
||||
|
||||
float YGNode::resolveFlexShrink() {
|
||||
if (parent_ == nullptr) {
|
||||
if (owner_ == nullptr) {
|
||||
return 0.0;
|
||||
}
|
||||
if (!style_.flexShrink.isUndefined()) {
|
||||
@@ -621,7 +638,7 @@ bool YGNode::isNodeFlexible() {
|
||||
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
|
||||
}
|
||||
|
||||
float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
|
||||
float YGNode::getLeadingBorder(const YGFlexDirection& axis) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.border[YGEdgeStart].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(style_.border[YGEdgeStart].value) &&
|
||||
@@ -634,7 +651,7 @@ float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
|
||||
return YGFloatMax(computedEdgeValue, 0.0f);
|
||||
}
|
||||
|
||||
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
|
||||
float YGNode::getTrailingBorder(const YGFlexDirection& flexDirection) const {
|
||||
if (YGFlexDirectionIsRow(flexDirection) &&
|
||||
style_.border[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||
!YGFloatIsUndefined(style_.border[YGEdgeEnd].value) &&
|
||||
@@ -648,51 +665,52 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
|
||||
return YGFloatMax(computedEdgeValue, 0.0f);
|
||||
}
|
||||
|
||||
float YGNode::getLeadingPadding(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
YGFloatOptional YGNode::getLeadingPadding(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
const YGFloatOptional& paddingEdgeStart =
|
||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize);
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.padding[YGEdgeStart].unit != YGUnitUndefined &&
|
||||
!YGResolveValue(style_.padding[YGEdgeStart], widthSize).isUndefined() &&
|
||||
YGUnwrapFloatOptional(
|
||||
YGResolveValue(style_.padding[YGEdgeStart], widthSize)) > 0.0f) {
|
||||
return YGUnwrapFloatOptional(YGResolveValue(style_.padding[YGEdgeStart], widthSize));
|
||||
!paddingEdgeStart.isUndefined() && paddingEdgeStart.getValue() > 0.0f) {
|
||||
return paddingEdgeStart;
|
||||
}
|
||||
|
||||
float resolvedValue = YGUnwrapFloatOptional(YGResolveValue(
|
||||
YGFloatOptional resolvedValue = YGResolveValue(
|
||||
*YGComputedEdgeValue(style_.padding, leading[axis], &YGValueZero),
|
||||
widthSize));
|
||||
return YGFloatMax(resolvedValue, 0.0f);
|
||||
widthSize);
|
||||
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
|
||||
}
|
||||
|
||||
float YGNode::getTrailingPadding(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
YGFloatOptional YGNode::getTrailingPadding(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
if (YGFlexDirectionIsRow(axis) &&
|
||||
style_.padding[YGEdgeEnd].unit != YGUnitUndefined &&
|
||||
!YGResolveValue(style_.padding[YGEdgeEnd], widthSize).isUndefined() &&
|
||||
YGUnwrapFloatOptional(
|
||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize)) >= 0.0f) {
|
||||
return YGUnwrapFloatOptional(YGResolveValue(style_.padding[YGEdgeEnd], widthSize));
|
||||
YGResolveValue(style_.padding[YGEdgeEnd], widthSize).getValue() >= 0.0f) {
|
||||
return YGResolveValue(style_.padding[YGEdgeEnd], widthSize);
|
||||
}
|
||||
|
||||
float resolvedValue = YGUnwrapFloatOptional(YGResolveValue(
|
||||
YGFloatOptional resolvedValue = YGResolveValue(
|
||||
*YGComputedEdgeValue(style_.padding, trailing[axis], &YGValueZero),
|
||||
widthSize));
|
||||
widthSize);
|
||||
|
||||
return YGFloatMax(resolvedValue, 0.0f);
|
||||
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
|
||||
}
|
||||
|
||||
float YGNode::getLeadingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
return getLeadingPadding(axis, widthSize) + getLeadingBorder(axis);
|
||||
YGFloatOptional YGNode::getLeadingPaddingAndBorder(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
return getLeadingPadding(axis, widthSize) +
|
||||
YGFloatOptional(getLeadingBorder(axis));
|
||||
}
|
||||
|
||||
float YGNode::getTrailingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const {
|
||||
return getTrailingPadding(axis, widthSize) + getTrailingBorder(axis);
|
||||
YGFloatOptional YGNode::getTrailingPaddingAndBorder(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const {
|
||||
return getTrailingPadding(axis, widthSize) +
|
||||
YGFloatOptional(getTrailingBorder(axis));
|
||||
}
|
||||
|
||||
bool YGNode::didUseLegacyFlag() {
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include "YGConfig.h"
|
||||
#include "YGLayout.h"
|
||||
#include "YGStyle.h"
|
||||
#include "Yoga-internal.h"
|
||||
@@ -23,14 +24,16 @@ struct YGNode {
|
||||
YGStyle style_;
|
||||
YGLayout layout_;
|
||||
uint32_t lineIndex_;
|
||||
YGNodeRef parent_;
|
||||
YGNodeRef owner_;
|
||||
YGVector children_;
|
||||
YGNodeRef nextChild_;
|
||||
YGConfigRef config_;
|
||||
bool isDirty_;
|
||||
std::array<YGValue, 2> resolvedDimensions_;
|
||||
|
||||
float relativePosition(const YGFlexDirection axis, const float axisSize);
|
||||
YGFloatOptional relativePosition(
|
||||
const YGFlexDirection& axis,
|
||||
const float& axisSize) const;
|
||||
|
||||
public:
|
||||
YGNode();
|
||||
@@ -49,7 +52,7 @@ struct YGNode {
|
||||
YGStyle style,
|
||||
const YGLayout& layout,
|
||||
uint32_t lineIndex,
|
||||
YGNodeRef parent,
|
||||
YGNodeRef owner,
|
||||
const YGVector& children,
|
||||
YGNodeRef nextChild,
|
||||
YGConfigRef config,
|
||||
@@ -69,7 +72,12 @@ struct YGNode {
|
||||
// For Performance reasons passing as reference.
|
||||
YGLayout& getLayout();
|
||||
uint32_t getLineIndex() const;
|
||||
YGNodeRef getParent() const;
|
||||
// returns the YGNodeRef that owns this YGNode. An owner is used to identify
|
||||
// the YogaTree that a YGNode belongs to.
|
||||
// This method will return the parent of the YGNode when a YGNode only belongs
|
||||
// to one YogaTree or nullptr when the YGNode is shared between two or more
|
||||
// YogaTrees.
|
||||
YGNodeRef getOwner() const;
|
||||
YGVector getChildren() const;
|
||||
uint32_t getChildrenCount() const;
|
||||
YGNodeRef getChild(uint32_t index) const;
|
||||
@@ -80,23 +88,36 @@ struct YGNode {
|
||||
YGValue getResolvedDimension(int index);
|
||||
|
||||
// Methods related to positions, margin, padding and border
|
||||
float getLeadingPosition(const YGFlexDirection axis, const float axisSize) const;
|
||||
bool isLeadingPositionDefined(const YGFlexDirection axis) const;
|
||||
bool isTrailingPosDefined(const YGFlexDirection axis) const;
|
||||
float getTrailingPosition(const YGFlexDirection axis, const float axisSize) const;
|
||||
float getLeadingMargin(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getTrailingMargin(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getLeadingBorder(const YGFlexDirection flexDirection) const;
|
||||
float getTrailingBorder(const YGFlexDirection flexDirection) const;
|
||||
float getLeadingPadding(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getTrailingPadding(const YGFlexDirection axis, const float widthSize) const;
|
||||
float getLeadingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const;
|
||||
float getTrailingPaddingAndBorder(
|
||||
const YGFlexDirection axis,
|
||||
const float widthSize) const;
|
||||
float getMarginForAxis(const YGFlexDirection axis, const float widthSize) const;
|
||||
YGFloatOptional getLeadingPosition(const YGFlexDirection& axis,
|
||||
const float& axisSize) const;
|
||||
bool isLeadingPositionDefined(const YGFlexDirection& axis) const;
|
||||
bool isTrailingPosDefined(const YGFlexDirection& axis) const;
|
||||
YGFloatOptional getTrailingPosition(
|
||||
const YGFlexDirection& axis,
|
||||
const float& axisSize) const;
|
||||
YGFloatOptional getLeadingMargin(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const;
|
||||
YGFloatOptional getTrailingMargin(
|
||||
const YGFlexDirection& axis,
|
||||
const float& widthSize) const;
|
||||
float getLeadingBorder(const YGFlexDirection& flexDirection) const;
|
||||
float getTrailingBorder(const YGFlexDirection& flexDirection) const;
|
||||
YGFloatOptional getLeadingPadding(
|
||||
const YGFlexDirection& axis,
|
||||
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
|
||||
|
||||
void setContext(void* context);
|
||||
@@ -111,13 +132,13 @@ struct YGNode {
|
||||
void setStyleAlignContent(YGAlign alignContent);
|
||||
void setLayout(const YGLayout& layout);
|
||||
void setLineIndex(uint32_t lineIndex);
|
||||
void setParent(YGNodeRef parent);
|
||||
void setOwner(YGNodeRef owner);
|
||||
void setChildren(const YGVector& children);
|
||||
void setNextChild(YGNodeRef nextChild);
|
||||
void setConfig(YGConfigRef config);
|
||||
void setDirty(bool isDirty);
|
||||
void setLayoutLastParentDirection(YGDirection direction);
|
||||
void setLayoutComputedFlexBasis(float computedFlexBasis);
|
||||
void setLayoutLastOwnerDirection(YGDirection direction);
|
||||
void setLayoutComputedFlexBasis(const YGFloatOptional& computedFlexBasis);
|
||||
void setLayoutComputedFlexBasisGeneration(
|
||||
uint32_t computedFlexBasisGeneration);
|
||||
void setLayoutMeasuredDimension(float measuredDimension, int index);
|
||||
@@ -132,7 +153,7 @@ struct YGNode {
|
||||
const YGDirection direction,
|
||||
const float mainSize,
|
||||
const float crossSize,
|
||||
const float parentWidth);
|
||||
const float ownerWidth);
|
||||
void setAndPropogateUseLegacyFlag(bool useLegacyFlag);
|
||||
void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout);
|
||||
void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag);
|
||||
@@ -143,7 +164,7 @@ struct YGNode {
|
||||
YGValue marginTrailingValue(const YGFlexDirection axis) const;
|
||||
YGValue resolveFlexBasisPtr() const;
|
||||
void resolveDimension();
|
||||
YGDirection resolveDirection(const YGDirection parentDirection);
|
||||
YGDirection resolveDirection(const YGDirection ownerDirection);
|
||||
void clearChildren();
|
||||
/// Replaces the occurrences of oldChild with newChild
|
||||
void replaceChild(YGNodeRef oldChild, YGNodeRef newChild);
|
||||
|
@@ -9,7 +9,7 @@
|
||||
|
||||
const YGValue kYGValueUndefined = {0, YGUnitUndefined};
|
||||
|
||||
const YGValue kYGValueAuto = {YGUndefined, YGUnitAuto};
|
||||
const YGValue kYGValueAuto = {0, YGUnitAuto};
|
||||
|
||||
const std::array<YGValue, YGEdgeCount> kYGDefaultEdgeValuesUnit = {
|
||||
{kYGValueUndefined,
|
||||
@@ -42,7 +42,7 @@ YGStyle::YGStyle()
|
||||
flex(YGFloatOptional()),
|
||||
flexGrow(YGFloatOptional()),
|
||||
flexShrink(YGFloatOptional()),
|
||||
flexBasis({0, YGUnitAuto}),
|
||||
flexBasis(kYGValueAuto),
|
||||
margin(kYGDefaultEdgeValuesUnit),
|
||||
position(kYGDefaultEdgeValuesUnit),
|
||||
padding(kYGDefaultEdgeValuesUnit),
|
||||
@@ -50,7 +50,7 @@ YGStyle::YGStyle()
|
||||
dimensions(kYGDefaultDimensionValuesAutoUnit),
|
||||
minDimensions(kYGDefaultDimensionValuesUnit),
|
||||
maxDimensions(kYGDefaultDimensionValuesUnit),
|
||||
aspectRatio(YGUndefined) {}
|
||||
aspectRatio(YGFloatOptional()) {}
|
||||
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
bool YGStyle::operator==(const YGStyle& style) {
|
||||
@@ -91,10 +91,9 @@ bool YGStyle::operator==(const YGStyle& style) {
|
||||
flexShrink.getValue() == style.flexShrink.getValue();
|
||||
}
|
||||
|
||||
if (!(YGFloatIsUndefined(aspectRatio) &&
|
||||
YGFloatIsUndefined(style.aspectRatio))) {
|
||||
areNonFloatValuesEqual =
|
||||
areNonFloatValuesEqual && aspectRatio == style.aspectRatio;
|
||||
if (!(aspectRatio.isUndefined() && style.aspectRatio.isUndefined())) {
|
||||
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||
aspectRatio.getValue() == style.aspectRatio.getValue();
|
||||
}
|
||||
|
||||
return areNonFloatValuesEqual;
|
||||
|
@@ -32,7 +32,7 @@ struct YGStyle {
|
||||
std::array<YGValue, 2> dimensions;
|
||||
std::array<YGValue, 2> minDimensions;
|
||||
std::array<YGValue, 2> maxDimensions;
|
||||
float aspectRatio;
|
||||
YGFloatOptional aspectRatio;
|
||||
|
||||
YGStyle();
|
||||
// Yoga specific properties, not compatible with flexbox specification
|
||||
|
@@ -87,16 +87,6 @@ struct YGCachedMeasurement {
|
||||
// layouts should not require more than 16 entries to fit within the cache.
|
||||
#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 kDefaultFlexShrink = 0.0f;
|
||||
|
926
yoga/Yoga.cpp
926
yoga/Yoga.cpp
File diff suppressed because it is too large
Load Diff
34
yoga/Yoga.h
34
yoga/Yoga.h
@@ -62,10 +62,8 @@ typedef int (*YGLogger)(const YGConfigRef config,
|
||||
YGLogLevel level,
|
||||
const char *format,
|
||||
va_list args);
|
||||
typedef void (*YGNodeClonedFunc)(YGNodeRef oldNode,
|
||||
YGNodeRef newNode,
|
||||
YGNodeRef parent,
|
||||
int childIndex);
|
||||
typedef YGNodeRef (
|
||||
*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex);
|
||||
|
||||
// YGNode
|
||||
WIN_EXPORT YGNodeRef YGNodeNew(void);
|
||||
@@ -79,17 +77,31 @@ WIN_EXPORT int32_t YGNodeGetInstanceCount(void);
|
||||
WIN_EXPORT void YGNodeInsertChild(const YGNodeRef node,
|
||||
const YGNodeRef child,
|
||||
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 YGNodeRemoveAllChildren(const YGNodeRef node);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, const uint32_t index);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node);
|
||||
WIN_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node);
|
||||
WIN_EXPORT uint32_t YGNodeGetChildCount(const YGNodeRef node);
|
||||
WIN_EXPORT void YGNodeSetChildren(YGNodeRef const parent, const YGNodeRef children[], const uint32_t count);
|
||||
WIN_EXPORT void YGNodeSetChildren(
|
||||
YGNodeRef const owner,
|
||||
const YGNodeRef children[],
|
||||
const uint32_t count);
|
||||
|
||||
WIN_EXPORT void YGNodeCalculateLayout(const YGNodeRef node,
|
||||
const float availableWidth,
|
||||
const float availableHeight,
|
||||
const YGDirection parentDirection);
|
||||
const YGDirection ownerDirection);
|
||||
|
||||
// Mark a node as dirty. Only valid for nodes with a custom measure function
|
||||
// set.
|
||||
@@ -283,8 +295,8 @@ WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(const YGConfigRef config,
|
||||
WIN_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, const bool enabled);
|
||||
WIN_EXPORT bool YGConfigGetUseWebDefaults(const YGConfigRef config);
|
||||
|
||||
WIN_EXPORT void YGConfigSetNodeClonedFunc(const YGConfigRef config,
|
||||
const YGNodeClonedFunc callback);
|
||||
WIN_EXPORT void YGConfigSetCloneNodeFunc(const YGConfigRef config,
|
||||
const YGCloneNodeFunc callback);
|
||||
|
||||
// Export only for C#
|
||||
WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
|
||||
@@ -308,6 +320,8 @@ YG_EXTERN_C_END
|
||||
// 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 YGNodeSetChildren(YGNodeRef const parent, const std::vector<YGNodeRef> &children);
|
||||
extern void YGNodeSetChildren(
|
||||
YGNodeRef const owner,
|
||||
const std::vector<YGNodeRef>& children);
|
||||
|
||||
#endif
|
||||
|
@@ -32,6 +32,7 @@ BASE_COMPILER_FLAGS = [
|
||||
'-Wall',
|
||||
'-Werror',
|
||||
'-O3',
|
||||
'-ffast-math',
|
||||
]
|
||||
|
||||
LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [
|
||||
@@ -112,4 +113,3 @@ def prebuilt_jar(*args, **kwargs):
|
||||
|
||||
def is_apple_platform():
|
||||
return True
|
||||
|
||||
|
Reference in New Issue
Block a user