@shopify/react-native-skia 2.5.4 → 2.6.0

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 (178) hide show
  1. package/android/src/main/java/com/shopify/reactnative/skia/WebGPUViewManager.java +7 -7
  2. package/apple/{WebGPUView.h → SkiaWebGPUView.h} +1 -1
  3. package/apple/{WebGPUView.mm → SkiaWebGPUView.mm} +7 -7
  4. package/cpp/api/CustomBlendModes.h +1 -0
  5. package/cpp/api/JsiSkApi.h +4 -0
  6. package/cpp/api/JsiSkCanvas.h +2 -2
  7. package/cpp/api/JsiSkContourMeasureIter.h +1 -1
  8. package/cpp/api/JsiSkPath.h +483 -355
  9. package/cpp/api/JsiSkPathBuilder.h +415 -0
  10. package/cpp/api/JsiSkPathBuilderFactory.h +53 -0
  11. package/cpp/api/JsiSkPathEffectFactory.h +2 -2
  12. package/cpp/api/JsiSkPathFactory.h +274 -3
  13. package/cpp/api/recorder/DataTypes.h +1 -1
  14. package/cpp/api/recorder/Drawings.h +6 -2
  15. package/cpp/rnskia/RNDawnContext.h +21 -0
  16. package/cpp/rnskia/RNDawnUtils.h +115 -113
  17. package/lib/commonjs/animation/functions/interpolatePaths.d.ts +1 -1
  18. package/lib/commonjs/animation/functions/interpolatePaths.js +5 -4
  19. package/lib/commonjs/animation/functions/interpolatePaths.js.map +1 -1
  20. package/lib/commonjs/external/reanimated/interpolators.d.ts +11 -2
  21. package/lib/commonjs/external/reanimated/interpolators.js +21 -4
  22. package/lib/commonjs/external/reanimated/interpolators.js.map +1 -1
  23. package/lib/commonjs/skia/types/Path/PathBuilder.d.ts +201 -0
  24. package/lib/commonjs/skia/types/Path/PathBuilder.js +6 -0
  25. package/lib/commonjs/skia/types/Path/PathBuilder.js.map +1 -0
  26. package/lib/commonjs/skia/types/Path/PathBuilderFactory.d.ts +13 -0
  27. package/lib/commonjs/skia/types/Path/PathBuilderFactory.js +6 -0
  28. package/lib/commonjs/skia/types/Path/PathBuilderFactory.js.map +1 -0
  29. package/lib/commonjs/skia/types/Path/PathFactory.d.ts +87 -1
  30. package/lib/commonjs/skia/types/Path/PathFactory.js.map +1 -1
  31. package/lib/commonjs/skia/types/Path/index.d.ts +2 -0
  32. package/lib/commonjs/skia/types/Path/index.js +22 -0
  33. package/lib/commonjs/skia/types/Path/index.js.map +1 -1
  34. package/lib/commonjs/skia/types/Skia.d.ts +2 -1
  35. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  36. package/lib/commonjs/skia/web/Host.js +1 -3
  37. package/lib/commonjs/skia/web/Host.js.map +1 -1
  38. package/lib/commonjs/skia/web/JsiSkCanvas.js +6 -2
  39. package/lib/commonjs/skia/web/JsiSkCanvas.js.map +1 -1
  40. package/lib/commonjs/skia/web/JsiSkContourMeasure.js +4 -1
  41. package/lib/commonjs/skia/web/JsiSkContourMeasure.js.map +1 -1
  42. package/lib/commonjs/skia/web/JsiSkPath.d.ts +42 -30
  43. package/lib/commonjs/skia/web/JsiSkPath.js +302 -111
  44. package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
  45. package/lib/commonjs/skia/web/JsiSkPathBuilder.d.ts +45 -0
  46. package/lib/commonjs/skia/web/JsiSkPathBuilder.js +192 -0
  47. package/lib/commonjs/skia/web/JsiSkPathBuilder.js.map +1 -0
  48. package/lib/commonjs/skia/web/JsiSkPathBuilderFactory.d.ts +9 -0
  49. package/lib/commonjs/skia/web/JsiSkPathBuilderFactory.js +26 -0
  50. package/lib/commonjs/skia/web/JsiSkPathBuilderFactory.js.map +1 -0
  51. package/lib/commonjs/skia/web/JsiSkPathEffectFactory.js +6 -2
  52. package/lib/commonjs/skia/web/JsiSkPathEffectFactory.js.map +1 -1
  53. package/lib/commonjs/skia/web/JsiSkPathFactory.d.ts +13 -1
  54. package/lib/commonjs/skia/web/JsiSkPathFactory.js +140 -5
  55. package/lib/commonjs/skia/web/JsiSkPathFactory.js.map +1 -1
  56. package/lib/commonjs/skia/web/JsiSkia.js +8 -1
  57. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  58. package/lib/commonjs/sksg/Recorder/commands/Drawing.js +18 -6
  59. package/lib/commonjs/sksg/Recorder/commands/Drawing.js.map +1 -1
  60. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +2 -2
  61. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js +2 -3
  62. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  63. package/lib/commonjs/specs/WebGPUViewNativeComponent.d.ts +2 -2
  64. package/lib/commonjs/specs/WebGPUViewNativeComponent.js +2 -3
  65. package/lib/commonjs/specs/WebGPUViewNativeComponent.js.map +1 -1
  66. package/lib/commonjs/specs/WebGPUViewNativeComponent.web.js +2 -0
  67. package/lib/commonjs/specs/WebGPUViewNativeComponent.web.js.map +1 -1
  68. package/lib/module/animation/functions/interpolatePaths.d.ts +1 -1
  69. package/lib/module/animation/functions/interpolatePaths.js +5 -4
  70. package/lib/module/animation/functions/interpolatePaths.js.map +1 -1
  71. package/lib/module/external/reanimated/interpolators.d.ts +11 -2
  72. package/lib/module/external/reanimated/interpolators.js +21 -4
  73. package/lib/module/external/reanimated/interpolators.js.map +1 -1
  74. package/lib/module/skia/types/Path/PathBuilder.d.ts +201 -0
  75. package/lib/module/skia/types/Path/PathBuilder.js +2 -0
  76. package/lib/module/skia/types/Path/PathBuilder.js.map +1 -0
  77. package/lib/module/skia/types/Path/PathBuilderFactory.d.ts +13 -0
  78. package/lib/module/skia/types/Path/PathBuilderFactory.js +2 -0
  79. package/lib/module/skia/types/Path/PathBuilderFactory.js.map +1 -0
  80. package/lib/module/skia/types/Path/PathFactory.d.ts +87 -1
  81. package/lib/module/skia/types/Path/PathFactory.js.map +1 -1
  82. package/lib/module/skia/types/Path/index.d.ts +2 -0
  83. package/lib/module/skia/types/Path/index.js +2 -0
  84. package/lib/module/skia/types/Path/index.js.map +1 -1
  85. package/lib/module/skia/types/Skia.d.ts +2 -1
  86. package/lib/module/skia/types/Skia.js.map +1 -1
  87. package/lib/module/skia/web/Host.js +1 -3
  88. package/lib/module/skia/web/Host.js.map +1 -1
  89. package/lib/module/skia/web/JsiSkCanvas.js +6 -2
  90. package/lib/module/skia/web/JsiSkCanvas.js.map +1 -1
  91. package/lib/module/skia/web/JsiSkContourMeasure.js +4 -1
  92. package/lib/module/skia/web/JsiSkContourMeasure.js.map +1 -1
  93. package/lib/module/skia/web/JsiSkPath.d.ts +42 -30
  94. package/lib/module/skia/web/JsiSkPath.js +300 -110
  95. package/lib/module/skia/web/JsiSkPath.js.map +1 -1
  96. package/lib/module/skia/web/JsiSkPathBuilder.d.ts +45 -0
  97. package/lib/module/skia/web/JsiSkPathBuilder.js +186 -0
  98. package/lib/module/skia/web/JsiSkPathBuilder.js.map +1 -0
  99. package/lib/module/skia/web/JsiSkPathBuilderFactory.d.ts +9 -0
  100. package/lib/module/skia/web/JsiSkPathBuilderFactory.js +19 -0
  101. package/lib/module/skia/web/JsiSkPathBuilderFactory.js.map +1 -0
  102. package/lib/module/skia/web/JsiSkPathEffectFactory.js +6 -2
  103. package/lib/module/skia/web/JsiSkPathEffectFactory.js.map +1 -1
  104. package/lib/module/skia/web/JsiSkPathFactory.d.ts +13 -1
  105. package/lib/module/skia/web/JsiSkPathFactory.js +141 -6
  106. package/lib/module/skia/web/JsiSkPathFactory.js.map +1 -1
  107. package/lib/module/skia/web/JsiSkia.js +8 -1
  108. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  109. package/lib/module/sksg/Recorder/commands/Drawing.js +18 -6
  110. package/lib/module/sksg/Recorder/commands/Drawing.js.map +1 -1
  111. package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +2 -2
  112. package/lib/module/specs/SkiaPictureViewNativeComponent.js +1 -1
  113. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  114. package/lib/module/specs/WebGPUViewNativeComponent.d.ts +2 -2
  115. package/lib/module/specs/WebGPUViewNativeComponent.js +2 -2
  116. package/lib/module/specs/WebGPUViewNativeComponent.js.map +1 -1
  117. package/lib/module/specs/WebGPUViewNativeComponent.web.js +2 -0
  118. package/lib/module/specs/WebGPUViewNativeComponent.web.js.map +1 -1
  119. package/lib/typescript/lib/commonjs/animation/functions/interpolatePaths.d.ts +1 -1
  120. package/lib/typescript/lib/commonjs/external/reanimated/interpolators.d.ts +1 -1
  121. package/lib/typescript/lib/commonjs/skia/types/Path/PathBuilder.d.ts +1 -0
  122. package/lib/typescript/lib/commonjs/skia/types/Path/PathBuilderFactory.d.ts +1 -0
  123. package/lib/typescript/lib/commonjs/skia/web/JsiSkPath.d.ts +33 -25
  124. package/lib/typescript/lib/commonjs/skia/web/JsiSkPathBuilder.d.ts +46 -0
  125. package/lib/typescript/lib/commonjs/skia/web/JsiSkPathBuilderFactory.d.ts +7 -0
  126. package/lib/typescript/lib/commonjs/skia/web/JsiSkPathFactory.d.ts +12 -0
  127. package/lib/typescript/lib/commonjs/skia/web/JsiSkia.d.ts +2 -0
  128. package/lib/typescript/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +2 -1
  129. package/lib/typescript/lib/commonjs/specs/WebGPUViewNativeComponent.d.ts +2 -1
  130. package/lib/typescript/lib/module/animation/functions/interpolatePaths.d.ts +1 -1
  131. package/lib/typescript/lib/module/external/reanimated/interpolators.d.ts +1 -1
  132. package/lib/typescript/lib/module/mock/index.d.ts +1 -1
  133. package/lib/typescript/lib/module/skia/Skia.web.d.ts +1 -0
  134. package/lib/typescript/lib/module/skia/types/Path/PathBuilder.d.ts +1 -0
  135. package/lib/typescript/lib/module/skia/types/Path/PathBuilderFactory.d.ts +1 -0
  136. package/lib/typescript/lib/module/skia/types/Path/index.d.ts +2 -0
  137. package/lib/typescript/lib/module/skia/web/JsiSkPath.d.ts +38 -25
  138. package/lib/typescript/lib/module/skia/web/JsiSkPathBuilder.d.ts +45 -0
  139. package/lib/typescript/lib/module/skia/web/JsiSkPathBuilderFactory.d.ts +6 -0
  140. package/lib/typescript/lib/module/skia/web/JsiSkPathFactory.d.ts +12 -0
  141. package/lib/typescript/lib/module/skia/web/JsiSkia.d.ts +2 -0
  142. package/lib/typescript/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +1 -1
  143. package/lib/typescript/lib/module/specs/WebGPUViewNativeComponent.d.ts +1 -1
  144. package/lib/typescript/src/animation/functions/interpolatePaths.d.ts +1 -1
  145. package/lib/typescript/src/external/reanimated/interpolators.d.ts +11 -2
  146. package/lib/typescript/src/skia/types/Path/PathBuilder.d.ts +201 -0
  147. package/lib/typescript/src/skia/types/Path/PathBuilderFactory.d.ts +13 -0
  148. package/lib/typescript/src/skia/types/Path/PathFactory.d.ts +87 -1
  149. package/lib/typescript/src/skia/types/Path/index.d.ts +2 -0
  150. package/lib/typescript/src/skia/types/Skia.d.ts +2 -1
  151. package/lib/typescript/src/skia/web/JsiSkPath.d.ts +42 -30
  152. package/lib/typescript/src/skia/web/JsiSkPathBuilder.d.ts +45 -0
  153. package/lib/typescript/src/skia/web/JsiSkPathBuilderFactory.d.ts +9 -0
  154. package/lib/typescript/src/skia/web/JsiSkPathFactory.d.ts +13 -1
  155. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +2 -2
  156. package/lib/typescript/src/specs/WebGPUViewNativeComponent.d.ts +2 -2
  157. package/package.json +4 -3
  158. package/scripts/install-libs.js +16 -6
  159. package/src/animation/functions/interpolatePaths.ts +5 -6
  160. package/src/external/reanimated/interpolators.ts +25 -5
  161. package/src/skia/types/Path/PathBuilder.ts +303 -0
  162. package/src/skia/types/Path/PathBuilderFactory.ts +15 -0
  163. package/src/skia/types/Path/PathFactory.ts +108 -1
  164. package/src/skia/types/Path/index.ts +2 -0
  165. package/src/skia/types/Skia.ts +2 -1
  166. package/src/skia/web/Host.ts +7 -1
  167. package/src/skia/web/JsiSkCanvas.ts +6 -6
  168. package/src/skia/web/JsiSkContourMeasure.ts +4 -4
  169. package/src/skia/web/JsiSkPath.ts +451 -168
  170. package/src/skia/web/JsiSkPathBuilder.ts +293 -0
  171. package/src/skia/web/JsiSkPathBuilderFactory.ts +32 -0
  172. package/src/skia/web/JsiSkPathEffectFactory.ts +6 -2
  173. package/src/skia/web/JsiSkPathFactory.ts +231 -8
  174. package/src/skia/web/JsiSkia.ts +11 -8
  175. package/src/sksg/Recorder/commands/Drawing.ts +20 -7
  176. package/src/specs/SkiaPictureViewNativeComponent.ts +1 -2
  177. package/src/specs/WebGPUViewNativeComponent.ts +3 -3
  178. package/src/specs/WebGPUViewNativeComponent.web.ts +2 -0
@@ -2,6 +2,8 @@
2
2
 
3
3
  #include <algorithm>
4
4
  #include <memory>
5
+ #include <set>
6
+ #include <string>
5
7
  #include <utility>
6
8
  #include <vector>
7
9
 
@@ -12,11 +14,13 @@
12
14
  #include "JsiSkPoint.h"
13
15
  #include "JsiSkRRect.h"
14
16
  #include "JsiSkRect.h"
17
+ #include "RNSkLog.h"
15
18
 
16
19
  #pragma clang diagnostic push
17
20
  #pragma clang diagnostic ignored "-Wdocumentation"
18
21
 
19
22
  #include "include/core/SkPath.h"
23
+ #include "include/core/SkPathBuilder.h"
20
24
  #include "include/core/SkPathEffect.h"
21
25
  #include "include/core/SkPathTypes.h"
22
26
  #include "include/core/SkPathUtils.h"
@@ -25,7 +29,6 @@
25
29
  #include "include/effects/SkDashPathEffect.h"
26
30
  #include "include/effects/SkTrimPathEffect.h"
27
31
  #include "include/utils/SkParsePath.h"
28
- #include "include/utils/SkTextUtils.h"
29
32
 
30
33
  #include "include/pathops/SkPathOps.h"
31
34
 
@@ -35,7 +38,29 @@ namespace RNSkia {
35
38
 
36
39
  namespace jsi = facebook::jsi;
37
40
 
38
- class JsiSkPath : public JsiSkWrappingSharedPtrHostObject<SkPath> {
41
+ // Track which deprecation warnings have been shown to avoid spam
42
+ inline std::set<std::string> &getShownPathDeprecationWarnings() {
43
+ static std::set<std::string> warnings;
44
+ return warnings;
45
+ }
46
+
47
+ inline void warnDeprecatedPathMethod(jsi::Runtime &runtime,
48
+ const char *methodName,
49
+ const char *suggestion) {
50
+ auto &warnings = getShownPathDeprecationWarnings();
51
+ if (warnings.find(methodName) != warnings.end()) {
52
+ return;
53
+ }
54
+ warnings.insert(methodName);
55
+ std::string message =
56
+ std::string("[react-native-skia] SkPath.") + methodName +
57
+ "() is deprecated and will be removed in a future release. " + suggestion +
58
+ " See migration guide: "
59
+ "https://shopify.github.io/react-native-skia/docs/shapes/path-migration";
60
+ RNSkLogger::warnToJavascriptConsole(runtime, message);
61
+ }
62
+
63
+ class JsiSkPath : public JsiSkWrappingSharedPtrHostObject<SkPathBuilder> {
39
64
  private:
40
65
  static const int MOVE = 0;
41
66
  static const int LINE = 1;
@@ -44,30 +69,163 @@ private:
44
69
  static const int CUBIC = 4;
45
70
  static const int CLOSE = 5;
46
71
 
47
- float pinT(double value) {
48
- // Clamp the double value between 0 and 1 and then cast it to float
49
- return static_cast<float>(std::clamp(value, 0.0, 1.0));
50
- }
72
+ SkPath asPath() const { return getObject()->snapshot(); }
51
73
 
52
74
  public:
75
+ // Mutable building methods (deprecated)
76
+
77
+ JSI_HOST_FUNCTION(moveTo) {
78
+ warnDeprecatedPathMethod(runtime, "moveTo",
79
+ "Use Skia.PathBuilder.Make().moveTo() instead.");
80
+ SkScalar x = arguments[0].asNumber();
81
+ SkScalar y = arguments[1].asNumber();
82
+ getObject()->moveTo(x, y);
83
+ return thisValue.getObject(runtime);
84
+ }
85
+
86
+ JSI_HOST_FUNCTION(rMoveTo) {
87
+ warnDeprecatedPathMethod(runtime, "rMoveTo",
88
+ "Use Skia.PathBuilder.Make().rMoveTo() instead.");
89
+ SkScalar x = arguments[0].asNumber();
90
+ SkScalar y = arguments[1].asNumber();
91
+ getObject()->rMoveTo({x, y});
92
+ return thisValue.getObject(runtime);
93
+ }
94
+
95
+ JSI_HOST_FUNCTION(lineTo) {
96
+ warnDeprecatedPathMethod(runtime, "lineTo",
97
+ "Use Skia.PathBuilder.Make().lineTo() instead.");
98
+ SkScalar x = arguments[0].asNumber();
99
+ SkScalar y = arguments[1].asNumber();
100
+ getObject()->lineTo(x, y);
101
+ return thisValue.getObject(runtime);
102
+ }
103
+
104
+ JSI_HOST_FUNCTION(rLineTo) {
105
+ warnDeprecatedPathMethod(runtime, "rLineTo",
106
+ "Use Skia.PathBuilder.Make().rLineTo() instead.");
107
+ SkScalar x = arguments[0].asNumber();
108
+ SkScalar y = arguments[1].asNumber();
109
+ getObject()->rLineTo(x, y);
110
+ return thisValue.getObject(runtime);
111
+ }
112
+
113
+ JSI_HOST_FUNCTION(quadTo) {
114
+ warnDeprecatedPathMethod(runtime, "quadTo",
115
+ "Use Skia.PathBuilder.Make().quadTo() instead.");
116
+ SkScalar x1 = arguments[0].asNumber();
117
+ SkScalar y1 = arguments[1].asNumber();
118
+ SkScalar x2 = arguments[2].asNumber();
119
+ SkScalar y2 = arguments[3].asNumber();
120
+ getObject()->quadTo(x1, y1, x2, y2);
121
+ return thisValue.getObject(runtime);
122
+ }
123
+
124
+ JSI_HOST_FUNCTION(rQuadTo) {
125
+ warnDeprecatedPathMethod(runtime, "rQuadTo",
126
+ "Use Skia.PathBuilder.Make().rQuadTo() instead.");
127
+ SkScalar x1 = arguments[0].asNumber();
128
+ SkScalar y1 = arguments[1].asNumber();
129
+ SkScalar x2 = arguments[2].asNumber();
130
+ SkScalar y2 = arguments[3].asNumber();
131
+ getObject()->rQuadTo(x1, y1, x2, y2);
132
+ return thisValue.getObject(runtime);
133
+ }
134
+
135
+ JSI_HOST_FUNCTION(conicTo) {
136
+ warnDeprecatedPathMethod(runtime, "conicTo",
137
+ "Use Skia.PathBuilder.Make().conicTo() instead.");
138
+ SkScalar x1 = arguments[0].asNumber();
139
+ SkScalar y1 = arguments[1].asNumber();
140
+ SkScalar x2 = arguments[2].asNumber();
141
+ SkScalar y2 = arguments[3].asNumber();
142
+ SkScalar w = arguments[4].asNumber();
143
+ getObject()->conicTo(x1, y1, x2, y2, w);
144
+ return thisValue.getObject(runtime);
145
+ }
146
+
147
+ JSI_HOST_FUNCTION(rConicTo) {
148
+ warnDeprecatedPathMethod(runtime, "rConicTo",
149
+ "Use Skia.PathBuilder.Make().rConicTo() instead.");
150
+ SkScalar x1 = arguments[0].asNumber();
151
+ SkScalar y1 = arguments[1].asNumber();
152
+ SkScalar x2 = arguments[2].asNumber();
153
+ SkScalar y2 = arguments[3].asNumber();
154
+ SkScalar w = arguments[4].asNumber();
155
+ getObject()->rConicTo(x1, y1, x2, y2, w);
156
+ return thisValue.getObject(runtime);
157
+ }
158
+
159
+ JSI_HOST_FUNCTION(cubicTo) {
160
+ warnDeprecatedPathMethod(runtime, "cubicTo",
161
+ "Use Skia.PathBuilder.Make().cubicTo() instead.");
162
+ SkScalar x1 = arguments[0].asNumber();
163
+ SkScalar y1 = arguments[1].asNumber();
164
+ SkScalar x2 = arguments[2].asNumber();
165
+ SkScalar y2 = arguments[3].asNumber();
166
+ SkScalar x3 = arguments[4].asNumber();
167
+ SkScalar y3 = arguments[5].asNumber();
168
+ getObject()->cubicTo(x1, y1, x2, y2, x3, y3);
169
+ return thisValue.getObject(runtime);
170
+ }
171
+
172
+ JSI_HOST_FUNCTION(rCubicTo) {
173
+ warnDeprecatedPathMethod(runtime, "rCubicTo",
174
+ "Use Skia.PathBuilder.Make().rCubicTo() instead.");
175
+ SkScalar x1 = arguments[0].asNumber();
176
+ SkScalar y1 = arguments[1].asNumber();
177
+ SkScalar x2 = arguments[2].asNumber();
178
+ SkScalar y2 = arguments[3].asNumber();
179
+ SkScalar x3 = arguments[4].asNumber();
180
+ SkScalar y3 = arguments[5].asNumber();
181
+ getObject()->rCubicTo(x1, y1, x2, y2, x3, y3);
182
+ return thisValue.getObject(runtime);
183
+ }
184
+
185
+ JSI_HOST_FUNCTION(close) {
186
+ warnDeprecatedPathMethod(runtime, "close",
187
+ "Use Skia.PathBuilder.Make().close() instead.");
188
+ getObject()->close();
189
+ return thisValue.getObject(runtime);
190
+ }
191
+
192
+ JSI_HOST_FUNCTION(reset) {
193
+ warnDeprecatedPathMethod(runtime, "reset",
194
+ "Use Skia.PathBuilder.Make().reset() instead.");
195
+ getObject()->reset();
196
+ return thisValue.getObject(runtime);
197
+ }
198
+
199
+ JSI_HOST_FUNCTION(rewind) {
200
+ warnDeprecatedPathMethod(runtime, "rewind",
201
+ "Use Skia.PathBuilder.Make().reset() instead.");
202
+ getObject()->reset();
203
+ return thisValue.getObject(runtime);
204
+ }
205
+
53
206
  JSI_HOST_FUNCTION(addPath) {
207
+ warnDeprecatedPathMethod(runtime, "addPath",
208
+ "Use Skia.PathBuilder.Make().addPath() instead.");
54
209
  auto src = JsiSkPath::fromValue(runtime, arguments[0]);
210
+ auto srcPath = src->snapshot();
55
211
  auto matrix =
56
212
  count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()
57
213
  ? JsiSkMatrix::fromValue(runtime, arguments[1])
58
214
  : nullptr;
59
- auto mode = count > 2 && arguments[2].isBool() && arguments[2].getBool()
60
- ? SkPath::kExtend_AddPathMode
61
- : SkPath::kAppend_AddPathMode;
62
- if (matrix == nullptr) {
63
- getObject()->addPath(*src, mode);
215
+ auto extend = count > 2 && arguments[2].getBool();
216
+ auto mode = extend ? SkPath::kExtend_AddPathMode
217
+ : SkPath::kAppend_AddPathMode;
218
+ if (matrix) {
219
+ getObject()->addPath(srcPath, *matrix, mode);
64
220
  } else {
65
- getObject()->addPath(*src, *matrix, mode);
221
+ getObject()->addPath(srcPath, mode);
66
222
  }
67
223
  return thisValue.getObject(runtime);
68
224
  }
69
225
 
70
226
  JSI_HOST_FUNCTION(addArc) {
227
+ warnDeprecatedPathMethod(runtime, "addArc",
228
+ "Use Skia.PathBuilder.Make().addArc() instead.");
71
229
  auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
72
230
  auto start = arguments[1].asNumber();
73
231
  auto sweep = arguments[2].asNumber();
@@ -76,53 +234,77 @@ public:
76
234
  }
77
235
 
78
236
  JSI_HOST_FUNCTION(addOval) {
237
+ warnDeprecatedPathMethod(runtime,
238
+ "addOval",
239
+ "Use Skia.Path.Oval() or Skia.PathBuilder.Make().addOval() instead.");
79
240
  auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
80
- auto direction = SkPathDirection::kCW;
81
- if (count >= 2 && arguments[1].getBool()) {
82
- direction = SkPathDirection::kCCW;
83
- }
84
- unsigned startIndex = count < 3 ? 0 : arguments[2].asNumber();
85
- auto result = getObject()->addOval(*rect, direction, startIndex);
86
- return thisValue.getObject(runtime);
87
- }
88
-
89
- JSI_HOST_FUNCTION(addPoly) {
90
- std::vector<SkPoint> points;
91
- auto jsiPoints = arguments[0].asObject(runtime).asArray(runtime);
92
- auto close = arguments[1].getBool();
93
- auto pointsSize = jsiPoints.size(runtime);
94
- points.reserve(pointsSize);
95
- for (int i = 0; i < pointsSize; i++) {
96
- std::shared_ptr<SkPoint> point = JsiSkPoint::fromValue(
97
- runtime, jsiPoints.getValueAtIndex(runtime, i).asObject(runtime));
98
- points.push_back(*point.get());
99
- }
100
- auto p = SkSpan(points.data(), points.size());
101
- getObject()->addPoly(p, close);
241
+ auto isCCW = count > 1 && arguments[1].getBool();
242
+ auto startIndex = count > 2 ? static_cast<unsigned>(arguments[2].asNumber()) : 1;
243
+ auto direction =
244
+ isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
245
+ getObject()->addOval(*rect, direction, startIndex);
102
246
  return thisValue.getObject(runtime);
103
247
  }
104
248
 
105
249
  JSI_HOST_FUNCTION(addRect) {
250
+ warnDeprecatedPathMethod(runtime,
251
+ "addRect",
252
+ "Use Skia.Path.Rect() or Skia.PathBuilder.Make().addRect() instead.");
106
253
  auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
107
- auto direction = SkPathDirection::kCW;
108
- if (count >= 2 && arguments[1].getBool()) {
109
- direction = SkPathDirection::kCCW;
110
- }
254
+ auto isCCW = count > 1 && arguments[1].getBool();
255
+ auto direction =
256
+ isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
111
257
  getObject()->addRect(*rect, direction);
112
258
  return thisValue.getObject(runtime);
113
259
  }
114
260
 
115
261
  JSI_HOST_FUNCTION(addRRect) {
262
+ warnDeprecatedPathMethod(runtime,
263
+ "addRRect",
264
+ "Use Skia.Path.RRect() or Skia.PathBuilder.Make().addRRect() instead.");
116
265
  auto rrect = JsiSkRRect::fromValue(runtime, arguments[0]);
117
- auto direction = SkPathDirection::kCW;
118
- if (count >= 2 && arguments[1].getBool()) {
119
- direction = SkPathDirection::kCCW;
120
- }
266
+ auto isCCW = count > 1 && arguments[1].getBool();
267
+ auto direction =
268
+ isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
121
269
  getObject()->addRRect(*rrect, direction);
122
270
  return thisValue.getObject(runtime);
123
271
  }
124
272
 
273
+ JSI_HOST_FUNCTION(addCircle) {
274
+ warnDeprecatedPathMethod(runtime,
275
+ "addCircle",
276
+ "Use Skia.Path.Circle() or Skia.PathBuilder.Make().addCircle() "
277
+ "instead.");
278
+ SkScalar x = arguments[0].asNumber();
279
+ SkScalar y = arguments[1].asNumber();
280
+ SkScalar r = arguments[2].asNumber();
281
+ getObject()->addCircle(x, y, r);
282
+ return thisValue.getObject(runtime);
283
+ }
284
+
285
+ JSI_HOST_FUNCTION(addPoly) {
286
+ warnDeprecatedPathMethod(runtime,
287
+ "addPoly",
288
+ "Use Skia.Path.Polygon() or Skia.PathBuilder.Make().addPoly() "
289
+ "instead.");
290
+ auto jsiPoints = arguments[0].asObject(runtime).asArray(runtime);
291
+ auto close = arguments[1].getBool();
292
+ auto pointsSize = static_cast<int>(jsiPoints.size(runtime));
293
+ std::vector<SkPoint> points;
294
+ points.reserve(pointsSize);
295
+ for (int i = 0; i < pointsSize; i++) {
296
+ auto pt = JsiSkPoint::fromValue(
297
+ runtime, jsiPoints.getValueAtIndex(runtime, i));
298
+ points.push_back(*pt);
299
+ }
300
+ getObject()->addPolygon(SkSpan<const SkPoint>(points.data(), points.size()),
301
+ close);
302
+ return thisValue.getObject(runtime);
303
+ }
304
+
125
305
  JSI_HOST_FUNCTION(arcToOval) {
306
+ warnDeprecatedPathMethod(runtime,
307
+ "arcToOval", "Use Skia.PathBuilder.Make().arcToOval() instead.");
126
308
  auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
127
309
  auto start = arguments[1].asNumber();
128
310
  auto sweep = arguments[2].asNumber();
@@ -132,395 +314,313 @@ public:
132
314
  }
133
315
 
134
316
  JSI_HOST_FUNCTION(arcToRotated) {
135
- auto rx = arguments[0].asNumber();
136
- auto ry = arguments[1].asNumber();
137
- auto xAxisRotate = arguments[2].asNumber();
317
+ warnDeprecatedPathMethod(runtime,
318
+ "arcToRotated", "Use Skia.PathBuilder.Make().arcToRotated() instead.");
319
+ SkScalar rx = arguments[0].asNumber();
320
+ SkScalar ry = arguments[1].asNumber();
321
+ SkScalar xAxisRotate = arguments[2].asNumber();
138
322
  auto useSmallArc = arguments[3].getBool();
139
- auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize
140
- : SkPath::ArcSize::kLarge_ArcSize;
323
+ auto isCCW = arguments[4].getBool();
324
+ SkScalar x = arguments[5].asNumber();
325
+ SkScalar y = arguments[6].asNumber();
326
+ auto arcSize = useSmallArc ? SkPathBuilder::kSmall_ArcSize
327
+ : SkPathBuilder::kLarge_ArcSize;
141
328
  auto sweep =
142
- arguments[4].getBool() ? SkPathDirection::kCCW : SkPathDirection::kCW;
143
- auto x = arguments[5].asNumber();
144
- auto y = arguments[6].asNumber();
145
- getObject()->arcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
329
+ isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
330
+ getObject()->arcTo(SkPoint::Make(rx, ry), xAxisRotate, arcSize, sweep,
331
+ SkPoint::Make(x, y));
146
332
  return thisValue.getObject(runtime);
147
333
  }
148
334
 
149
335
  JSI_HOST_FUNCTION(rArcTo) {
150
- auto rx = arguments[0].asNumber();
151
- auto ry = arguments[1].asNumber();
152
- auto xAxisRotate = arguments[2].asNumber();
336
+ warnDeprecatedPathMethod(runtime, "rArcTo",
337
+ "Use Skia.PathBuilder.Make().rArcTo() instead.");
338
+ SkScalar rx = arguments[0].asNumber();
339
+ SkScalar ry = arguments[1].asNumber();
340
+ SkScalar xAxisRotate = arguments[2].asNumber();
153
341
  auto useSmallArc = arguments[3].getBool();
154
- auto arcSize = useSmallArc ? SkPath::ArcSize::kSmall_ArcSize
155
- : SkPath::ArcSize::kLarge_ArcSize;
342
+ auto isCCW = arguments[4].getBool();
343
+ SkScalar dx = arguments[5].asNumber();
344
+ SkScalar dy = arguments[6].asNumber();
345
+ auto arcSize = useSmallArc ? SkPathBuilder::kSmall_ArcSize
346
+ : SkPathBuilder::kLarge_ArcSize;
156
347
  auto sweep =
157
- arguments[4].getBool() ? SkPathDirection::kCCW : SkPathDirection::kCW;
158
- auto x = arguments[5].asNumber();
159
- auto y = arguments[6].asNumber();
160
- getObject()->rArcTo(rx, ry, xAxisRotate, arcSize, sweep, x, y);
348
+ isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
349
+ SkVector dxdy(dx, dy);
350
+ SkPoint r(rx, ry);
351
+ getObject()->rArcTo(r, xAxisRotate, arcSize, sweep, dxdy);
161
352
  return thisValue.getObject(runtime);
162
353
  }
163
354
 
164
355
  JSI_HOST_FUNCTION(arcToTangent) {
165
- auto x1 = arguments[0].asNumber();
166
- auto y1 = arguments[1].asNumber();
167
- auto x2 = arguments[2].asNumber();
168
- auto y2 = arguments[3].asNumber();
169
- auto r = arguments[4].asNumber();
170
- getObject()->arcTo(x1, y1, x2, y2, r);
356
+ warnDeprecatedPathMethod(runtime,
357
+ "arcToTangent", "Use Skia.PathBuilder.Make().arcToTangent() instead.");
358
+ SkScalar x1 = arguments[0].asNumber();
359
+ SkScalar y1 = arguments[1].asNumber();
360
+ SkScalar x2 = arguments[2].asNumber();
361
+ SkScalar y2 = arguments[3].asNumber();
362
+ SkScalar r = arguments[4].asNumber();
363
+ getObject()->arcTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), r);
171
364
  return thisValue.getObject(runtime);
172
365
  }
173
366
 
174
- JSI_HOST_FUNCTION(computeTightBounds) {
175
- auto result = getObject()->computeTightBounds();
176
- auto hostObjectInstance = std::make_shared<JsiSkRect>(getContext(), result);
177
- return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
178
- runtime, hostObjectInstance, getContext());
179
- }
180
-
181
- // TODO-API: Should this be a property?
182
- JSI_HOST_FUNCTION(getBounds) {
183
- auto result = getObject()->getBounds();
184
- auto hostObjectInstance = std::make_shared<JsiSkRect>(getContext(), result);
185
- return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
186
- runtime, hostObjectInstance, getContext());
187
- }
188
-
189
- JSI_HOST_FUNCTION(conicTo) {
190
- auto x1 = arguments[0].asNumber();
191
- auto y1 = arguments[1].asNumber();
192
- auto x2 = arguments[2].asNumber();
193
- auto y2 = arguments[3].asNumber();
194
- auto w = arguments[4].asNumber();
195
- getObject()->conicTo(x1, y1, x2, y2, w);
367
+ JSI_HOST_FUNCTION(setFillType) {
368
+ warnDeprecatedPathMethod(runtime,
369
+ "setFillType", "Use Skia.PathBuilder.Make().setFillType() instead.");
370
+ auto ft = arguments[0].asNumber();
371
+ getObject()->setFillType(static_cast<SkPathFillType>(static_cast<int>(ft)));
196
372
  return thisValue.getObject(runtime);
197
373
  }
198
374
 
199
- JSI_HOST_FUNCTION(rConicTo) {
200
- auto x1 = arguments[0].asNumber();
201
- auto y1 = arguments[1].asNumber();
202
- auto x2 = arguments[2].asNumber();
203
- auto y2 = arguments[3].asNumber();
204
- auto w = arguments[4].asNumber();
205
- getObject()->rConicTo(x1, y1, x2, y2, w);
375
+ JSI_HOST_FUNCTION(setIsVolatile) {
376
+ warnDeprecatedPathMethod(runtime,
377
+ "setIsVolatile", "Use Skia.PathBuilder.Make().setIsVolatile() instead.");
378
+ auto v = arguments[0].getBool();
379
+ getObject()->setIsVolatile(v);
206
380
  return thisValue.getObject(runtime);
207
381
  }
208
382
 
209
- JSI_HOST_FUNCTION(contains) {
210
- auto x = arguments[0].asNumber();
211
- auto y = arguments[1].asNumber();
212
- return jsi::Value(getObject()->contains(x, y));
213
- }
383
+ // Mutable transform methods (deprecated)
214
384
 
215
- JSI_HOST_FUNCTION(dash) {
216
- SkScalar on = arguments[0].asNumber();
217
- SkScalar off = arguments[1].asNumber();
218
- auto phase = arguments[2].asNumber();
219
- SkScalar intervals[] = {on, off};
220
- auto i = SkSpan(intervals, 2);
221
- auto pe = SkDashPathEffect::Make(i, phase);
222
- if (!pe) {
223
- // TODO: SkDebugf("Invalid args to dash()\n");
224
- return jsi::Value(false);
225
- }
226
- SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
227
- SkPath &path = *getObject();
228
- // TODO: why we don't need to swap here? In trim() which is the same
229
- // API, we need to swap
230
- if (pe->filterPath(&path, path, &rec, nullptr)) {
231
- return jsi::Value(true);
232
- }
233
- SkDebugf("Could not make dashed path\n");
234
- return jsi::Value(false);
385
+ JSI_HOST_FUNCTION(transform) {
386
+ warnDeprecatedPathMethod(runtime,
387
+ "transform", "Use Skia.PathBuilder.Make().transform() instead.");
388
+ auto m3 = *JsiSkMatrix::fromValue(runtime, arguments[0]);
389
+ getObject()->transform(m3);
390
+ return thisValue.getObject(runtime);
235
391
  }
236
392
 
237
- JSI_HOST_FUNCTION(equals) {
238
- auto p1 = JsiSkPath::fromValue(runtime, arguments[0]).get();
239
- auto p2 = JsiSkPath::fromValue(runtime, arguments[1]).get();
240
- return jsi::Value(p1 == p2);
393
+ JSI_HOST_FUNCTION(offset) {
394
+ warnDeprecatedPathMethod(runtime, "offset",
395
+ "Use Skia.PathBuilder.Make().offset() instead.");
396
+ SkScalar dx = arguments[0].asNumber();
397
+ SkScalar dy = arguments[1].asNumber();
398
+ getObject()->offset(dx, dy);
399
+ return thisValue.getObject(runtime);
241
400
  }
242
401
 
243
- // TODO-API: Property?
244
- JSI_HOST_FUNCTION(getFillType) {
245
- auto fillType = getObject()->getFillType();
246
- return jsi::Value(static_cast<int>(fillType));
247
- }
402
+ // Mutable path operations (deprecated)
248
403
 
249
- // TODO-API: Property?
250
- JSI_HOST_FUNCTION(setFillType) {
251
- auto ft = (SkPathFillType)arguments[0].asNumber();
252
- getObject()->setFillType(ft);
404
+ JSI_HOST_FUNCTION(simplify) {
405
+ warnDeprecatedPathMethod(runtime, "simplify",
406
+ "Use Skia.Path.Simplify(path) instead.");
407
+ auto path = asPath();
408
+ auto result = ::Simplify(path);
409
+ if (result.has_value()) {
410
+ *getObject() = SkPathBuilder(result.value());
411
+ }
253
412
  return thisValue.getObject(runtime);
254
413
  }
255
414
 
256
- // TODO-API: Property?
257
- JSI_HOST_FUNCTION(setIsVolatile) {
258
- auto v = arguments[0].getBool();
259
- getObject()->setIsVolatile(v);
415
+ JSI_HOST_FUNCTION(op) {
416
+ warnDeprecatedPathMethod(runtime, "op", "Use Skia.Path.MakeFromOp() instead.");
417
+ auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
418
+ auto pathOp = static_cast<SkPathOp>(static_cast<int>(arguments[1].asNumber()));
419
+ auto p1 = asPath();
420
+ auto p2 = path2->snapshot();
421
+ auto result = ::Op(p1, p2, pathOp);
422
+ if (result.has_value()) {
423
+ *getObject() = SkPathBuilder(result.value());
424
+ }
260
425
  return thisValue.getObject(runtime);
261
426
  }
262
427
 
263
- JSI_HOST_FUNCTION(isVolatile) {
264
- return jsi::Value(getObject()->isVolatile());
428
+ JSI_HOST_FUNCTION(makeAsWinding) {
429
+ warnDeprecatedPathMethod(runtime, "makeAsWinding",
430
+ "Use Skia.Path.AsWinding(path) instead.");
431
+ auto path = asPath();
432
+ auto result = ::AsWinding(path);
433
+ if (result.has_value()) {
434
+ *getObject() = SkPathBuilder(result.value());
435
+ }
436
+ return thisValue.getObject(runtime);
265
437
  }
266
438
 
267
- JSI_HOST_FUNCTION(transform) {
268
- auto m3 = *JsiSkMatrix::fromValue(runtime, arguments[0]);
269
- getObject()->transform(m3);
439
+ JSI_HOST_FUNCTION(dash) {
440
+ warnDeprecatedPathMethod(runtime, "dash",
441
+ "Use Skia.Path.Dash(path, on, off, phase) instead.");
442
+ auto path = asPath();
443
+ SkScalar on = arguments[0].asNumber();
444
+ SkScalar off = arguments[1].asNumber();
445
+ auto phase = arguments[2].asNumber();
446
+ SkScalar intervals[] = {on, off};
447
+ auto pe = SkDashPathEffect::Make(SkSpan(intervals, 2), phase);
448
+ if (pe) {
449
+ SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
450
+ SkPathBuilder resultBuilder;
451
+ if (pe->filterPath(&resultBuilder, path, &rec)) {
452
+ *getObject() = std::move(resultBuilder);
453
+ }
454
+ }
270
455
  return thisValue.getObject(runtime);
271
456
  }
272
457
 
273
458
  JSI_HOST_FUNCTION(stroke) {
274
- auto path = *getObject();
275
- auto opts = arguments[0].asObject(runtime);
459
+ warnDeprecatedPathMethod(runtime, "stroke",
460
+ "Use Skia.Path.Stroke(path, opts) instead.");
461
+ auto path = asPath();
276
462
  SkPaint p;
277
463
  p.setStyle(SkPaint::kStroke_Style);
278
464
 
279
- auto jsiCap = opts.getProperty(runtime, "cap");
280
- if (!jsiCap.isUndefined()) {
281
- auto cap = (SkPaint::Cap)jsiCap.asNumber();
282
- p.setStrokeCap(cap);
283
- }
465
+ if (count > 0 && !arguments[0].isUndefined()) {
466
+ auto opts = arguments[0].asObject(runtime);
284
467
 
285
- auto jsiJoin = opts.getProperty(runtime, "join");
286
- if (!jsiJoin.isUndefined()) {
287
- auto join = (SkPaint::Join)jsiJoin.asNumber();
288
- p.setStrokeJoin(join);
289
- }
468
+ auto jsiCap = opts.getProperty(runtime, "cap");
469
+ if (!jsiCap.isUndefined()) {
470
+ p.setStrokeCap(static_cast<SkPaint::Cap>(static_cast<int>(jsiCap.asNumber())));
471
+ }
290
472
 
291
- auto jsiWidth = opts.getProperty(runtime, "width");
292
- if (!jsiWidth.isUndefined()) {
293
- auto width = jsiWidth.asNumber();
294
- p.setStrokeWidth(width);
295
- }
473
+ auto jsiJoin = opts.getProperty(runtime, "join");
474
+ if (!jsiJoin.isUndefined()) {
475
+ p.setStrokeJoin(static_cast<SkPaint::Join>(static_cast<int>(jsiJoin.asNumber())));
476
+ }
477
+
478
+ auto jsiWidth = opts.getProperty(runtime, "width");
479
+ if (!jsiWidth.isUndefined()) {
480
+ p.setStrokeWidth(jsiWidth.asNumber());
481
+ }
296
482
 
297
- auto jsiMiterLimit = opts.getProperty(runtime, "miter_limit");
298
- if (!jsiMiterLimit.isUndefined()) {
299
- auto miter_limit = opts.getProperty(runtime, "miter_limit").asNumber();
300
- p.setStrokeMiter(miter_limit);
483
+ auto jsiMiterLimit = opts.getProperty(runtime, "miter_limit");
484
+ if (!jsiMiterLimit.isUndefined()) {
485
+ p.setStrokeMiter(jsiMiterLimit.asNumber());
486
+ }
301
487
  }
302
488
 
303
- auto jsiPrecision = opts.getProperty(runtime, "precision");
304
- auto precision = jsiPrecision.isUndefined() ? 1 : jsiPrecision.asNumber();
305
- auto result =
306
- skpathutils::FillPathWithPaint(path, p, &path, nullptr, precision);
307
- if (result) {
308
- getObject()->swap(path);
489
+ SkPathBuilder resultBuilder;
490
+ auto success = skpathutils::FillPathWithPaint(path, p, &resultBuilder);
491
+ if (success) {
492
+ *getObject() = std::move(resultBuilder);
309
493
  }
310
- return result ? thisValue.getObject(runtime) : jsi::Value::null();
494
+ return thisValue.getObject(runtime);
311
495
  }
312
496
 
313
497
  JSI_HOST_FUNCTION(trim) {
314
- auto start = pinT(arguments[0].asNumber());
315
- auto end = pinT(arguments[1].asNumber());
498
+ warnDeprecatedPathMethod(runtime,
499
+ "trim", "Use Skia.Path.Trim(path, start, end, isComplement) instead.");
500
+ auto path = asPath();
501
+ float start =
502
+ std::clamp(static_cast<float>(arguments[0].asNumber()), 0.0f, 1.0f);
503
+ float end =
504
+ std::clamp(static_cast<float>(arguments[1].asNumber()), 0.0f, 1.0f);
316
505
  auto isComplement = arguments[2].getBool();
317
- auto path = *getObject();
318
506
  auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted
319
507
  : SkTrimPathEffect::Mode::kNormal;
320
508
  auto pe = SkTrimPathEffect::Make(start, end, mode);
321
- SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
322
- if (!pe) {
323
- return thisValue.getObject(runtime);
324
- }
325
- if (pe->filterPath(&path, path, &rec, nullptr)) {
326
- getObject()->swap(path);
327
- return thisValue.getObject(runtime);
328
- }
329
- return jsi::Value::null();
330
- }
331
-
332
- JSI_HOST_FUNCTION(getPoint) {
333
- auto index = arguments[0].asNumber();
334
- auto point = getObject()->getPoint(index);
335
- auto hostObjectInstance = std::make_shared<JsiSkPoint>(getContext(), point);
336
- return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
337
- runtime, hostObjectInstance, getContext());
338
- }
339
-
340
- JSI_HOST_FUNCTION(toSVGString) {
341
- SkPath path = *getObject();
342
- auto s = SkParsePath::ToSVGString(path);
343
- return jsi::String::createFromUtf8(runtime, s.c_str());
344
- }
345
-
346
- JSI_HOST_FUNCTION(makeAsWinding) {
347
- SkPath out;
348
- if (AsWinding(*getObject(), &out)) {
349
- getObject()->swap(out);
350
- return thisValue.getObject(runtime);
509
+ if (pe) {
510
+ SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
511
+ SkPathBuilder resultBuilder;
512
+ if (pe->filterPath(&resultBuilder, path, &rec)) {
513
+ *getObject() = std::move(resultBuilder);
514
+ }
351
515
  }
352
- return jsi::Value::null();
353
- }
354
-
355
- JSI_HOST_FUNCTION(isEmpty) { return jsi::Value(getObject()->isEmpty()); }
356
-
357
- JSI_HOST_FUNCTION(offset) {
358
- SkScalar dx = arguments[0].asNumber();
359
- SkScalar dy = arguments[1].asNumber();
360
- getObject()->offset(dx, dy);
361
516
  return thisValue.getObject(runtime);
362
517
  }
363
518
 
364
- JSI_HOST_FUNCTION(moveTo) {
365
- SkScalar x = arguments[0].asNumber();
366
- SkScalar y = arguments[1].asNumber();
367
- getObject()->moveTo(x, y);
368
- return thisValue.getObject(runtime);
369
- }
519
+ // Query methods
370
520
 
371
- JSI_HOST_FUNCTION(rMoveTo) {
372
- SkScalar x = arguments[0].asNumber();
373
- SkScalar y = arguments[1].asNumber();
374
- getObject()->rMoveTo(x, y);
375
- return thisValue.getObject(runtime);
376
- }
377
- JSI_HOST_FUNCTION(lineTo) {
378
- SkScalar x = arguments[0].asNumber();
379
- SkScalar y = arguments[1].asNumber();
380
- getObject()->lineTo(x, y);
381
- return thisValue.getObject(runtime);
382
- }
383
-
384
- JSI_HOST_FUNCTION(rLineTo) {
385
- SkScalar x = arguments[0].asNumber();
386
- SkScalar y = arguments[1].asNumber();
387
- getObject()->rLineTo(x, y);
388
- return thisValue.getObject(runtime);
521
+ JSI_HOST_FUNCTION(computeTightBounds) {
522
+ auto path = asPath();
523
+ auto result = path.computeTightBounds();
524
+ auto hostObjectInstance = std::make_shared<JsiSkRect>(getContext(), result);
525
+ return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
526
+ runtime, hostObjectInstance, getContext());
389
527
  }
390
528
 
391
- JSI_HOST_FUNCTION(cubicTo) {
392
- auto x1 = arguments[0].asNumber();
393
- auto y1 = arguments[1].asNumber();
394
- auto x2 = arguments[2].asNumber();
395
- auto y2 = arguments[3].asNumber();
396
- auto x3 = arguments[4].asNumber();
397
- auto y3 = arguments[5].asNumber();
398
- getObject()->cubicTo(x1, y1, x2, y2, x3, y3);
399
- return thisValue.getObject(runtime);
529
+ JSI_HOST_FUNCTION(getBounds) {
530
+ auto result = getObject()->computeBounds();
531
+ auto hostObjectInstance = std::make_shared<JsiSkRect>(getContext(), result);
532
+ return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
533
+ runtime, hostObjectInstance, getContext());
400
534
  }
401
535
 
402
- JSI_HOST_FUNCTION(rCubicTo) {
403
- auto x1 = arguments[0].asNumber();
404
- auto y1 = arguments[1].asNumber();
405
- auto x2 = arguments[2].asNumber();
406
- auto y2 = arguments[3].asNumber();
407
- auto x3 = arguments[4].asNumber();
408
- auto y3 = arguments[5].asNumber();
409
- getObject()->rCubicTo(x1, y1, x2, y2, x3, y3);
410
- return thisValue.getObject(runtime);
536
+ JSI_HOST_FUNCTION(contains) {
537
+ auto x = arguments[0].asNumber();
538
+ auto y = arguments[1].asNumber();
539
+ return jsi::Value(asPath().contains(x, y));
411
540
  }
412
541
 
413
- JSI_HOST_FUNCTION(reset) {
414
- getObject()->reset();
415
- return thisValue.getObject(runtime);
542
+ JSI_HOST_FUNCTION(getFillType) {
543
+ auto fillType = getObject()->fillType();
544
+ return jsi::Value(static_cast<int>(fillType));
416
545
  }
417
546
 
418
- JSI_HOST_FUNCTION(rewind) {
419
- getObject()->rewind();
420
- return thisValue.getObject(runtime);
547
+ JSI_HOST_FUNCTION(isVolatile) {
548
+ return jsi::Value(asPath().isVolatile());
421
549
  }
422
550
 
423
- JSI_HOST_FUNCTION(quadTo) {
424
- auto x1 = arguments[0].asNumber();
425
- auto y1 = arguments[1].asNumber();
426
- auto x2 = arguments[2].asNumber();
427
- auto y2 = arguments[3].asNumber();
428
- getObject()->quadTo(x1, y1, x2, y2);
429
- return thisValue.getObject(runtime);
551
+ JSI_HOST_FUNCTION(getPoint) {
552
+ auto index = arguments[0].asNumber();
553
+ auto point = asPath().getPoint(index);
554
+ auto hostObjectInstance = std::make_shared<JsiSkPoint>(getContext(), point);
555
+ return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
556
+ runtime, hostObjectInstance, getContext());
430
557
  }
431
558
 
432
- JSI_HOST_FUNCTION(rQuadTo) {
433
- auto x1 = arguments[0].asNumber();
434
- auto y1 = arguments[1].asNumber();
435
- auto x2 = arguments[2].asNumber();
436
- auto y2 = arguments[3].asNumber();
437
- getObject()->rQuadTo(x1, y1, x2, y2);
438
- return thisValue.getObject(runtime);
439
- }
559
+ JSI_HOST_FUNCTION(isEmpty) { return jsi::Value(getObject()->isEmpty()); }
440
560
 
441
- JSI_HOST_FUNCTION(addCircle) {
442
- auto x = arguments[0].asNumber();
443
- auto y = arguments[1].asNumber();
444
- auto r = arguments[2].asNumber();
445
- getObject()->addCircle(x, y, r);
446
- return thisValue.getObject(runtime);
561
+ JSI_HOST_FUNCTION(countPoints) {
562
+ auto points = asPath().countPoints();
563
+ return jsi::Value(points);
447
564
  }
448
565
 
449
566
  JSI_HOST_FUNCTION(getLastPt) {
450
- SkPoint last;
451
- getObject()->getLastPt(&last);
567
+ auto last = getObject()->getLastPt();
452
568
  auto point = jsi::Object(runtime);
453
- point.setProperty(runtime, "x", static_cast<double>(last.fX));
454
- point.setProperty(runtime, "y", static_cast<double>(last.fY));
569
+ if (last.has_value()) {
570
+ point.setProperty(runtime, "x", static_cast<double>(last->fX));
571
+ point.setProperty(runtime, "y", static_cast<double>(last->fY));
572
+ } else {
573
+ point.setProperty(runtime, "x", 0.0);
574
+ point.setProperty(runtime, "y", 0.0);
575
+ }
455
576
  return point;
456
577
  }
457
578
 
458
- JSI_HOST_FUNCTION(close) {
459
- getObject()->close();
460
- return thisValue.getObject(runtime);
461
- }
462
-
463
- JSI_HOST_FUNCTION(simplify) {
464
- SkPath result;
465
- if (Simplify(*getObject(), &result)) {
466
- getObject()->swap(result);
467
- return jsi::Value(true);
468
- }
469
- return jsi::Value(false);
579
+ JSI_HOST_FUNCTION(toSVGString) {
580
+ auto path = asPath();
581
+ auto s = SkParsePath::ToSVGString(path);
582
+ return jsi::String::createFromUtf8(runtime, s.c_str());
470
583
  }
471
584
 
472
- JSI_HOST_FUNCTION(countPoints) {
473
- auto points = getObject()->countPoints();
474
- return jsi::Value(points);
585
+ JSI_HOST_FUNCTION(equals) {
586
+ auto p1 = JsiSkPath::fromValue(runtime, arguments[0]);
587
+ auto p2 = JsiSkPath::fromValue(runtime, arguments[1]);
588
+ return jsi::Value(p1->snapshot() == p2->snapshot());
475
589
  }
476
590
 
477
591
  JSI_HOST_FUNCTION(copy) {
478
- const auto *path = getObject().get();
592
+ auto path = asPath();
479
593
  auto hostObjectInstance =
480
- std::make_shared<JsiSkPath>(getContext(), SkPath(*path));
594
+ std::make_shared<JsiSkPath>(getContext(), path);
481
595
  return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
482
596
  runtime, hostObjectInstance, getContext());
483
597
  }
484
598
 
485
- JSI_HOST_FUNCTION(op) {
486
- auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
487
- int pathOp = arguments[1].asNumber();
488
- SkPath result;
489
- if (Op(*getObject(), *path2, SkPathOp(pathOp), &result)) {
490
- getObject()->swap(result);
491
- return jsi::Value(true);
492
- }
493
- return jsi::Value(false);
494
- }
495
-
496
599
  JSI_HOST_FUNCTION(isInterpolatable) {
497
600
  auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
498
- return getObject()->isInterpolatable(*path2);
601
+ auto p1 = asPath();
602
+ auto p2 = path2->snapshot();
603
+ return p1.isInterpolatable(p2);
499
604
  }
500
605
 
501
606
  JSI_HOST_FUNCTION(interpolate) {
502
607
  auto path2 = JsiSkPath::fromValue(runtime, arguments[0]);
503
608
  auto weight = arguments[1].asNumber();
504
- if (count > 2 && !arguments[2].isUndefined()) {
505
- auto path3 = JsiSkPath::fromValue(runtime, arguments[2]);
506
- auto succeed = getObject()->interpolate(*path2, weight, path3.get());
507
- if (!succeed) {
508
- return nullptr;
509
- }
510
- return arguments[2].asObject(runtime);
511
- }
609
+ auto p1 = asPath();
610
+ auto p2 = path2->snapshot();
512
611
  SkPath result;
513
- auto succeed = getObject()->interpolate(*path2, weight, &result);
612
+ auto succeed = p1.interpolate(p2, weight, &result);
514
613
  if (!succeed) {
515
- return nullptr;
614
+ return jsi::Value::null();
516
615
  }
517
616
  auto hostObjectInstance =
518
617
  std::make_shared<JsiSkPath>(getContext(), std::move(result));
519
618
  return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
520
619
  runtime, hostObjectInstance, getContext());
521
620
  }
621
+
522
622
  JSI_HOST_FUNCTION(toCmds) {
523
- auto path = *getObject();
623
+ auto path = asPath();
524
624
  std::vector<jsi::Array> cmdList;
525
625
  SkPoint pts[4];
526
626
  SkPath::Iter iter(path, false);
@@ -601,56 +701,84 @@ public:
601
701
  EXPORT_JSI_API_TYPENAME(JsiSkPath, Path)
602
702
 
603
703
  JSI_EXPORT_FUNCTIONS(
604
- JSI_EXPORT_FUNC(JsiSkPath, addPath), JSI_EXPORT_FUNC(JsiSkPath, addArc),
605
- JSI_EXPORT_FUNC(JsiSkPath, addOval), JSI_EXPORT_FUNC(JsiSkPath, addPoly),
606
- JSI_EXPORT_FUNC(JsiSkPath, addRect), JSI_EXPORT_FUNC(JsiSkPath, addRRect),
704
+ // Mutable building methods
705
+ JSI_EXPORT_FUNC(JsiSkPath, moveTo),
706
+ JSI_EXPORT_FUNC(JsiSkPath, rMoveTo),
707
+ JSI_EXPORT_FUNC(JsiSkPath, lineTo),
708
+ JSI_EXPORT_FUNC(JsiSkPath, rLineTo),
709
+ JSI_EXPORT_FUNC(JsiSkPath, quadTo),
710
+ JSI_EXPORT_FUNC(JsiSkPath, rQuadTo),
711
+ JSI_EXPORT_FUNC(JsiSkPath, conicTo),
712
+ JSI_EXPORT_FUNC(JsiSkPath, rConicTo),
713
+ JSI_EXPORT_FUNC(JsiSkPath, cubicTo),
714
+ JSI_EXPORT_FUNC(JsiSkPath, rCubicTo),
715
+ JSI_EXPORT_FUNC(JsiSkPath, close),
716
+ JSI_EXPORT_FUNC(JsiSkPath, reset),
717
+ JSI_EXPORT_FUNC(JsiSkPath, rewind),
718
+ JSI_EXPORT_FUNC(JsiSkPath, addPath),
719
+ JSI_EXPORT_FUNC(JsiSkPath, addArc),
720
+ JSI_EXPORT_FUNC(JsiSkPath, addOval),
721
+ JSI_EXPORT_FUNC(JsiSkPath, addRect),
722
+ JSI_EXPORT_FUNC(JsiSkPath, addRRect),
723
+ JSI_EXPORT_FUNC(JsiSkPath, addCircle),
724
+ JSI_EXPORT_FUNC(JsiSkPath, addPoly),
607
725
  JSI_EXPORT_FUNC(JsiSkPath, arcToOval),
608
726
  JSI_EXPORT_FUNC(JsiSkPath, arcToRotated),
609
727
  JSI_EXPORT_FUNC(JsiSkPath, rArcTo),
610
728
  JSI_EXPORT_FUNC(JsiSkPath, arcToTangent),
729
+ JSI_EXPORT_FUNC(JsiSkPath, setFillType),
730
+ JSI_EXPORT_FUNC(JsiSkPath, setIsVolatile),
731
+ // Mutable transform methods
732
+ JSI_EXPORT_FUNC(JsiSkPath, transform),
733
+ JSI_EXPORT_FUNC(JsiSkPath, offset),
734
+ // Mutable path operations
735
+ JSI_EXPORT_FUNC(JsiSkPath, simplify),
736
+ JSI_EXPORT_FUNC(JsiSkPath, op),
737
+ JSI_EXPORT_FUNC(JsiSkPath, makeAsWinding),
738
+ JSI_EXPORT_FUNC(JsiSkPath, dash),
739
+ JSI_EXPORT_FUNC(JsiSkPath, stroke),
740
+ JSI_EXPORT_FUNC(JsiSkPath, trim),
741
+ // Query methods
611
742
  JSI_EXPORT_FUNC(JsiSkPath, computeTightBounds),
612
743
  JSI_EXPORT_FUNC(JsiSkPath, getBounds),
613
- JSI_EXPORT_FUNC(JsiSkPath, conicTo), JSI_EXPORT_FUNC(JsiSkPath, rConicTo),
614
- JSI_EXPORT_FUNC(JsiSkPath, contains), JSI_EXPORT_FUNC(JsiSkPath, dash),
615
- JSI_EXPORT_FUNC(JsiSkPath, equals),
744
+ JSI_EXPORT_FUNC(JsiSkPath, contains),
616
745
  JSI_EXPORT_FUNC(JsiSkPath, getFillType),
617
- JSI_EXPORT_FUNC(JsiSkPath, setFillType),
618
- JSI_EXPORT_FUNC(JsiSkPath, setIsVolatile),
619
746
  JSI_EXPORT_FUNC(JsiSkPath, isVolatile),
620
- JSI_EXPORT_FUNC(JsiSkPath, transform), JSI_EXPORT_FUNC(JsiSkPath, stroke),
621
- JSI_EXPORT_FUNC(JsiSkPath, trim), JSI_EXPORT_FUNC(JsiSkPath, getPoint),
747
+ JSI_EXPORT_FUNC(JsiSkPath, getPoint),
748
+ JSI_EXPORT_FUNC(JsiSkPath, isEmpty),
749
+ JSI_EXPORT_FUNC(JsiSkPath, countPoints),
750
+ JSI_EXPORT_FUNC(JsiSkPath, getLastPt),
622
751
  JSI_EXPORT_FUNC(JsiSkPath, toSVGString),
623
- JSI_EXPORT_FUNC(JsiSkPath, makeAsWinding),
624
- JSI_EXPORT_FUNC(JsiSkPath, isEmpty), JSI_EXPORT_FUNC(JsiSkPath, offset),
625
- JSI_EXPORT_FUNC(JsiSkPath, moveTo), JSI_EXPORT_FUNC(JsiSkPath, rMoveTo),
626
- JSI_EXPORT_FUNC(JsiSkPath, lineTo), JSI_EXPORT_FUNC(JsiSkPath, rLineTo),
627
- JSI_EXPORT_FUNC(JsiSkPath, cubicTo), JSI_EXPORT_FUNC(JsiSkPath, rCubicTo),
628
- JSI_EXPORT_FUNC(JsiSkPath, reset), JSI_EXPORT_FUNC(JsiSkPath, rewind),
629
- JSI_EXPORT_FUNC(JsiSkPath, quadTo), JSI_EXPORT_FUNC(JsiSkPath, rQuadTo),
630
- JSI_EXPORT_FUNC(JsiSkPath, addCircle),
631
- JSI_EXPORT_FUNC(JsiSkPath, getLastPt), JSI_EXPORT_FUNC(JsiSkPath, close),
632
- JSI_EXPORT_FUNC(JsiSkPath, simplify),
633
- JSI_EXPORT_FUNC(JsiSkPath, countPoints), JSI_EXPORT_FUNC(JsiSkPath, copy),
634
- JSI_EXPORT_FUNC(JsiSkPath, op),
752
+ JSI_EXPORT_FUNC(JsiSkPath, equals),
753
+ JSI_EXPORT_FUNC(JsiSkPath, copy),
635
754
  JSI_EXPORT_FUNC(JsiSkPath, isInterpolatable),
636
755
  JSI_EXPORT_FUNC(JsiSkPath, interpolate),
637
- JSI_EXPORT_FUNC(JsiSkPath, toCmds), JSI_EXPORT_FUNC(JsiSkPath, dispose))
756
+ JSI_EXPORT_FUNC(JsiSkPath, toCmds),
757
+ JSI_EXPORT_FUNC(JsiSkPath, dispose))
758
+
759
+ JsiSkPath(std::shared_ptr<RNSkPlatformContext> context, SkPathBuilder builder)
760
+ : JsiSkWrappingSharedPtrHostObject<SkPathBuilder>(
761
+ std::move(context),
762
+ std::make_shared<SkPathBuilder>(std::move(builder))) {}
638
763
 
639
- JsiSkPath(std::shared_ptr<RNSkPlatformContext> context, SkPath path)
640
- : JsiSkWrappingSharedPtrHostObject<SkPath>(
641
- std::move(context), std::make_shared<SkPath>(std::move(path))) {}
764
+ // Convenience: construct from SkPath
765
+ JsiSkPath(std::shared_ptr<RNSkPlatformContext> context, const SkPath &path)
766
+ : JsiSkPath(std::move(context), SkPathBuilder(path)) {}
642
767
 
643
768
  size_t getMemoryPressure() const override {
644
- auto path = getObject();
645
- if (!path)
769
+ auto builder = getObject();
770
+ if (!builder)
646
771
  return 0;
647
772
 
648
- // SkPath provides approximateBytesUsed() to estimate memory usage
649
- return path->approximateBytesUsed();
773
+ return builder->snapshot().approximateBytesUsed();
650
774
  }
651
775
 
652
776
  std::string getObjectType() const override { return "JsiSkPath"; }
653
777
 
778
+ static SkPath pathFromValue(jsi::Runtime &runtime, const jsi::Value &obj) {
779
+ return fromValue(runtime, obj)->snapshot();
780
+ }
781
+
654
782
  static jsi::Value toValue(jsi::Runtime &runtime,
655
783
  std::shared_ptr<RNSkPlatformContext> context,
656
784
  const SkPath &path) {