@shopify/react-native-skia 0.1.119 → 0.1.122
Sign up to get free protection for your applications and to get access to all the features.
- package/android/CMakeLists.txt +30 -16
- package/android/build.gradle +81 -34
- package/android/src/main/java/com/shopify/reactnative/skia/PlatformContext.java +1 -1
- package/cpp/api/JsiSkApi.h +2 -0
- package/cpp/api/JsiSkColor.h +49 -0
- package/cpp/api/JsiSkPath.h +31 -2
- package/cpp/api/JsiSkPathFactory.h +96 -1
- package/cpp/api/third_party/CSSColorParser.h +324 -0
- package/cpp/rnskia/RNSkAnimation.h +4 -7
- package/cpp/rnskia/values/RNSkClockValue.h +4 -4
- package/cpp/rnskia/values/RNSkDerivedValue.h +1 -1
- package/cpp/rnskia/values/RNSkReadonlyValue.h +9 -15
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +3 -6
- package/ios/RNSkia-iOS/RNSkDrawViewImpl.mm +2 -4
- package/ios/RNSkia-iOS/SkiaDrawView.mm +3 -2
- package/lib/commonjs/renderer/components/shapes/Path.js +1 -1
- package/lib/commonjs/renderer/components/shapes/Path.js.map +1 -1
- package/lib/commonjs/renderer/nodes/Node.js +3 -3
- package/lib/commonjs/renderer/nodes/Node.js.map +1 -1
- package/lib/commonjs/skia/Color.js +3 -25
- package/lib/commonjs/skia/Color.js.map +1 -1
- package/lib/commonjs/skia/Image/Image.js.map +1 -1
- package/lib/commonjs/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
- package/lib/commonjs/skia/Paint/Paint.js.map +1 -1
- package/lib/commonjs/skia/Path/Path.js +13 -1
- package/lib/commonjs/skia/Path/Path.js.map +1 -1
- package/lib/commonjs/skia/Shader/Shader.js.map +1 -1
- package/lib/commonjs/skia/Skia.js +41 -3
- package/lib/commonjs/skia/Skia.js.map +1 -1
- package/lib/module/renderer/components/shapes/Path.js +1 -1
- package/lib/module/renderer/components/shapes/Path.js.map +1 -1
- package/lib/module/renderer/nodes/Node.js +3 -3
- package/lib/module/renderer/nodes/Node.js.map +1 -1
- package/lib/module/skia/Color.js +2 -21
- package/lib/module/skia/Color.js.map +1 -1
- package/lib/module/skia/Image/Image.js.map +1 -1
- package/lib/module/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
- package/lib/module/skia/Paint/Paint.js.map +1 -1
- package/lib/module/skia/Path/Path.js +11 -0
- package/lib/module/skia/Path/Path.js.map +1 -1
- package/lib/module/skia/Shader/Shader.js.map +1 -1
- package/lib/module/skia/Skia.js +43 -2
- package/lib/module/skia/Skia.js.map +1 -1
- package/lib/typescript/src/skia/Color.d.ts +0 -1
- package/lib/typescript/src/skia/Image/Image.d.ts +3 -3
- package/lib/typescript/src/skia/ImageFilter/ImageFilterFactory.d.ts +2 -2
- package/lib/typescript/src/skia/Paint/Paint.d.ts +2 -2
- package/lib/typescript/src/skia/Path/Path.d.ts +13 -0
- package/lib/typescript/src/skia/Path/PathFactory.d.ts +7 -1
- package/lib/typescript/src/skia/Picture/Picture.d.ts +2 -2
- package/lib/typescript/src/skia/RuntimeEffect/RuntimeEffect.d.ts +3 -3
- package/lib/typescript/src/skia/Shader/Shader.d.ts +2 -2
- package/lib/typescript/src/skia/Shader/ShaderFactory.d.ts +9 -9
- package/lib/typescript/src/skia/Skia.d.ts +5 -3
- package/package.json +1 -1
- package/scripts/install-npm.js +1 -1
- package/src/renderer/components/shapes/Path.tsx +1 -1
- package/src/renderer/nodes/Node.ts +3 -3
- package/src/skia/Color.ts +3 -20
- package/src/skia/Image/Image.ts +3 -3
- package/src/skia/ImageFilter/ImageFilterFactory.ts +2 -2
- package/src/skia/Paint/Paint.ts +2 -2
- package/src/skia/Path/Path.ts +16 -0
- package/src/skia/Path/PathFactory.ts +8 -1
- package/src/skia/Picture/Picture.ts +2 -2
- package/src/skia/RuntimeEffect/RuntimeEffect.ts +4 -4
- package/src/skia/Shader/Shader.ts +2 -2
- package/src/skia/Shader/ShaderFactory.ts +9 -9
- package/src/skia/Skia.ts +44 -3
package/android/CMakeLists.txt
CHANGED
@@ -10,12 +10,20 @@ set (SKIA_SVG_LIB "svg")
|
|
10
10
|
set (SKIA_SKSHAPER_LIB "skshaper")
|
11
11
|
|
12
12
|
set(build_DIR ${CMAKE_SOURCE_DIR}/build)
|
13
|
-
file
|
13
|
+
file(GLOB LIBRN_DIR "${PREBUILT_DIR}/${ANDROID_ABI}")
|
14
14
|
file(GLOB libfbjni_link_DIRS "${build_DIR}/fbjni*.aar/jni/${ANDROID_ABI}")
|
15
15
|
file(GLOB libfbjni_include_DIRS "${build_DIR}/fbjni-*-headers.jar/")
|
16
16
|
|
17
17
|
link_directories(../libs/android/${ANDROID_ABI}/)
|
18
18
|
|
19
|
+
if(${REACT_NATIVE_VERSION} LESS 66)
|
20
|
+
file(
|
21
|
+
TO_CMAKE_PATH
|
22
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp"
|
23
|
+
INCLUDE_JSI_CPP
|
24
|
+
)
|
25
|
+
endif()
|
26
|
+
|
19
27
|
add_library(
|
20
28
|
${PACKAGE_NAME}
|
21
29
|
SHARED
|
@@ -39,16 +47,10 @@ target_include_directories(
|
|
39
47
|
PRIVATE
|
40
48
|
|
41
49
|
# When installed in the development environment
|
42
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
46
|
-
|
47
|
-
# When installed as a package the paths are a bit different
|
48
|
-
"../../../react-native/ReactCommon/callinvoker"
|
49
|
-
"../../../react-native/ReactCommon/jsi"
|
50
|
-
"../../../react-native/ReactCommon/react/nativemodule/core"
|
51
|
-
"../../../react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
|
50
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
|
51
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
|
52
|
+
"${NODE_MODULES_DIR}/react-native/ReactCommon/react/nativemodule/core"
|
53
|
+
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
|
52
54
|
|
53
55
|
cpp/skia/include/config/
|
54
56
|
cpp/skia/include/core/
|
@@ -87,11 +89,23 @@ find_library(
|
|
87
89
|
)
|
88
90
|
|
89
91
|
find_library(
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
)
|
92
|
+
JSI_LIB
|
93
|
+
jsi
|
94
|
+
PATHS ${LIBRN_DIR}
|
95
|
+
NO_CMAKE_FIND_ROOT_PATH
|
96
|
+
)
|
97
|
+
if(${REACT_NATIVE_VERSION} LESS 66)
|
98
|
+
# JSI lib didn't exist on RN 0.65 and before. Simply omit it.
|
99
|
+
set (JSI_LIB "")
|
100
|
+
else()
|
101
|
+
# RN 0.66 distributes libjsi.so, can be used instead of compiling jsi.cpp manually.
|
102
|
+
find_library(
|
103
|
+
JSI_LIB
|
104
|
+
jsi
|
105
|
+
PATHS ${LIBRN_DIR}
|
106
|
+
NO_CMAKE_FIND_ROOT_PATH
|
107
|
+
)
|
108
|
+
endif()
|
95
109
|
|
96
110
|
find_library(
|
97
111
|
REACT_LIB
|
package/android/build.gradle
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import java.nio.file.Paths
|
2
|
+
|
1
3
|
// android/build.gradle
|
2
4
|
|
3
5
|
// based on:
|
@@ -26,6 +28,60 @@ def safeExtGet(prop, fallback) {
|
|
26
28
|
|
27
29
|
apply plugin: 'com.android.library'
|
28
30
|
|
31
|
+
static def findNodeModules(baseDir) {
|
32
|
+
def basePath = baseDir.toPath().normalize()
|
33
|
+
// Node's module resolution algorithm searches up to the root directory,
|
34
|
+
// after which the base path will be null
|
35
|
+
while (basePath) {
|
36
|
+
def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
|
37
|
+
def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
|
38
|
+
if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
|
39
|
+
return nodeModulesPath.toString()
|
40
|
+
}
|
41
|
+
basePath = basePath.getParent()
|
42
|
+
}
|
43
|
+
throw new GradleException("React-Native-Skia: Failed to find node_modules/ path!")
|
44
|
+
}
|
45
|
+
|
46
|
+
def nodeModules = findNodeModules(projectDir)
|
47
|
+
logger.warn("react-native-skia: node_modules/ found at: ${nodeModules}")
|
48
|
+
|
49
|
+
def sourceBuild = false
|
50
|
+
def defaultDir = null
|
51
|
+
def androidSourcesDir = null
|
52
|
+
def androidSourcesName = 'React Native sources'
|
53
|
+
|
54
|
+
if (rootProject.ext.has('reactNativeAndroidRoot')) {
|
55
|
+
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
|
56
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
57
|
+
} else if (findProject(':ReactAndroid') != null) {
|
58
|
+
sourceBuild = true
|
59
|
+
defaultDir = project(':ReactAndroid').projectDir
|
60
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
61
|
+
} else {
|
62
|
+
defaultDir = file("$nodeModules/react-native/android")
|
63
|
+
androidSourcesDir = defaultDir.parentFile.toString()
|
64
|
+
}
|
65
|
+
|
66
|
+
if (!defaultDir.exists()) {
|
67
|
+
throw new GradleException(
|
68
|
+
"${project.name}: React Native android directory (node_modules/react-native/android) does not exist! Resolved node_modules to: ${nodeModules}"
|
69
|
+
)
|
70
|
+
}
|
71
|
+
|
72
|
+
def prebuiltDir = sourceBuild
|
73
|
+
? "$nodeModules/react-native/ReactAndroid/src/main/jni/prebuilt/lib"
|
74
|
+
: "$buildDir/react-native-0*/jni"
|
75
|
+
|
76
|
+
|
77
|
+
def reactProperties = new Properties()
|
78
|
+
file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
|
79
|
+
def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
|
80
|
+
|
81
|
+
logger.warn("react-native-skia: React Native version: ${REACT_NATIVE_VERSION}")
|
82
|
+
logger.warn("react-native-skia: Is Source build: ${sourceBuild}")
|
83
|
+
logger.warn("react-native-skia: Prebuilt dir: ${prebuiltDir}")
|
84
|
+
|
29
85
|
buildscript {
|
30
86
|
// The Android Gradle plugin is only required when opening the android folder stand-alone.
|
31
87
|
// This avoids unnecessary downloads and potential conflicts when the library is included as a
|
@@ -56,7 +112,10 @@ android {
|
|
56
112
|
cmake {
|
57
113
|
cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
|
58
114
|
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
59
|
-
arguments '-DANDROID_STL=c++_shared'
|
115
|
+
arguments '-DANDROID_STL=c++_shared',
|
116
|
+
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
|
117
|
+
"-DNODE_MODULES_DIR=${nodeModules}",
|
118
|
+
"-DPREBUILT_DIR=${prebuiltDir}"
|
60
119
|
}
|
61
120
|
}
|
62
121
|
}
|
@@ -72,7 +131,13 @@ android {
|
|
72
131
|
}
|
73
132
|
|
74
133
|
packagingOptions {
|
75
|
-
excludes = [
|
134
|
+
excludes = [
|
135
|
+
"**/libc++_shared.so",
|
136
|
+
"**/libfbjni.so",
|
137
|
+
"**/libjsi.so",
|
138
|
+
"**/libreact_nativemodule_core.so",
|
139
|
+
"**/libturbomodulejsijni.so"
|
140
|
+
]
|
76
141
|
}
|
77
142
|
|
78
143
|
|
@@ -114,33 +179,6 @@ dependencies {
|
|
114
179
|
extractJNI(files(rnAAR))
|
115
180
|
}
|
116
181
|
|
117
|
-
def configureReactNativePom(def pom) {
|
118
|
-
def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text)
|
119
|
-
|
120
|
-
pom.project {
|
121
|
-
name packageJson.title
|
122
|
-
artifactId packageJson.name
|
123
|
-
version = packageJson.version
|
124
|
-
group = "com.shopify.reactnative.skia"
|
125
|
-
description packageJson.description
|
126
|
-
url packageJson.repository.baseUrl
|
127
|
-
|
128
|
-
licenses {
|
129
|
-
license {
|
130
|
-
name packageJson.license
|
131
|
-
url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename
|
132
|
-
distribution 'repo'
|
133
|
-
}
|
134
|
-
}
|
135
|
-
|
136
|
-
developers {
|
137
|
-
developer {
|
138
|
-
name packageJson.author
|
139
|
-
}
|
140
|
-
}
|
141
|
-
}
|
142
|
-
}
|
143
|
-
|
144
182
|
afterEvaluate { project ->
|
145
183
|
task androidSourcesJar(type: Jar) {
|
146
184
|
classifier = 'sources'
|
@@ -188,9 +226,18 @@ task extractJNIFiles {
|
|
188
226
|
}
|
189
227
|
}
|
190
228
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
229
|
+
extractJNIFiles.mustRunAfter extractAARHeaders
|
230
|
+
|
231
|
+
def nativeBuildDependsOn(dependsOnTask, variant) {
|
232
|
+
def buildTasks = tasks.findAll({ task ->
|
233
|
+
!task.name.contains("Clean") && (task.name.contains("externalNative") || task.name.contains("CMake")) })
|
234
|
+
if (variant != null) {
|
235
|
+
buildTasks = buildTasks.findAll({ task -> task.name.contains(variant) })
|
236
|
+
}
|
237
|
+
buildTasks.forEach { task -> task.dependsOn(dependsOnTask) }
|
196
238
|
}
|
239
|
+
|
240
|
+
afterEvaluate {
|
241
|
+
nativeBuildDependsOn(extractAARHeaders, null)
|
242
|
+
nativeBuildDependsOn(extractJNIFiles, null)
|
243
|
+
}
|
@@ -66,7 +66,7 @@ public class PlatformContext {
|
|
66
66
|
Choreographer.getInstance().postFrameCallback(frameCallback);
|
67
67
|
}
|
68
68
|
|
69
|
-
public void raise(String message) {
|
69
|
+
public void raise(final String message) {
|
70
70
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
71
71
|
@Override
|
72
72
|
public void run() {
|
package/cpp/api/JsiSkApi.h
CHANGED
@@ -39,6 +39,7 @@
|
|
39
39
|
#include "JsiSkContourMeasureIter.h"
|
40
40
|
#include "JsiSkPictureRecorder.h"
|
41
41
|
#include "JsiSkPictureFactory.h"
|
42
|
+
#include "JsiSkColor.h"
|
42
43
|
|
43
44
|
namespace RNSkia
|
44
45
|
{
|
@@ -67,6 +68,7 @@ namespace RNSkia
|
|
67
68
|
installFunction("ContourMeasureIter", JsiSkContourMeasureIter::createCtor(context));
|
68
69
|
installFunction("MakeVertices", JsiSkVertices::createCtor(context));
|
69
70
|
installFunction("PictureRecorder", JsiSkPictureRecorder::createCtor(context));
|
71
|
+
installFunction("parseColorString", JsiSkColor::createCtor());
|
70
72
|
|
71
73
|
// Static members
|
72
74
|
installReadonlyProperty("FontMgr",
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <memory>
|
4
|
+
#include <utility>
|
5
|
+
|
6
|
+
#include <jsi/jsi.h>
|
7
|
+
|
8
|
+
#include "JsiSkHostObjects.h"
|
9
|
+
#include "third_party/CSSColorParser.h"
|
10
|
+
|
11
|
+
#pragma clang diagnostic push
|
12
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
13
|
+
|
14
|
+
#include <SkColor.h>
|
15
|
+
|
16
|
+
#pragma clang diagnostic pop
|
17
|
+
|
18
|
+
namespace RNSkia {
|
19
|
+
|
20
|
+
using namespace facebook;
|
21
|
+
|
22
|
+
class JsiSkColor : public JsiHostObject {
|
23
|
+
public:
|
24
|
+
|
25
|
+
JsiSkColor(): JsiHostObject() {}
|
26
|
+
|
27
|
+
~JsiSkColor() {}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Creates the function for construction a new instance of the SkColor
|
31
|
+
* wrapper
|
32
|
+
* @return A function for creating a new host object wrapper for the SkColor
|
33
|
+
* class
|
34
|
+
*/
|
35
|
+
static const jsi::HostFunctionType
|
36
|
+
createCtor() {
|
37
|
+
return JSI_HOST_FUNCTION_LAMBDA {
|
38
|
+
auto text = arguments[0].asString(runtime).utf8(runtime);
|
39
|
+
auto color = CSSColorParser::parse(text);
|
40
|
+
if (color.a == -1.0f) {
|
41
|
+
return jsi::Value::undefined();
|
42
|
+
}
|
43
|
+
int a = round(color.a * 255);
|
44
|
+
// Because JS numbers are unsigned we need to do this conversion
|
45
|
+
return jsi::Value(static_cast<double>(SkColorSetARGB(a, color.r, color.g, color.b) >> 0));
|
46
|
+
};
|
47
|
+
}
|
48
|
+
};
|
49
|
+
} // namespace RNSkia
|
package/cpp/api/JsiSkPath.h
CHANGED
@@ -29,9 +29,9 @@ namespace RNSkia {
|
|
29
29
|
|
30
30
|
using namespace facebook;
|
31
31
|
|
32
|
+
|
32
33
|
class JsiSkPath : public JsiSkWrappingSharedPtrHostObject<SkPath> {
|
33
34
|
public:
|
34
|
-
|
35
35
|
// TODO: declare in JsiSkWrappingSkPtrHostObject via extra template parameter?
|
36
36
|
JSI_PROPERTY_GET(__typename__) {
|
37
37
|
return jsi::String::createFromUtf8(runtime, "Path");
|
@@ -484,6 +484,33 @@ public:
|
|
484
484
|
runtime, std::make_shared<JsiSkPath>(getContext(), std::move(result)));
|
485
485
|
}
|
486
486
|
|
487
|
+
JSI_HOST_FUNCTION(toCmds) {
|
488
|
+
auto path = *getObject();
|
489
|
+
auto cmds = jsi::Array(runtime, path.countVerbs());
|
490
|
+
auto it = SkPath::Iter(path, false);
|
491
|
+
// { "Move", "Line", "Quad", "Conic", "Cubic", "Close", "Done" };
|
492
|
+
const int pointCount[] = { 1 , 2 , 3 , 3 , 4 , 1 , 0 };
|
493
|
+
const int cmdCount[] = { 3 , 5 , 7 , 8 , 9 , 3 , 0 };
|
494
|
+
SkPoint points[4];
|
495
|
+
SkPath::Verb verb;
|
496
|
+
auto k = 0;
|
497
|
+
while (SkPath::kDone_Verb != (verb = it.next(points))) {
|
498
|
+
auto verbVal = static_cast<int>(verb);
|
499
|
+
auto cmd = jsi::Array(runtime, cmdCount[verbVal]);
|
500
|
+
auto j = 0;
|
501
|
+
cmd.setValueAtIndex(runtime, j++, jsi::Value(verbVal));
|
502
|
+
for (int i = 0; i < pointCount[verbVal]; ++i) {
|
503
|
+
cmd.setValueAtIndex(runtime, j++, jsi::Value(static_cast<double>(points[i].fX)));
|
504
|
+
cmd.setValueAtIndex(runtime, j++, jsi::Value(static_cast<double>(points[i].fY)));
|
505
|
+
}
|
506
|
+
if (SkPath::kConic_Verb == verb) {
|
507
|
+
cmd.setValueAtIndex(runtime, j, jsi::Value(static_cast<double>(it.conicWeight())));
|
508
|
+
}
|
509
|
+
cmds.setValueAtIndex(runtime, k++, cmd);
|
510
|
+
}
|
511
|
+
return cmds;
|
512
|
+
}
|
513
|
+
|
487
514
|
JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkPath, __typename__))
|
488
515
|
|
489
516
|
JSI_EXPORT_FUNCTIONS(
|
@@ -518,7 +545,9 @@ public:
|
|
518
545
|
JSI_EXPORT_FUNC(JsiSkPath, simplify),
|
519
546
|
JSI_EXPORT_FUNC(JsiSkPath, countPoints), JSI_EXPORT_FUNC(JsiSkPath, copy),
|
520
547
|
JSI_EXPORT_FUNC(JsiSkPath, fromText), JSI_EXPORT_FUNC(JsiSkPath, op),
|
521
|
-
JSI_EXPORT_FUNC(JsiSkPath, isInterpolatable),
|
548
|
+
JSI_EXPORT_FUNC(JsiSkPath, isInterpolatable),
|
549
|
+
JSI_EXPORT_FUNC(JsiSkPath, interpolate),
|
550
|
+
JSI_EXPORT_FUNC(JsiSkPath, toCmds),
|
522
551
|
)
|
523
552
|
|
524
553
|
JsiSkPath(std::shared_ptr<RNSkPlatformContext> context, SkPath path)
|
@@ -13,6 +13,7 @@
|
|
13
13
|
|
14
14
|
#include <SkPath.h>
|
15
15
|
#include <SkPathOps.h>
|
16
|
+
#include <RNSkLog.h>
|
16
17
|
|
17
18
|
#pragma clang diagnostic pop
|
18
19
|
|
@@ -21,6 +22,14 @@ namespace RNSkia {
|
|
21
22
|
using namespace facebook;
|
22
23
|
|
23
24
|
class JsiSkPathFactory : public JsiSkHostObject {
|
25
|
+
|
26
|
+
static const int MOVE = 0;
|
27
|
+
static const int LINE = 1;
|
28
|
+
static const int QUAD = 2;
|
29
|
+
static const int CONIC = 3;
|
30
|
+
static const int CUBIC = 4;
|
31
|
+
static const int CLOSE = 5;
|
32
|
+
|
24
33
|
public:
|
25
34
|
JSI_HOST_FUNCTION(Make) {
|
26
35
|
return jsi::Object::createFromHostObject(
|
@@ -53,9 +62,95 @@ public:
|
|
53
62
|
runtime, std::make_shared<JsiSkPath>(getContext(), std::move(result)));
|
54
63
|
}
|
55
64
|
|
65
|
+
JSI_HOST_FUNCTION(MakeFromCmds) {
|
66
|
+
SkPath path;
|
67
|
+
auto cmds = arguments[0].asObject(runtime).asArray(runtime);
|
68
|
+
auto cmdCount = cmds.size(runtime);
|
69
|
+
for (int i = 0; i < cmdCount; i++) {
|
70
|
+
auto cmd = cmds.getValueAtIndex(runtime, i).asObject(runtime).asArray(runtime);
|
71
|
+
if (cmd.size(runtime) < 1) {
|
72
|
+
RNSkLogger::logToConsole("Invalid command found (got an empty array)");
|
73
|
+
return jsi::Value::null();
|
74
|
+
}
|
75
|
+
auto verb = static_cast<int>(cmd.getValueAtIndex(runtime, 0).asNumber());
|
76
|
+
switch (verb) {
|
77
|
+
case MOVE: {
|
78
|
+
if (cmd.size(runtime) < 3) {
|
79
|
+
RNSkLogger::logToConsole( "Invalid move command found");
|
80
|
+
return jsi::Value::null();
|
81
|
+
}
|
82
|
+
auto x = cmd.getValueAtIndex(runtime, 1).asNumber();
|
83
|
+
auto y = cmd.getValueAtIndex(runtime, 2).asNumber();
|
84
|
+
path.moveTo(x, y);
|
85
|
+
break;
|
86
|
+
}
|
87
|
+
case LINE: {
|
88
|
+
if (cmd.size(runtime) < 3) {
|
89
|
+
RNSkLogger::logToConsole("Invalid line command found");
|
90
|
+
return jsi::Value::null();
|
91
|
+
}
|
92
|
+
auto x = cmd.getValueAtIndex(runtime, 1).asNumber();
|
93
|
+
auto y = cmd.getValueAtIndex(runtime, 2).asNumber();
|
94
|
+
path.lineTo(x, y);
|
95
|
+
break;
|
96
|
+
}
|
97
|
+
case QUAD: {
|
98
|
+
if (cmd.size(runtime) < 5) {
|
99
|
+
RNSkLogger::logToConsole("Invalid line command found");
|
100
|
+
return jsi::Value::null();
|
101
|
+
}
|
102
|
+
auto x1 = cmd.getValueAtIndex(runtime, 1).asNumber();
|
103
|
+
auto y1 = cmd.getValueAtIndex(runtime, 2).asNumber();
|
104
|
+
auto x2 = cmd.getValueAtIndex(runtime, 3).asNumber();
|
105
|
+
auto y2 = cmd.getValueAtIndex(runtime, 4).asNumber();
|
106
|
+
path.quadTo(x1, y1, x2, y2);
|
107
|
+
break;
|
108
|
+
}
|
109
|
+
case CONIC: {
|
110
|
+
if (cmd.size(runtime) < 6) {
|
111
|
+
RNSkLogger::logToConsole("Invalid line command found");
|
112
|
+
return jsi::Value::null();
|
113
|
+
}
|
114
|
+
auto x1 = cmd.getValueAtIndex(runtime, 1).asNumber();
|
115
|
+
auto y1 = cmd.getValueAtIndex(runtime, 2).asNumber();
|
116
|
+
auto x2 = cmd.getValueAtIndex(runtime, 3).asNumber();
|
117
|
+
auto y2 = cmd.getValueAtIndex(runtime, 4).asNumber();
|
118
|
+
auto w = cmd.getValueAtIndex(runtime, 5).asNumber();
|
119
|
+
path.conicTo(x1, y1, x2, y2, w);
|
120
|
+
break;
|
121
|
+
}
|
122
|
+
case CUBIC: {
|
123
|
+
if (cmd.size(runtime) < 7) {
|
124
|
+
RNSkLogger::logToConsole("Invalid line command found");
|
125
|
+
return jsi::Value::null();
|
126
|
+
}
|
127
|
+
auto x1 = cmd.getValueAtIndex(runtime, 1).asNumber();
|
128
|
+
auto y1 = cmd.getValueAtIndex(runtime, 2).asNumber();
|
129
|
+
auto x2 = cmd.getValueAtIndex(runtime, 3).asNumber();
|
130
|
+
auto y2 = cmd.getValueAtIndex(runtime, 4).asNumber();
|
131
|
+
auto x3 = cmd.getValueAtIndex(runtime, 5).asNumber();
|
132
|
+
auto y3 = cmd.getValueAtIndex(runtime, 6).asNumber();
|
133
|
+
path.cubicTo(x1, y1, x2, y2, x3, y3);
|
134
|
+
break;
|
135
|
+
}
|
136
|
+
case CLOSE: {
|
137
|
+
path.close();
|
138
|
+
break;
|
139
|
+
}
|
140
|
+
default: {
|
141
|
+
RNSkLogger::logToConsole("Found an unknown command");
|
142
|
+
return jsi::Value::null();
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
return jsi::Object::createFromHostObject(
|
147
|
+
runtime, std::make_shared<JsiSkPath>(getContext(), std::move(path)));
|
148
|
+
}
|
149
|
+
|
56
150
|
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkPathFactory, Make),
|
57
151
|
JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromSVGString),
|
58
|
-
JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromOp)
|
152
|
+
JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromOp),
|
153
|
+
JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromCmds))
|
59
154
|
|
60
155
|
JsiSkPathFactory(std::shared_ptr<RNSkPlatformContext> context)
|
61
156
|
: JsiSkHostObject(std::move(context)) {}
|