Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.facebook.react.uimanager

import android.graphics.Matrix
import com.facebook.react.bridge.NativeArray
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.ReadableType
Expand All @@ -28,6 +29,10 @@ internal object SkewMatrixHelper {
*/
@JvmStatic
fun isAffine2DTransformWithSkew(transforms: ReadableArray): Boolean {
// Read Fabric's arrays in C++ rather than crossing JNI for every element and key.
if (transforms is NativeArray) {
return TransformHelper.isAffine2DTransformWithSkew(transforms)
}
if (isRawMatrixShorthand(transforms)) {
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ public object TransformHelper {
return doubleArrayOf(newTranslateX, newTranslateY, newTranslateZ)
}

/** Native implementation of [SkewMatrixHelper.isAffine2DTransformWithSkew]. */
@JvmStatic
internal fun isAffine2DTransformWithSkew(transforms: NativeArray): Boolean =
nativeIsAffine2DTransformWithSkew(transforms)

@JvmStatic
private external fun nativeIsAffine2DTransformWithSkew(transforms: NativeArray): Boolean

@JvmStatic
private external fun nativeProcessTransform(
transforms: NativeArray,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,49 @@ void processTransform(
jResult->setRegion(0, MatrixSize, doubleTransform.data());
}

// Same result as SkewMatrixHelper.isAffine2DTransformWithSkew, but reads the
// array in place instead of crossing JNI for each element and key.
jboolean isAffine2DTransformWithSkew(
jni::alias_ref<jclass> /*unused*/,
NativeArray* jTransforms) {
const auto& transforms = jTransforms->getArray();
// The raw 16-element matrix shorthand used by Fabric LayoutAnimations.
if (transforms.size() == 16 && transforms[0].isNumber()) {
return JNI_FALSE;
}
bool hasSkewTransform = false;
for (const auto& transform : transforms) {
if (!transform.isObject() || transform.empty()) {
continue;
}
const auto& [key, value] = *transform.items().begin();
if (!key.isString()) {
continue;
}
const auto& type = key.getString();
if (type == "matrix" || type == "perspective" || type == "rotateX" ||
type == "rotateY") {
return JNI_FALSE;
}
if (type == "translate") {
if (value.isArray() && value.size() > 2 && value[2].isNumber() &&
value[2].asDouble() != 0.0) {
return JNI_FALSE;
}
} else if (type == "skewX" || type == "skewY") {
hasSkewTransform = true;
}
}
return hasSkewTransform ? JNI_TRUE : JNI_FALSE;
}

} // namespace

void TransformHelper::registerNatives() {
javaClassLocal()->registerNatives({
makeNativeMethod("nativeProcessTransform", processTransform),
makeNativeMethod(
"nativeIsAffine2DTransformWithSkew", isAffine2DTransformWithSkew),
});
}

Expand Down
Loading