diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.kt index c00957b14db0..9f09f26b09f9 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNative.kt @@ -311,6 +311,8 @@ public object YogaNative { @JvmStatic public external fun jni_YGNodeSetHasMeasureFuncJNI(nativePointer: Long, hasMeasureFunc: Boolean) + @JvmStatic public external fun jni_YGNodeSetNodeTypeJNI(nativePointer: Long, nodeType: Int) + @JvmStatic public external fun jni_YGNodeSetHasMinContentMeasureFuncJNI( nativePointer: Long, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.kt index 08b84232c855..754ed7a27913 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.kt @@ -228,6 +228,17 @@ public abstract class YogaNode : YogaProps { abstract override fun setMeasureFunction(measureFunction: YogaMeasureFunction?) + /** + * Sets the node type, which selects how layout is rounded to the pixel grid: a + * [YogaNodeType.TEXT] node's fractional size is rounded up and its position down, so its content + * is not truncated. [setMeasureFunction] sets it ([YogaNodeType.TEXT] for a function, + * [YogaNodeType.DEFAULT] for null), so call this after it. + * + * Does nothing by default, so a subclass built against an earlier [YogaNode] keeps working, with + * the rounding [setMeasureFunction] selected. + */ + public open fun setNodeType(nodeType: YogaNodeType) {} + abstract override fun setMinContentMeasureFunction(measureFunction: YogaMeasureFunction?) abstract override fun setMinContentWidth(minContentWidth: Float) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.kt index 484865c163db..9e2b1fe14e1b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/yoga/YogaNodeJNIBase.kt @@ -526,6 +526,10 @@ public abstract class YogaNodeJNIBase : YogaNode, Cloneable { YogaNative.jni_YGNodeSetHasMeasureFuncJNI(nativePointer, measureFunction != null) } + override fun setNodeType(nodeType: YogaNodeType) { + YogaNative.jni_YGNodeSetNodeTypeJNI(nativePointer, nodeType.intValue()) + } + override fun setMinContentMeasureFunction(measureFunction: YogaMeasureFunction?) { this.minContentMeasureFunction = measureFunction YogaNative.jni_YGNodeSetHasMinContentMeasureFuncJNI(nativePointer, measureFunction != null) diff --git a/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp b/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp index f720c2084062..d3d39a704c17 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.cpp @@ -685,6 +685,15 @@ static void jni_YGNodeSetHasMeasureFuncJNI( static_cast(hasMeasureFunc) ? YGJNIMeasureFunc : nullptr); } +static void jni_YGNodeSetNodeTypeJNI( + JNIEnv* /*env*/, + jobject /*obj*/, + jlong nativePointer, + jint nodeType) { + YGNodeSetNodeType( + _jlong2YGNodeRef(nativePointer), static_cast(nodeType)); +} + static YGSize YGJNIMinContentMeasureFunc( YGNodeConstRef node, float width, @@ -1139,6 +1148,7 @@ static JNINativeMethod methods[] = { "(JZ)V", (void*)jni_YGNodeSetHasMeasureFuncJNI}, // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast) + {"jni_YGNodeSetNodeTypeJNI", "(JI)V", (void*)jni_YGNodeSetNodeTypeJNI}, {"jni_YGNodeSetHasMinContentMeasureFuncJNI", "(JZ)V", (void*)jni_YGNodeSetHasMinContentMeasureFuncJNI},