@shopify/react-native-skia 0.1.119 → 0.1.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)) {}
|