@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
@@ -0,0 +1,293 @@
1
+ import type { CanvasKit, PathBuilder as CKPathBuilder } from "canvaskit-wasm";
2
+
3
+ import type {
4
+ FillType,
5
+ InputMatrix,
6
+ InputRRect,
7
+ SkMatrix,
8
+ SkPath,
9
+ SkPathBuilder,
10
+ SkPoint,
11
+ SkRect,
12
+ } from "../types";
13
+
14
+ import { getEnum, HostObject } from "./Host";
15
+ import { JsiSkPath, toMatrix3x3 } from "./JsiSkPath";
16
+ import { JsiSkMatrix } from "./JsiSkMatrix";
17
+ import { JsiSkPoint } from "./JsiSkPoint";
18
+ import { JsiSkRect } from "./JsiSkRect";
19
+ import { JsiSkRRect } from "./JsiSkRRect";
20
+
21
+ /**
22
+ * Web implementation of SkPathBuilder using CanvasKit's native PathBuilder.
23
+ */
24
+ export class JsiSkPathBuilder
25
+ extends HostObject<CKPathBuilder, "PathBuilder">
26
+ implements SkPathBuilder
27
+ {
28
+ constructor(CanvasKit: CanvasKit, ref: CKPathBuilder) {
29
+ super(CanvasKit, ref, "PathBuilder");
30
+ }
31
+
32
+ // Movement methods
33
+ moveTo(x: number, y: number) {
34
+ this.ref.moveTo(x, y);
35
+ return this;
36
+ }
37
+
38
+ rMoveTo(x: number, y: number) {
39
+ this.ref.rMoveTo(x, y);
40
+ return this;
41
+ }
42
+
43
+ lineTo(x: number, y: number) {
44
+ this.ref.lineTo(x, y);
45
+ return this;
46
+ }
47
+
48
+ rLineTo(x: number, y: number) {
49
+ this.ref.rLineTo(x, y);
50
+ return this;
51
+ }
52
+
53
+ // Curve methods
54
+ quadTo(x1: number, y1: number, x2: number, y2: number) {
55
+ this.ref.quadTo(x1, y1, x2, y2);
56
+ return this;
57
+ }
58
+
59
+ rQuadTo(x1: number, y1: number, x2: number, y2: number) {
60
+ this.ref.rQuadTo(x1, y1, x2, y2);
61
+ return this;
62
+ }
63
+
64
+ conicTo(x1: number, y1: number, x2: number, y2: number, w: number) {
65
+ this.ref.conicTo(x1, y1, x2, y2, w);
66
+ return this;
67
+ }
68
+
69
+ rConicTo(x1: number, y1: number, x2: number, y2: number, w: number) {
70
+ this.ref.rConicTo(x1, y1, x2, y2, w);
71
+ return this;
72
+ }
73
+
74
+ cubicTo(
75
+ x1: number,
76
+ y1: number,
77
+ x2: number,
78
+ y2: number,
79
+ x3: number,
80
+ y3: number
81
+ ) {
82
+ this.ref.cubicTo(x1, y1, x2, y2, x3, y3);
83
+ return this;
84
+ }
85
+
86
+ rCubicTo(
87
+ x1: number,
88
+ y1: number,
89
+ x2: number,
90
+ y2: number,
91
+ x3: number,
92
+ y3: number
93
+ ) {
94
+ this.ref.rCubicTo(x1, y1, x2, y2, x3, y3);
95
+ return this;
96
+ }
97
+
98
+ close() {
99
+ this.ref.close();
100
+ return this;
101
+ }
102
+
103
+ // Arc methods
104
+ arcToOval(
105
+ oval: SkRect,
106
+ startAngleInDegrees: number,
107
+ sweepAngleInDegrees: number,
108
+ forceMoveTo: boolean
109
+ ) {
110
+ this.ref.arcToOval(
111
+ JsiSkRect.fromValue(this.CanvasKit, oval),
112
+ startAngleInDegrees,
113
+ sweepAngleInDegrees,
114
+ forceMoveTo
115
+ );
116
+ return this;
117
+ }
118
+
119
+ arcToRotated(
120
+ rx: number,
121
+ ry: number,
122
+ xAxisRotateInDegrees: number,
123
+ useSmallArc: boolean,
124
+ isCCW: boolean,
125
+ x: number,
126
+ y: number
127
+ ) {
128
+ this.ref.arcToRotated(
129
+ rx,
130
+ ry,
131
+ xAxisRotateInDegrees,
132
+ useSmallArc,
133
+ isCCW,
134
+ x,
135
+ y
136
+ );
137
+ return this;
138
+ }
139
+
140
+ rArcTo(
141
+ rx: number,
142
+ ry: number,
143
+ xAxisRotateInDegrees: number,
144
+ useSmallArc: boolean,
145
+ isCCW: boolean,
146
+ dx: number,
147
+ dy: number
148
+ ) {
149
+ this.ref.rArcTo(rx, ry, xAxisRotateInDegrees, useSmallArc, isCCW, dx, dy);
150
+ return this;
151
+ }
152
+
153
+ arcToTangent(x1: number, y1: number, x2: number, y2: number, radius: number) {
154
+ this.ref.arcToTangent(x1, y1, x2, y2, radius);
155
+ return this;
156
+ }
157
+
158
+ // Shape methods
159
+ addRect(rect: SkRect, isCCW?: boolean) {
160
+ this.ref.addRect(JsiSkRect.fromValue(this.CanvasKit, rect), isCCW);
161
+ return this;
162
+ }
163
+
164
+ addOval(oval: SkRect, isCCW?: boolean, startIndex?: number) {
165
+ this.ref.addOval(
166
+ JsiSkRect.fromValue(this.CanvasKit, oval),
167
+ isCCW,
168
+ startIndex
169
+ );
170
+ return this;
171
+ }
172
+
173
+ addArc(
174
+ oval: SkRect,
175
+ startAngleInDegrees: number,
176
+ sweepAngleInDegrees: number
177
+ ) {
178
+ this.ref.addArc(
179
+ JsiSkRect.fromValue(this.CanvasKit, oval),
180
+ startAngleInDegrees,
181
+ sweepAngleInDegrees
182
+ );
183
+ return this;
184
+ }
185
+
186
+ addRRect(rrect: InputRRect, isCCW?: boolean) {
187
+ this.ref.addRRect(JsiSkRRect.fromValue(this.CanvasKit, rrect), isCCW);
188
+ return this;
189
+ }
190
+
191
+ addCircle(x: number, y: number, r: number, _isCCW?: boolean) {
192
+ this.ref.addCircle(x, y, r);
193
+ return this;
194
+ }
195
+
196
+ addPoly(points: SkPoint[], close: boolean) {
197
+ this.ref.addPolygon(
198
+ points.map((p) => Array.from(JsiSkPoint.fromValue(p))).flat(),
199
+ close
200
+ );
201
+ return this;
202
+ }
203
+
204
+ addPath(src: SkPath, matrix?: SkMatrix, extend = false) {
205
+ const srcPath = JsiSkPath.pathFromValue(src);
206
+ const args = [
207
+ srcPath,
208
+ ...(matrix ? JsiSkMatrix.fromValue<Float32Array>(matrix) : []),
209
+ extend,
210
+ ];
211
+ this.ref.addPath(...args);
212
+ srcPath.delete();
213
+ return this;
214
+ }
215
+
216
+ // Configuration methods
217
+ setFillType(fill: FillType) {
218
+ this.ref.setFillType(getEnum(this.CanvasKit, "FillType", fill));
219
+ return this;
220
+ }
221
+
222
+ setIsVolatile(_isVolatile: boolean) {
223
+ // Not supported in CanvasKit PathBuilder - no-op
224
+ return this;
225
+ }
226
+
227
+ reset() {
228
+ // CanvasKit PathBuilder doesn't have reset - recreate
229
+ const newBuilder = new this.CanvasKit.PathBuilder();
230
+ // Swap the ref - delete old one
231
+ if (
232
+ this.ref !== null &&
233
+ typeof this.ref === "object" &&
234
+ "delete" in this.ref &&
235
+ typeof this.ref.delete === "function"
236
+ ) {
237
+ this.ref.delete();
238
+ }
239
+ this.ref = newBuilder;
240
+ return this;
241
+ }
242
+
243
+ offset(dx: number, dy: number) {
244
+ this.ref.offset(dx, dy);
245
+ return this;
246
+ }
247
+
248
+ transform(m: InputMatrix) {
249
+ const matrix = toMatrix3x3(m);
250
+ this.ref.transform(matrix);
251
+ return this;
252
+ }
253
+
254
+ // Query methods
255
+ computeBounds(): SkRect {
256
+ return new JsiSkRect(this.CanvasKit, this.ref.getBounds());
257
+ }
258
+
259
+ isEmpty(): boolean {
260
+ return this.ref.isEmpty();
261
+ }
262
+
263
+ getLastPt(): { x: number; y: number } {
264
+ const count = this.ref.countPoints();
265
+ if (count === 0) {
266
+ return { x: 0, y: 0 };
267
+ }
268
+ // PathBuilder doesn't have getPoint - snapshot to get it
269
+ const path = this.ref.snapshot();
270
+ const pt = path.getPoint(count - 1);
271
+ path.delete();
272
+ return { x: pt[0], y: pt[1] };
273
+ }
274
+
275
+ countPoints(): number {
276
+ return this.ref.countPoints();
277
+ }
278
+
279
+ // Build methods
280
+ build(): SkPath {
281
+ const path = this.ref.snapshot();
282
+ const builder = new this.CanvasKit.PathBuilder(path);
283
+ path.delete();
284
+ return new JsiSkPath(this.CanvasKit, builder);
285
+ }
286
+
287
+ detach(): SkPath {
288
+ const path = this.ref.detach();
289
+ const builder = new this.CanvasKit.PathBuilder(path);
290
+ path.delete();
291
+ return new JsiSkPath(this.CanvasKit, builder);
292
+ }
293
+ }
@@ -0,0 +1,32 @@
1
+ import type { CanvasKit } from "canvaskit-wasm";
2
+
3
+ import type { PathBuilderFactory, SkPath } from "../types";
4
+
5
+ import { Host } from "./Host";
6
+ import { JsiSkPath } from "./JsiSkPath";
7
+ import { JsiSkPathBuilder } from "./JsiSkPathBuilder";
8
+
9
+ export class JsiSkPathBuilderFactory
10
+ extends Host
11
+ implements PathBuilderFactory
12
+ {
13
+ constructor(CanvasKit: CanvasKit) {
14
+ super(CanvasKit);
15
+ }
16
+
17
+ Make() {
18
+ return new JsiSkPathBuilder(
19
+ this.CanvasKit,
20
+ new this.CanvasKit.PathBuilder()
21
+ );
22
+ }
23
+
24
+ MakeFromPath(path: SkPath) {
25
+ const srcBuilder =
26
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(path);
27
+ const srcPath = srcBuilder.snapshot();
28
+ const builder = new this.CanvasKit.PathBuilder(srcPath);
29
+ srcPath.delete();
30
+ return new JsiSkPathBuilder(this.CanvasKit, builder);
31
+ }
32
+ }
@@ -65,12 +65,14 @@ export class JsiSkPathEffectFactory extends Host implements PathEffectFactory {
65
65
  phase: number,
66
66
  style: Path1DEffectStyle
67
67
  ) {
68
+ const p = JsiSkPath.pathFromValue(path);
68
69
  const pe = this.CanvasKit.PathEffect.MakePath1D(
69
- JsiSkPath.fromValue(path),
70
+ p,
70
71
  advance,
71
72
  phase,
72
73
  getEnum(this.CanvasKit, "Path1DEffect", style)
73
74
  );
75
+ p.delete();
74
76
  if (pe === null) {
75
77
  return null;
76
78
  }
@@ -78,10 +80,12 @@ export class JsiSkPathEffectFactory extends Host implements PathEffectFactory {
78
80
  }
79
81
 
80
82
  MakePath2D(matrix: SkMatrix, path: SkPath) {
83
+ const p = JsiSkPath.pathFromValue(path);
81
84
  const pe = this.CanvasKit.PathEffect.MakePath2D(
82
85
  JsiSkMatrix.fromValue(matrix),
83
- JsiSkPath.fromValue(path)
86
+ p
84
87
  );
88
+ p.delete();
85
89
  if (pe === null) {
86
90
  return null;
87
91
  }
@@ -1,10 +1,24 @@
1
1
  import type { CanvasKit } from "canvaskit-wasm";
2
2
 
3
- import type { PathCommand, PathOp, SkFont, SkPath } from "../types";
3
+ import type {
4
+ InputRRect,
5
+ PathCommand,
6
+ PathOp,
7
+ SkFont,
8
+ SkPath,
9
+ SkPoint,
10
+ SkRect,
11
+ StrokeOpts,
12
+ } from "../types";
4
13
  import type { PathFactory } from "../types/Path/PathFactory";
5
14
 
6
- import { Host, getEnum, throwNotImplementedOnRNWeb } from "./Host";
15
+ import { Host, getEnum, optEnum, throwNotImplementedOnRNWeb } from "./Host";
7
16
  import { JsiSkPath } from "./JsiSkPath";
17
+ import { JsiSkPoint } from "./JsiSkPoint";
18
+ import { JsiSkRect } from "./JsiSkRect";
19
+ import { JsiSkRRect } from "./JsiSkRRect";
20
+
21
+ const pinT = (t: number) => Math.min(Math.max(t, 0), 1);
8
22
 
9
23
  export class JsiSkPathFactory extends Host implements PathFactory {
10
24
  constructor(CanvasKit: CanvasKit) {
@@ -12,7 +26,7 @@ export class JsiSkPathFactory extends Host implements PathFactory {
12
26
  }
13
27
 
14
28
  Make() {
15
- return new JsiSkPath(this.CanvasKit, new this.CanvasKit.Path());
29
+ return new JsiSkPath(this.CanvasKit, new this.CanvasKit.PathBuilder());
16
30
  }
17
31
 
18
32
  MakeFromSVGString(str: string) {
@@ -20,19 +34,39 @@ export class JsiSkPathFactory extends Host implements PathFactory {
20
34
  if (path === null) {
21
35
  return null;
22
36
  }
23
- return new JsiSkPath(this.CanvasKit, path);
37
+ const result = new JsiSkPath(
38
+ this.CanvasKit,
39
+ new this.CanvasKit.PathBuilder(path)
40
+ );
41
+ path.delete();
42
+ return result;
24
43
  }
25
44
 
26
45
  MakeFromOp(one: SkPath, two: SkPath, op: PathOp) {
46
+ const p1 =
47
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
48
+ one
49
+ ).snapshot();
50
+ const p2 =
51
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
52
+ two
53
+ ).snapshot();
27
54
  const path = this.CanvasKit.Path.MakeFromOp(
28
- JsiSkPath.fromValue(one),
29
- JsiSkPath.fromValue(two),
55
+ p1,
56
+ p2,
30
57
  getEnum(this.CanvasKit, "PathOp", op)
31
58
  );
59
+ p1.delete();
60
+ p2.delete();
32
61
  if (path === null) {
33
62
  return null;
34
63
  }
35
- return new JsiSkPath(this.CanvasKit, path);
64
+ const result = new JsiSkPath(
65
+ this.CanvasKit,
66
+ new this.CanvasKit.PathBuilder(path)
67
+ );
68
+ path.delete();
69
+ return result;
36
70
  }
37
71
 
38
72
  MakeFromCmds(cmds: PathCommand[]) {
@@ -40,10 +74,199 @@ export class JsiSkPathFactory extends Host implements PathFactory {
40
74
  if (path === null) {
41
75
  return null;
42
76
  }
43
- return new JsiSkPath(this.CanvasKit, path);
77
+ const result = new JsiSkPath(
78
+ this.CanvasKit,
79
+ new this.CanvasKit.PathBuilder(path)
80
+ );
81
+ path.delete();
82
+ return result;
44
83
  }
45
84
 
46
85
  MakeFromText(_text: string, _x: number, _y: number, _font: SkFont) {
47
86
  return throwNotImplementedOnRNWeb<SkPath>();
48
87
  }
88
+
89
+ // Static shape factories
90
+
91
+ Rect(rect: SkRect, isCCW?: boolean) {
92
+ const builder = new this.CanvasKit.PathBuilder();
93
+ builder.addRect(JsiSkRect.fromValue(this.CanvasKit, rect), isCCW);
94
+ return new JsiSkPath(this.CanvasKit, builder);
95
+ }
96
+
97
+ Oval(rect: SkRect, isCCW?: boolean, startIndex?: number) {
98
+ const builder = new this.CanvasKit.PathBuilder();
99
+ builder.addOval(
100
+ JsiSkRect.fromValue(this.CanvasKit, rect),
101
+ isCCW,
102
+ startIndex
103
+ );
104
+ return new JsiSkPath(this.CanvasKit, builder);
105
+ }
106
+
107
+ Circle(x: number, y: number, r: number) {
108
+ const builder = new this.CanvasKit.PathBuilder();
109
+ builder.addCircle(x, y, r);
110
+ return new JsiSkPath(this.CanvasKit, builder);
111
+ }
112
+
113
+ RRect(rrect: InputRRect, isCCW?: boolean) {
114
+ const builder = new this.CanvasKit.PathBuilder();
115
+ builder.addRRect(JsiSkRRect.fromValue(this.CanvasKit, rrect), isCCW);
116
+ return new JsiSkPath(this.CanvasKit, builder);
117
+ }
118
+
119
+ Line(p1: SkPoint, p2: SkPoint) {
120
+ const builder = new this.CanvasKit.PathBuilder();
121
+ const pt1 = JsiSkPoint.fromValue(p1);
122
+ const pt2 = JsiSkPoint.fromValue(p2);
123
+ builder.moveTo(pt1[0], pt1[1]);
124
+ builder.lineTo(pt2[0], pt2[1]);
125
+ return new JsiSkPath(this.CanvasKit, builder);
126
+ }
127
+
128
+ Polygon(points: SkPoint[], close: boolean) {
129
+ const builder = new this.CanvasKit.PathBuilder();
130
+ builder.addPolygon(
131
+ points.map((p) => Array.from(JsiSkPoint.fromValue(p))).flat(),
132
+ close
133
+ );
134
+ return new JsiSkPath(this.CanvasKit, builder);
135
+ }
136
+
137
+ // Static path operations
138
+
139
+ Stroke(srcPath: SkPath, opts?: StrokeOpts) {
140
+ const path =
141
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
142
+ srcPath
143
+ ).snapshot();
144
+ const result = path.makeStroked(
145
+ opts === undefined
146
+ ? undefined
147
+ : {
148
+ width: opts.width,
149
+ // eslint-disable-next-line camelcase
150
+ miter_limit: opts.miter_limit,
151
+ precision: opts.precision,
152
+ join: optEnum(this.CanvasKit, "StrokeJoin", opts.join),
153
+ cap: optEnum(this.CanvasKit, "StrokeCap", opts.cap),
154
+ }
155
+ );
156
+ path.delete();
157
+ if (result === null) {
158
+ return null;
159
+ }
160
+ const r = new JsiSkPath(
161
+ this.CanvasKit,
162
+ new this.CanvasKit.PathBuilder(result)
163
+ );
164
+ result.delete();
165
+ return r;
166
+ }
167
+
168
+ Trim(srcPath: SkPath, start: number, end: number, isComplement: boolean) {
169
+ const startT = pinT(start);
170
+ const stopT = pinT(end);
171
+ const path =
172
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
173
+ srcPath
174
+ ).snapshot();
175
+ if (startT <= 0 && stopT >= 1 && !isComplement) {
176
+ const r = new JsiSkPath(
177
+ this.CanvasKit,
178
+ new this.CanvasKit.PathBuilder(path)
179
+ );
180
+ path.delete();
181
+ return r;
182
+ }
183
+ const result = path.makeTrimmed(startT, stopT, isComplement);
184
+ path.delete();
185
+ if (result === null) {
186
+ return null;
187
+ }
188
+ const r = new JsiSkPath(
189
+ this.CanvasKit,
190
+ new this.CanvasKit.PathBuilder(result)
191
+ );
192
+ result.delete();
193
+ return r;
194
+ }
195
+
196
+ Simplify(srcPath: SkPath) {
197
+ const path =
198
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
199
+ srcPath
200
+ ).snapshot();
201
+ const result = path.makeSimplified();
202
+ path.delete();
203
+ if (result === null) {
204
+ return null;
205
+ }
206
+ const r = new JsiSkPath(
207
+ this.CanvasKit,
208
+ new this.CanvasKit.PathBuilder(result)
209
+ );
210
+ result.delete();
211
+ return r;
212
+ }
213
+
214
+ Dash(srcPath: SkPath, on: number, off: number, phase: number) {
215
+ const path =
216
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
217
+ srcPath
218
+ ).snapshot();
219
+ const result = path.makeDashed(on, off, phase);
220
+ path.delete();
221
+ if (result === null) {
222
+ return null;
223
+ }
224
+ const r = new JsiSkPath(
225
+ this.CanvasKit,
226
+ new this.CanvasKit.PathBuilder(result)
227
+ );
228
+ result.delete();
229
+ return r;
230
+ }
231
+
232
+ AsWinding(srcPath: SkPath) {
233
+ const path =
234
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
235
+ srcPath
236
+ ).snapshot();
237
+ const result = path.makeAsWinding();
238
+ path.delete();
239
+ if (result === null) {
240
+ return null;
241
+ }
242
+ const r = new JsiSkPath(
243
+ this.CanvasKit,
244
+ new this.CanvasKit.PathBuilder(result)
245
+ );
246
+ result.delete();
247
+ return r;
248
+ }
249
+
250
+ Interpolate(start: SkPath, end: SkPath, weight: number) {
251
+ const p1 =
252
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
253
+ start
254
+ ).snapshot();
255
+ const p2 =
256
+ JsiSkPath.fromValue<CanvasKit["PathBuilder"]["prototype"]>(
257
+ end
258
+ ).snapshot();
259
+ const path = this.CanvasKit.Path.MakeFromPathInterpolation(p1, p2, weight);
260
+ p1.delete();
261
+ p2.delete();
262
+ if (path === null) {
263
+ return null;
264
+ }
265
+ const r = new JsiSkPath(
266
+ this.CanvasKit,
267
+ new this.CanvasKit.PathBuilder(path)
268
+ );
269
+ path.delete();
270
+ return r;
271
+ }
49
272
  }
@@ -23,6 +23,7 @@ import { JsiSkContourMeasureIter } from "./JsiSkContourMeasureIter";
23
23
  import { JsiSkPictureRecorder } from "./JsiSkPictureRecorder";
24
24
  import { JsiSkPictureFactory } from "./JsiSkPictureFactory";
25
25
  import { JsiSkPathFactory } from "./JsiSkPathFactory";
26
+ import { JsiSkPathBuilderFactory } from "./JsiSkPathBuilderFactory";
26
27
  import { JsiSkMatrix } from "./JsiSkMatrix";
27
28
  import { JsiSkColorFilterFactory } from "./JsiSkColorFilterFactory";
28
29
  import { JsiSkTypefaceFactory } from "./JsiSkTypefaceFactory";
@@ -79,14 +80,15 @@ export const JsiSkApi = (CanvasKit: CanvasKit): Skia => ({
79
80
  forceClosed: boolean,
80
81
  resScale: number
81
82
  ): SkContourMeasureIter =>
82
- new JsiSkContourMeasureIter(
83
- CanvasKit,
84
- new CanvasKit.ContourMeasureIter(
85
- JsiSkPath.fromValue(path),
86
- forceClosed,
87
- resScale
88
- )
89
- ),
83
+ (() => {
84
+ const p = JsiSkPath.pathFromValue(path);
85
+ const iter = new JsiSkContourMeasureIter(
86
+ CanvasKit,
87
+ new CanvasKit.ContourMeasureIter(p, forceClosed, resScale)
88
+ );
89
+ p.delete();
90
+ return iter;
91
+ })(),
90
92
  Paint: () => {
91
93
  const paint = new JsiSkPaint(CanvasKit, new CanvasKit.Paint());
92
94
  paint.setAntiAlias(true);
@@ -96,6 +98,7 @@ export const JsiSkApi = (CanvasKit: CanvasKit): Skia => ({
96
98
  new JsiSkPictureRecorder(CanvasKit, new CanvasKit.PictureRecorder()),
97
99
  Picture: new JsiSkPictureFactory(CanvasKit),
98
100
  Path: new JsiSkPathFactory(CanvasKit),
101
+ PathBuilder: new JsiSkPathBuilderFactory(CanvasKit),
99
102
  Matrix: (matrix?: readonly number[]) =>
100
103
  new JsiSkMatrix(
101
104
  CanvasKit,
@@ -214,19 +214,32 @@ export const drawPath = (ctx: DrawingContext, props: PathProps) => {
214
214
  const hasEndOffset = end !== 1;
215
215
  const hasStrokeOptions = stroke !== undefined;
216
216
  const hasFillType = !!fillType;
217
- const willMutatePath =
218
- hasStartOffset || hasEndOffset || hasStrokeOptions || hasFillType;
219
- const pristinePath = processPath(ctx.Skia, pathProps.path);
220
- const path = willMutatePath ? pristinePath.copy() : pristinePath;
217
+
218
+ let path = processPath(ctx.Skia, pathProps.path);
219
+
220
+ // Apply fill type using PathBuilder
221
221
  if (hasFillType) {
222
- path.setFillType(FillType[enumKey(fillType)]);
222
+ const builder = ctx.Skia.PathBuilder.MakeFromPath(path);
223
+ builder.setFillType(FillType[enumKey(fillType)]);
224
+ path = builder.build();
223
225
  }
226
+
227
+ // Apply stroke using static Path.Stroke
224
228
  if (hasStrokeOptions) {
225
- path.stroke(stroke);
229
+ const stroked = ctx.Skia.Path.Stroke(path, stroke);
230
+ if (stroked) {
231
+ path = stroked;
232
+ }
226
233
  }
234
+
235
+ // Apply trim using static Path.Trim
227
236
  if (hasStartOffset || hasEndOffset) {
228
- path.trim(start, end, false);
237
+ const trimmed = ctx.Skia.Path.Trim(path, start, end, false);
238
+ if (trimmed) {
239
+ path = trimmed;
240
+ }
229
241
  }
242
+
230
243
  ctx.canvas.drawPath(path, ctx.paint);
231
244
  };
232
245