@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.
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)) {}