@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.
Files changed (69) hide show
  1. package/android/CMakeLists.txt +30 -16
  2. package/android/build.gradle +81 -34
  3. package/android/src/main/java/com/shopify/reactnative/skia/PlatformContext.java +1 -1
  4. package/cpp/api/JsiSkApi.h +2 -0
  5. package/cpp/api/JsiSkColor.h +49 -0
  6. package/cpp/api/JsiSkPath.h +31 -2
  7. package/cpp/api/JsiSkPathFactory.h +96 -1
  8. package/cpp/api/third_party/CSSColorParser.h +324 -0
  9. package/cpp/rnskia/RNSkAnimation.h +4 -7
  10. package/cpp/rnskia/values/RNSkClockValue.h +4 -4
  11. package/cpp/rnskia/values/RNSkDerivedValue.h +1 -1
  12. package/cpp/rnskia/values/RNSkReadonlyValue.h +9 -15
  13. package/ios/RNSkia-iOS/RNSkDrawViewImpl.h +3 -6
  14. package/ios/RNSkia-iOS/RNSkDrawViewImpl.mm +2 -4
  15. package/ios/RNSkia-iOS/SkiaDrawView.mm +3 -2
  16. package/lib/commonjs/renderer/components/shapes/Path.js +1 -1
  17. package/lib/commonjs/renderer/components/shapes/Path.js.map +1 -1
  18. package/lib/commonjs/renderer/nodes/Node.js +3 -3
  19. package/lib/commonjs/renderer/nodes/Node.js.map +1 -1
  20. package/lib/commonjs/skia/Color.js +3 -25
  21. package/lib/commonjs/skia/Color.js.map +1 -1
  22. package/lib/commonjs/skia/Image/Image.js.map +1 -1
  23. package/lib/commonjs/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
  24. package/lib/commonjs/skia/Paint/Paint.js.map +1 -1
  25. package/lib/commonjs/skia/Path/Path.js +13 -1
  26. package/lib/commonjs/skia/Path/Path.js.map +1 -1
  27. package/lib/commonjs/skia/Shader/Shader.js.map +1 -1
  28. package/lib/commonjs/skia/Skia.js +41 -3
  29. package/lib/commonjs/skia/Skia.js.map +1 -1
  30. package/lib/module/renderer/components/shapes/Path.js +1 -1
  31. package/lib/module/renderer/components/shapes/Path.js.map +1 -1
  32. package/lib/module/renderer/nodes/Node.js +3 -3
  33. package/lib/module/renderer/nodes/Node.js.map +1 -1
  34. package/lib/module/skia/Color.js +2 -21
  35. package/lib/module/skia/Color.js.map +1 -1
  36. package/lib/module/skia/Image/Image.js.map +1 -1
  37. package/lib/module/skia/ImageFilter/ImageFilterFactory.js.map +1 -1
  38. package/lib/module/skia/Paint/Paint.js.map +1 -1
  39. package/lib/module/skia/Path/Path.js +11 -0
  40. package/lib/module/skia/Path/Path.js.map +1 -1
  41. package/lib/module/skia/Shader/Shader.js.map +1 -1
  42. package/lib/module/skia/Skia.js +43 -2
  43. package/lib/module/skia/Skia.js.map +1 -1
  44. package/lib/typescript/src/skia/Color.d.ts +0 -1
  45. package/lib/typescript/src/skia/Image/Image.d.ts +3 -3
  46. package/lib/typescript/src/skia/ImageFilter/ImageFilterFactory.d.ts +2 -2
  47. package/lib/typescript/src/skia/Paint/Paint.d.ts +2 -2
  48. package/lib/typescript/src/skia/Path/Path.d.ts +13 -0
  49. package/lib/typescript/src/skia/Path/PathFactory.d.ts +7 -1
  50. package/lib/typescript/src/skia/Picture/Picture.d.ts +2 -2
  51. package/lib/typescript/src/skia/RuntimeEffect/RuntimeEffect.d.ts +3 -3
  52. package/lib/typescript/src/skia/Shader/Shader.d.ts +2 -2
  53. package/lib/typescript/src/skia/Shader/ShaderFactory.d.ts +9 -9
  54. package/lib/typescript/src/skia/Skia.d.ts +5 -3
  55. package/package.json +1 -1
  56. package/scripts/install-npm.js +1 -1
  57. package/src/renderer/components/shapes/Path.tsx +1 -1
  58. package/src/renderer/nodes/Node.ts +3 -3
  59. package/src/skia/Color.ts +3 -20
  60. package/src/skia/Image/Image.ts +3 -3
  61. package/src/skia/ImageFilter/ImageFilterFactory.ts +2 -2
  62. package/src/skia/Paint/Paint.ts +2 -2
  63. package/src/skia/Path/Path.ts +16 -0
  64. package/src/skia/Path/PathFactory.ts +8 -1
  65. package/src/skia/Picture/Picture.ts +2 -2
  66. package/src/skia/RuntimeEffect/RuntimeEffect.ts +4 -4
  67. package/src/skia/Shader/Shader.ts +2 -2
  68. package/src/skia/Shader/ShaderFactory.ts +9 -9
  69. package/src/skia/Skia.ts +44 -3
@@ -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 (GLOB LIBRN_DIR "${build_DIR}/react-native-0*/jni/${ANDROID_ABI}")
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
- "../node_modules/react-native/ReactCommon/callinvoker"
43
- "../node_modules/react-native/ReactCommon/jsi"
44
- "../node_modules/react-native/ReactCommon/react/nativemodule/core"
45
- "../node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni"
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
- JSI_LIB
91
- jsi
92
- PATHS ${LIBRN_DIR}
93
- NO_CMAKE_FIND_ROOT_PATH
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
@@ -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 = ["**/libc++_shared.so"]
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
- tasks.whenTaskAdded { task ->
192
- if (task.name.contains('externalNativeBuild')) {
193
- task.dependsOn(extractAARHeaders)
194
- task.dependsOn(extractJNIFiles)
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() {
@@ -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
@@ -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), JSI_EXPORT_FUNC(JsiSkPath, interpolate)
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)) {}