@shopify/react-native-skia 2.13.0 → 2.14.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 (124) hide show
  1. package/android/CMakeLists.txt +2 -0
  2. package/android/cpp/jni/include/JniSkiaPictureView.h +16 -15
  3. package/android/cpp/rnskia-android/OpenGLContext.h +1 -1
  4. package/android/cpp/rnskia-android/gl/Surface.h +1 -1
  5. package/apple/RNSkApplePlatformContext.h +3 -4
  6. package/apple/RNSkiaModule.h +11 -3
  7. package/apple/RNSkiaModule.mm +46 -19
  8. package/apple/SkiaPictureView.mm +2 -2
  9. package/apple/SkiaUIView.h +0 -1
  10. package/apple/SkiaUIView.mm +1 -1
  11. package/apple/ViewScreenshotService.h +2 -2
  12. package/apple/ViewScreenshotService.mm +5 -4
  13. package/cpp/api/JsiSkImage.h +1 -1
  14. package/cpp/api/JsiSkImageFilter.h +3 -1
  15. package/cpp/api/JsiSkParagraph.h +2 -1
  16. package/cpp/api/JsiSkParagraphBuilder.h +1 -1
  17. package/cpp/api/JsiSkParagraphBuilderFactory.h +1 -1
  18. package/cpp/api/JsiSkPath.h +11 -435
  19. package/cpp/api/JsiSkPathBuilder.h +11 -4
  20. package/cpp/api/JsiSkPictureRecorder.h +2 -1
  21. package/cpp/api/JsiSkShader.h +3 -1
  22. package/cpp/api/JsiSkSkottie.h +29 -28
  23. package/cpp/api/JsiSkStrutStyle.h +1 -1
  24. package/cpp/api/JsiSkSurfaceFactory.h +41 -0
  25. package/cpp/api/recorder/Command.h +1 -1
  26. package/cpp/api/recorder/Convertor.h +153 -132
  27. package/cpp/api/recorder/DataTypes.h +12 -12
  28. package/cpp/api/recorder/DrawingCtx.h +1 -1
  29. package/cpp/api/recorder/ImageFit.h +8 -5
  30. package/cpp/api/recorder/JsiRecorder.h +14 -31
  31. package/cpp/api/recorder/Paint.h +3 -3
  32. package/cpp/api/recorder/RNRecorder.h +56 -0
  33. package/cpp/api/third_party/base64.cpp +1 -1
  34. package/cpp/jsi/JSICache.cpp +23 -0
  35. package/cpp/jsi/JSICache.h +28 -1
  36. package/cpp/jsi/NativeObject.h +36 -7
  37. package/cpp/jsi/ViewProperty.cpp +23 -0
  38. package/cpp/jsi/ViewProperty.h +31 -10
  39. package/cpp/rnskia/RNDawnContext.h +34 -1
  40. package/cpp/rnskia/RNSkJsiViewApi.h +69 -2
  41. package/cpp/rnskia/RNSkPictureView.cpp +58 -0
  42. package/cpp/rnskia/RNSkPictureView.h +110 -24
  43. package/lib/commonjs/Platform/IPlatform.js.map +1 -1
  44. package/lib/commonjs/animation/functions/interpolate.js.map +1 -1
  45. package/lib/commonjs/animation/functions/interpolatePaths.js +18 -0
  46. package/lib/commonjs/animation/functions/interpolatePaths.js.map +1 -1
  47. package/lib/commonjs/skia/core/Image.js.map +1 -1
  48. package/lib/commonjs/skia/types/NativeBuffer/NativeBufferFactory.js.map +1 -1
  49. package/lib/commonjs/skia/types/Path/Path.d.ts +2 -336
  50. package/lib/commonjs/skia/types/Path/Path.js.map +1 -1
  51. package/lib/commonjs/skia/types/Recorder.d.ts +10 -0
  52. package/lib/commonjs/skia/types/Recorder.js.map +1 -1
  53. package/lib/commonjs/skia/types/Shader/Shader.js.map +1 -1
  54. package/lib/commonjs/skia/types/Surface/SurfaceFactory.d.ts +16 -0
  55. package/lib/commonjs/skia/types/Surface/SurfaceFactory.js.map +1 -1
  56. package/lib/commonjs/skia/web/JsiSkPath.d.ts +4 -38
  57. package/lib/commonjs/skia/web/JsiSkPath.js +3 -275
  58. package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
  59. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.d.ts +2 -1
  60. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js +3 -0
  61. package/lib/commonjs/skia/web/JsiSkSurfaceFactory.js.map +1 -1
  62. package/lib/commonjs/sksg/Container.native.d.ts +15 -1
  63. package/lib/commonjs/sksg/Container.native.js +34 -33
  64. package/lib/commonjs/sksg/Container.native.js.map +1 -1
  65. package/lib/commonjs/specs/NativeSkiaModule.web.js +4 -0
  66. package/lib/commonjs/specs/NativeSkiaModule.web.js.map +1 -1
  67. package/lib/commonjs/views/types.d.ts +9 -0
  68. package/lib/commonjs/views/types.js.map +1 -1
  69. package/lib/module/Platform/IPlatform.js.map +1 -1
  70. package/lib/module/animation/functions/interpolate.js.map +1 -1
  71. package/lib/module/animation/functions/interpolatePaths.js +18 -0
  72. package/lib/module/animation/functions/interpolatePaths.js.map +1 -1
  73. package/lib/module/skia/core/Image.js.map +1 -1
  74. package/lib/module/skia/types/NativeBuffer/NativeBufferFactory.js.map +1 -1
  75. package/lib/module/skia/types/Path/Path.d.ts +2 -336
  76. package/lib/module/skia/types/Path/Path.js.map +1 -1
  77. package/lib/module/skia/types/Recorder.d.ts +10 -0
  78. package/lib/module/skia/types/Recorder.js.map +1 -1
  79. package/lib/module/skia/types/Shader/Shader.js.map +1 -1
  80. package/lib/module/skia/types/Surface/SurfaceFactory.d.ts +16 -0
  81. package/lib/module/skia/types/Surface/SurfaceFactory.js.map +1 -1
  82. package/lib/module/skia/web/JsiSkPath.d.ts +4 -38
  83. package/lib/module/skia/web/JsiSkPath.js +4 -276
  84. package/lib/module/skia/web/JsiSkPath.js.map +1 -1
  85. package/lib/module/skia/web/JsiSkSurfaceFactory.d.ts +2 -1
  86. package/lib/module/skia/web/JsiSkSurfaceFactory.js +4 -1
  87. package/lib/module/skia/web/JsiSkSurfaceFactory.js.map +1 -1
  88. package/lib/module/sksg/Container.native.d.ts +15 -1
  89. package/lib/module/sksg/Container.native.js +34 -33
  90. package/lib/module/sksg/Container.native.js.map +1 -1
  91. package/lib/module/specs/NativeSkiaModule.web.js +4 -0
  92. package/lib/module/specs/NativeSkiaModule.web.js.map +1 -1
  93. package/lib/module/views/types.d.ts +9 -0
  94. package/lib/module/views/types.js.map +1 -1
  95. package/lib/typescript/lib/commonjs/skia/web/JsiSkPath.d.ts +1 -35
  96. package/lib/typescript/lib/commonjs/skia/web/JsiSkSurfaceFactory.d.ts +1 -0
  97. package/lib/typescript/lib/commonjs/sksg/Container.native.d.ts +15 -1
  98. package/lib/typescript/lib/module/skia/web/JsiSkPath.d.ts +3 -37
  99. package/lib/typescript/lib/module/skia/web/JsiSkSurfaceFactory.d.ts +1 -0
  100. package/lib/typescript/lib/module/sksg/Container.native.d.ts +15 -1
  101. package/lib/typescript/src/skia/types/Path/Path.d.ts +2 -336
  102. package/lib/typescript/src/skia/types/Recorder.d.ts +10 -0
  103. package/lib/typescript/src/skia/types/Surface/SurfaceFactory.d.ts +16 -0
  104. package/lib/typescript/src/skia/web/JsiSkPath.d.ts +4 -38
  105. package/lib/typescript/src/skia/web/JsiSkSurfaceFactory.d.ts +2 -1
  106. package/lib/typescript/src/sksg/Container.native.d.ts +15 -1
  107. package/lib/typescript/src/views/types.d.ts +9 -0
  108. package/package.json +2 -2
  109. package/src/Platform/IPlatform.ts +1 -4
  110. package/src/animation/functions/interpolate.ts +1 -4
  111. package/src/animation/functions/interpolatePaths.ts +24 -0
  112. package/src/skia/core/Image.ts +1 -2
  113. package/src/skia/types/NativeBuffer/NativeBufferFactory.ts +2 -5
  114. package/src/skia/types/Path/Path.ts +2 -420
  115. package/src/skia/types/Recorder.ts +10 -0
  116. package/src/skia/types/Shader/Shader.ts +1 -5
  117. package/src/skia/types/Surface/SurfaceFactory.ts +17 -0
  118. package/src/skia/web/JsiSkPath.ts +4 -495
  119. package/src/skia/web/JsiSkSurfaceFactory.ts +6 -2
  120. package/src/sksg/Container.native.ts +34 -37
  121. package/src/specs/NativeSkiaModule.web.ts +4 -0
  122. package/src/views/types.ts +13 -0
  123. package/apple/SkiaManager.h +0 -23
  124. package/apple/SkiaManager.mm +0 -63
@@ -3,7 +3,6 @@
3
3
  #include <algorithm>
4
4
  #include <memory>
5
5
  #include <optional>
6
- #include <set>
7
6
  #include <string>
8
7
  #include <utility>
9
8
  #include <variant>
@@ -41,29 +40,6 @@ namespace RNSkia {
41
40
 
42
41
  namespace jsi = facebook::jsi;
43
42
 
44
- // Track which deprecation warnings have been shown to avoid spam
45
- inline std::set<std::string> &getShownPathDeprecationWarnings() {
46
- static std::set<std::string> warnings;
47
- return warnings;
48
- }
49
-
50
- inline void warnDeprecatedPathMethod(jsi::Runtime &runtime,
51
- const char *methodName,
52
- const char *suggestion) {
53
- auto &warnings = getShownPathDeprecationWarnings();
54
- if (warnings.find(methodName) != warnings.end()) {
55
- return;
56
- }
57
- warnings.insert(methodName);
58
- std::string message =
59
- std::string("[react-native-skia] SkPath.") + methodName +
60
- "() is deprecated and will be removed in a future release. " +
61
- suggestion +
62
- " See migration guide: "
63
- "https://shopify.github.io/react-native-skia/docs/shapes/path-migration";
64
- RNSkLogger::warnToJavascriptConsole(runtime, message);
65
- }
66
-
67
43
  class JsiSkPath
68
44
  : public JsiSkWrappingSharedPtrNativeObject<JsiSkPath, SkPathBuilder> {
69
45
  public:
@@ -80,343 +56,6 @@ private:
80
56
  SkPath asPath() const { return getObject()->snapshot(); }
81
57
 
82
58
  public:
83
- // Mutable building methods (deprecated) — chainable, and they take the
84
- // runtime for the JS console deprecation warning.
85
-
86
- void moveTo(jsi::Runtime &runtime, double x, double y) {
87
- warnDeprecatedPathMethod(runtime, "moveTo",
88
- "Use Skia.PathBuilder.Make().moveTo() instead.");
89
- getObject()->moveTo(x, y);
90
- }
91
-
92
- void rMoveTo(jsi::Runtime &runtime, double x, double y) {
93
- warnDeprecatedPathMethod(runtime, "rMoveTo",
94
- "Use Skia.PathBuilder.Make().rMoveTo() instead.");
95
- getObject()->rMoveTo({static_cast<SkScalar>(x), static_cast<SkScalar>(y)});
96
- }
97
-
98
- void lineTo(jsi::Runtime &runtime, double x, double y) {
99
- warnDeprecatedPathMethod(runtime, "lineTo",
100
- "Use Skia.PathBuilder.Make().lineTo() instead.");
101
- getObject()->lineTo(x, y);
102
- }
103
-
104
- void rLineTo(jsi::Runtime &runtime, double x, double y) {
105
- warnDeprecatedPathMethod(runtime, "rLineTo",
106
- "Use Skia.PathBuilder.Make().rLineTo() instead.");
107
- getObject()->rLineTo(x, y);
108
- }
109
-
110
- void quadTo(jsi::Runtime &runtime, double x1, double y1, double x2,
111
- double y2) {
112
- warnDeprecatedPathMethod(runtime, "quadTo",
113
- "Use Skia.PathBuilder.Make().quadTo() instead.");
114
- getObject()->quadTo(x1, y1, x2, y2);
115
- }
116
-
117
- void rQuadTo(jsi::Runtime &runtime, double x1, double y1, double x2,
118
- double y2) {
119
- warnDeprecatedPathMethod(runtime, "rQuadTo",
120
- "Use Skia.PathBuilder.Make().rQuadTo() instead.");
121
- getObject()->rQuadTo(x1, y1, x2, y2);
122
- }
123
-
124
- void conicTo(jsi::Runtime &runtime, double x1, double y1, double x2,
125
- double y2, double w) {
126
- warnDeprecatedPathMethod(runtime, "conicTo",
127
- "Use Skia.PathBuilder.Make().conicTo() instead.");
128
- getObject()->conicTo(x1, y1, x2, y2, w);
129
- }
130
-
131
- void rConicTo(jsi::Runtime &runtime, double x1, double y1, double x2,
132
- double y2, double w) {
133
- warnDeprecatedPathMethod(runtime, "rConicTo",
134
- "Use Skia.PathBuilder.Make().rConicTo() instead.");
135
- getObject()->rConicTo(x1, y1, x2, y2, w);
136
- }
137
-
138
- void cubicTo(jsi::Runtime &runtime, double x1, double y1, double x2,
139
- double y2, double x3, double y3) {
140
- warnDeprecatedPathMethod(runtime, "cubicTo",
141
- "Use Skia.PathBuilder.Make().cubicTo() instead.");
142
- getObject()->cubicTo(x1, y1, x2, y2, x3, y3);
143
- }
144
-
145
- void rCubicTo(jsi::Runtime &runtime, double x1, double y1, double x2,
146
- double y2, double x3, double y3) {
147
- warnDeprecatedPathMethod(runtime, "rCubicTo",
148
- "Use Skia.PathBuilder.Make().rCubicTo() instead.");
149
- getObject()->rCubicTo(x1, y1, x2, y2, x3, y3);
150
- }
151
-
152
- void close(jsi::Runtime &runtime) {
153
- warnDeprecatedPathMethod(runtime, "close",
154
- "Use Skia.PathBuilder.Make().close() instead.");
155
- getObject()->close();
156
- }
157
-
158
- void reset(jsi::Runtime &runtime) {
159
- warnDeprecatedPathMethod(runtime, "reset",
160
- "Use Skia.PathBuilder.Make().reset() instead.");
161
- getObject()->reset();
162
- }
163
-
164
- void rewind(jsi::Runtime &runtime) {
165
- warnDeprecatedPathMethod(runtime, "rewind",
166
- "Use Skia.PathBuilder.Make().reset() instead.");
167
- getObject()->reset();
168
- }
169
-
170
- void addPath(jsi::Runtime &runtime, std::shared_ptr<SkPathBuilder> src,
171
- JsiOptional<std::shared_ptr<SkMatrix>> matrix,
172
- JsiOptional<bool> extend) {
173
- warnDeprecatedPathMethod(runtime, "addPath",
174
- "Use Skia.PathBuilder.Make().addPath() instead.");
175
- auto srcPath = src->snapshot();
176
- auto mode = extend.has_value() && *extend ? SkPath::kExtend_AddPathMode
177
- : SkPath::kAppend_AddPathMode;
178
- if (matrix.has_value()) {
179
- getObject()->addPath(srcPath, **matrix, mode);
180
- } else {
181
- getObject()->addPath(srcPath, mode);
182
- }
183
- }
184
-
185
- void addArc(jsi::Runtime &runtime, std::shared_ptr<SkRect> rect,
186
- double start, double sweep) {
187
- warnDeprecatedPathMethod(runtime, "addArc",
188
- "Use Skia.PathBuilder.Make().addArc() instead.");
189
- getObject()->addArc(*rect, start, sweep);
190
- }
191
-
192
- void addOval(jsi::Runtime &runtime, std::shared_ptr<SkRect> rect,
193
- JsiOptional<bool> isCCW, JsiOptional<double> startIndex) {
194
- warnDeprecatedPathMethod(
195
- runtime, "addOval",
196
- "Use Skia.Path.Oval() or Skia.PathBuilder.Make().addOval() instead.");
197
- getObject()->addOval(*rect, toDirection(isCCW),
198
- startIndex.has_value()
199
- ? static_cast<unsigned>(*startIndex)
200
- : 1);
201
- }
202
-
203
- void addRect(jsi::Runtime &runtime, std::shared_ptr<SkRect> rect,
204
- JsiOptional<bool> isCCW) {
205
- warnDeprecatedPathMethod(
206
- runtime, "addRect",
207
- "Use Skia.Path.Rect() or Skia.PathBuilder.Make().addRect() instead.");
208
- getObject()->addRect(*rect, toDirection(isCCW));
209
- }
210
-
211
- void addRRect(jsi::Runtime &runtime, std::shared_ptr<SkRRect> rrect,
212
- JsiOptional<bool> isCCW) {
213
- warnDeprecatedPathMethod(
214
- runtime, "addRRect",
215
- "Use Skia.Path.RRect() or Skia.PathBuilder.Make().addRRect() instead.");
216
- getObject()->addRRect(*rrect, toDirection(isCCW));
217
- }
218
-
219
- void addCircle(jsi::Runtime &runtime, double x, double y, double r) {
220
- warnDeprecatedPathMethod(
221
- runtime, "addCircle",
222
- "Use Skia.Path.Circle() or Skia.PathBuilder.Make().addCircle() "
223
- "instead.");
224
- getObject()->addCircle(x, y, r);
225
- }
226
-
227
- void addPoly(jsi::Runtime &runtime, std::vector<SkPoint> points,
228
- bool close) {
229
- warnDeprecatedPathMethod(
230
- runtime, "addPoly",
231
- "Use Skia.Path.Polygon() or Skia.PathBuilder.Make().addPoly() "
232
- "instead.");
233
- getObject()->addPolygon(SkSpan<const SkPoint>(points.data(), points.size()),
234
- close);
235
- }
236
-
237
- void arcToOval(jsi::Runtime &runtime, std::shared_ptr<SkRect> rect,
238
- double start, double sweep, bool forceMoveTo) {
239
- warnDeprecatedPathMethod(
240
- runtime, "arcToOval",
241
- "Use Skia.PathBuilder.Make().arcToOval() instead.");
242
- getObject()->arcTo(*rect, start, sweep, forceMoveTo);
243
- }
244
-
245
- void arcToRotated(jsi::Runtime &runtime, double rx, double ry,
246
- double xAxisRotate, bool useSmallArc, bool isCCW, double x,
247
- double y) {
248
- warnDeprecatedPathMethod(
249
- runtime, "arcToRotated",
250
- "Use Skia.PathBuilder.Make().arcToRotated() instead.");
251
- auto arcSize = useSmallArc ? SkPathBuilder::kSmall_ArcSize
252
- : SkPathBuilder::kLarge_ArcSize;
253
- auto sweep = isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
254
- getObject()->arcTo(SkPoint::Make(rx, ry), xAxisRotate, arcSize, sweep,
255
- SkPoint::Make(x, y));
256
- }
257
-
258
- void rArcTo(jsi::Runtime &runtime, double rx, double ry, double xAxisRotate,
259
- bool useSmallArc, bool isCCW, double dx, double dy) {
260
- warnDeprecatedPathMethod(runtime, "rArcTo",
261
- "Use Skia.PathBuilder.Make().rArcTo() instead.");
262
- auto arcSize = useSmallArc ? SkPathBuilder::kSmall_ArcSize
263
- : SkPathBuilder::kLarge_ArcSize;
264
- auto sweep = isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
265
- SkVector dxdy(dx, dy);
266
- SkPoint r(rx, ry);
267
- getObject()->rArcTo(r, xAxisRotate, arcSize, sweep, dxdy);
268
- }
269
-
270
- void arcToTangent(jsi::Runtime &runtime, double x1, double y1, double x2,
271
- double y2, double r) {
272
- warnDeprecatedPathMethod(
273
- runtime, "arcToTangent",
274
- "Use Skia.PathBuilder.Make().arcToTangent() instead.");
275
- getObject()->arcTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), r);
276
- }
277
-
278
- void setFillType(jsi::Runtime &runtime, double ft) {
279
- warnDeprecatedPathMethod(
280
- runtime, "setFillType",
281
- "Use Skia.PathBuilder.Make().setFillType() instead.");
282
- getObject()->setFillType(static_cast<SkPathFillType>(static_cast<int>(ft)));
283
- }
284
-
285
- void setIsVolatile(jsi::Runtime &runtime, bool v) {
286
- warnDeprecatedPathMethod(
287
- runtime, "setIsVolatile",
288
- "Use Skia.PathBuilder.Make().setIsVolatile() instead.");
289
- getObject()->setIsVolatile(v);
290
- }
291
-
292
- // Mutable transform methods (deprecated)
293
-
294
- void transform(jsi::Runtime &runtime, std::shared_ptr<SkMatrix> m3) {
295
- warnDeprecatedPathMethod(
296
- runtime, "transform",
297
- "Use Skia.PathBuilder.Make().transform() instead.");
298
- getObject()->transform(*m3);
299
- }
300
-
301
- void offset(jsi::Runtime &runtime, double dx, double dy) {
302
- warnDeprecatedPathMethod(runtime, "offset",
303
- "Use Skia.PathBuilder.Make().offset() instead.");
304
- getObject()->offset(dx, dy);
305
- }
306
-
307
- // Mutable path operations (deprecated)
308
-
309
- void simplify(jsi::Runtime &runtime) {
310
- warnDeprecatedPathMethod(runtime, "simplify",
311
- "Use Skia.Path.Simplify(path) instead.");
312
- auto path = asPath();
313
- auto result = ::Simplify(path);
314
- if (result.has_value()) {
315
- *getObject() = SkPathBuilder(result.value());
316
- }
317
- }
318
-
319
- void op(jsi::Runtime &runtime, std::shared_ptr<SkPathBuilder> path2,
320
- double pathOp) {
321
- warnDeprecatedPathMethod(runtime, "op",
322
- "Use Skia.Path.MakeFromOp() instead.");
323
- auto p1 = asPath();
324
- auto p2 = path2->snapshot();
325
- auto result =
326
- ::Op(p1, p2, static_cast<SkPathOp>(static_cast<int>(pathOp)));
327
- if (result.has_value()) {
328
- *getObject() = SkPathBuilder(result.value());
329
- }
330
- }
331
-
332
- void makeAsWinding(jsi::Runtime &runtime) {
333
- warnDeprecatedPathMethod(runtime, "makeAsWinding",
334
- "Use Skia.Path.AsWinding(path) instead.");
335
- auto path = asPath();
336
- auto result = ::AsWinding(path);
337
- if (result.has_value()) {
338
- *getObject() = SkPathBuilder(result.value());
339
- }
340
- }
341
-
342
- void dash(jsi::Runtime &runtime, double on, double off, double phase) {
343
- warnDeprecatedPathMethod(
344
- runtime, "dash", "Use Skia.Path.Dash(path, on, off, phase) instead.");
345
- auto path = asPath();
346
- SkScalar intervals[] = {static_cast<SkScalar>(on),
347
- static_cast<SkScalar>(off)};
348
- auto pe = SkDashPathEffect::Make(SkSpan(intervals, 2), phase);
349
- if (pe) {
350
- SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
351
- SkPathBuilder resultBuilder;
352
- if (pe->filterPath(&resultBuilder, path, &rec)) {
353
- *getObject() = std::move(resultBuilder);
354
- }
355
- }
356
- }
357
-
358
- // Stays raw: the options object is read leniently property by property.
359
- JSI_HOST_FUNCTION(stroke) {
360
- warnDeprecatedPathMethod(runtime, "stroke",
361
- "Use Skia.Path.Stroke(path, opts) instead.");
362
- auto path = asPath();
363
- SkPaint p;
364
- p.setStyle(SkPaint::kStroke_Style);
365
-
366
- if (count > 0 && !arguments[0].isUndefined()) {
367
- auto opts = arguments[0].asObject(runtime);
368
-
369
- auto jsiCap = opts.getProperty(runtime, "cap");
370
- if (!jsiCap.isUndefined()) {
371
- p.setStrokeCap(
372
- static_cast<SkPaint::Cap>(static_cast<int>(jsiCap.asNumber())));
373
- }
374
-
375
- auto jsiJoin = opts.getProperty(runtime, "join");
376
- if (!jsiJoin.isUndefined()) {
377
- p.setStrokeJoin(
378
- static_cast<SkPaint::Join>(static_cast<int>(jsiJoin.asNumber())));
379
- }
380
-
381
- auto jsiWidth = opts.getProperty(runtime, "width");
382
- if (!jsiWidth.isUndefined()) {
383
- p.setStrokeWidth(jsiWidth.asNumber());
384
- }
385
-
386
- auto jsiMiterLimit = opts.getProperty(runtime, "miter_limit");
387
- if (!jsiMiterLimit.isUndefined()) {
388
- p.setStrokeMiter(jsiMiterLimit.asNumber());
389
- }
390
- }
391
-
392
- SkPathBuilder resultBuilder;
393
- auto success = skpathutils::FillPathWithPaint(path, p, &resultBuilder);
394
- if (success) {
395
- *getObject() = std::move(resultBuilder);
396
- }
397
- return thisValue.getObject(runtime);
398
- }
399
-
400
- void trim(jsi::Runtime &runtime, double startValue, double endValue,
401
- bool isComplement) {
402
- warnDeprecatedPathMethod(
403
- runtime, "trim",
404
- "Use Skia.Path.Trim(path, start, end, isComplement) instead.");
405
- auto path = asPath();
406
- float start = std::clamp(static_cast<float>(startValue), 0.0f, 1.0f);
407
- float end = std::clamp(static_cast<float>(endValue), 0.0f, 1.0f);
408
- auto mode = isComplement ? SkTrimPathEffect::Mode::kInverted
409
- : SkTrimPathEffect::Mode::kNormal;
410
- auto pe = SkTrimPathEffect::Make(start, end, mode);
411
- if (pe) {
412
- SkStrokeRec rec(SkStrokeRec::InitStyle::kHairline_InitStyle);
413
- SkPathBuilder resultBuilder;
414
- if (pe->filterPath(&resultBuilder, path, &rec)) {
415
- *getObject() = std::move(resultBuilder);
416
- }
417
- }
418
- }
419
-
420
59
  // Query methods
421
60
 
422
61
  std::shared_ptr<JsiSkRect> computeTightBounds() {
@@ -540,76 +179,6 @@ public:
540
179
 
541
180
  static void definePrototype(jsi::Runtime &runtime, jsi::Object &prototype) {
542
181
  installCommon(runtime, prototype);
543
- // Mutable building methods
544
- installChainableMethodWithRuntime(runtime, prototype, "moveTo",
545
- &JsiSkPath::moveTo);
546
- installChainableMethodWithRuntime(runtime, prototype, "rMoveTo",
547
- &JsiSkPath::rMoveTo);
548
- installChainableMethodWithRuntime(runtime, prototype, "lineTo",
549
- &JsiSkPath::lineTo);
550
- installChainableMethodWithRuntime(runtime, prototype, "rLineTo",
551
- &JsiSkPath::rLineTo);
552
- installChainableMethodWithRuntime(runtime, prototype, "quadTo",
553
- &JsiSkPath::quadTo);
554
- installChainableMethodWithRuntime(runtime, prototype, "rQuadTo",
555
- &JsiSkPath::rQuadTo);
556
- installChainableMethodWithRuntime(runtime, prototype, "conicTo",
557
- &JsiSkPath::conicTo);
558
- installChainableMethodWithRuntime(runtime, prototype, "rConicTo",
559
- &JsiSkPath::rConicTo);
560
- installChainableMethodWithRuntime(runtime, prototype, "cubicTo",
561
- &JsiSkPath::cubicTo);
562
- installChainableMethodWithRuntime(runtime, prototype, "rCubicTo",
563
- &JsiSkPath::rCubicTo);
564
- installChainableMethodWithRuntime(runtime, prototype, "close",
565
- &JsiSkPath::close);
566
- installChainableMethodWithRuntime(runtime, prototype, "reset",
567
- &JsiSkPath::reset);
568
- installChainableMethodWithRuntime(runtime, prototype, "rewind",
569
- &JsiSkPath::rewind);
570
- installChainableMethodWithRuntime(runtime, prototype, "addPath",
571
- &JsiSkPath::addPath);
572
- installChainableMethodWithRuntime(runtime, prototype, "addArc",
573
- &JsiSkPath::addArc);
574
- installChainableMethodWithRuntime(runtime, prototype, "addOval",
575
- &JsiSkPath::addOval);
576
- installChainableMethodWithRuntime(runtime, prototype, "addRect",
577
- &JsiSkPath::addRect);
578
- installChainableMethodWithRuntime(runtime, prototype, "addRRect",
579
- &JsiSkPath::addRRect);
580
- installChainableMethodWithRuntime(runtime, prototype, "addCircle",
581
- &JsiSkPath::addCircle);
582
- installChainableMethodWithRuntime(runtime, prototype, "addPoly",
583
- &JsiSkPath::addPoly);
584
- installChainableMethodWithRuntime(runtime, prototype, "arcToOval",
585
- &JsiSkPath::arcToOval);
586
- installChainableMethodWithRuntime(runtime, prototype, "arcToRotated",
587
- &JsiSkPath::arcToRotated);
588
- installChainableMethodWithRuntime(runtime, prototype, "rArcTo",
589
- &JsiSkPath::rArcTo);
590
- installChainableMethodWithRuntime(runtime, prototype, "arcToTangent",
591
- &JsiSkPath::arcToTangent);
592
- installChainableMethodWithRuntime(runtime, prototype, "setFillType",
593
- &JsiSkPath::setFillType);
594
- installChainableMethodWithRuntime(runtime, prototype, "setIsVolatile",
595
- &JsiSkPath::setIsVolatile);
596
- // Mutable transform methods
597
- installChainableMethodWithRuntime(runtime, prototype, "transform",
598
- &JsiSkPath::transform);
599
- installChainableMethodWithRuntime(runtime, prototype, "offset",
600
- &JsiSkPath::offset);
601
- // Mutable path operations
602
- installChainableMethodWithRuntime(runtime, prototype, "simplify",
603
- &JsiSkPath::simplify);
604
- installChainableMethodWithRuntime(runtime, prototype, "op",
605
- &JsiSkPath::op);
606
- installChainableMethodWithRuntime(runtime, prototype, "makeAsWinding",
607
- &JsiSkPath::makeAsWinding);
608
- installChainableMethodWithRuntime(runtime, prototype, "dash",
609
- &JsiSkPath::dash);
610
- installHostMethod(runtime, prototype, "stroke", &JsiSkPath::stroke);
611
- installChainableMethodWithRuntime(runtime, prototype, "trim",
612
- &JsiSkPath::trim);
613
182
  // Query methods
614
183
  installMethod(runtime, prototype, "computeTightBounds",
615
184
  &JsiSkPath::computeTightBounds);
@@ -640,11 +209,18 @@ public:
640
209
  : JsiSkPath(std::move(context), SkPathBuilder(path)) {}
641
210
 
642
211
  size_t getMemoryPressure() override {
643
- auto builder = getObject();
644
- if (!builder)
212
+ if (isDisposed()) {
645
213
  return 0;
646
-
647
- return builder->snapshot().approximateBytesUsed();
214
+ }
215
+ auto builder = getObjectUnchecked();
216
+ if (!builder) {
217
+ return 0;
218
+ }
219
+ // The point, verb and conic weight arrays of the builder. Snapshotting
220
+ // the path to measure it would copy them, and this runs on every round
221
+ // trip of the object to JS.
222
+ return builder->points().size_bytes() + builder->verbs().size_bytes() +
223
+ builder->conicWeights().size_bytes();
648
224
  }
649
225
 
650
226
  /**
@@ -271,11 +271,18 @@ public:
271
271
  std::make_shared<SkPathBuilder>(std::move(builder))) {}
272
272
 
273
273
  size_t getMemoryPressure() override {
274
- auto builder = getObject();
275
- if (!builder)
274
+ if (isDisposed()) {
276
275
  return 0;
277
- // Estimate memory usage based on snapshot
278
- return builder->snapshot().approximateBytesUsed();
276
+ }
277
+ auto builder = getObjectUnchecked();
278
+ if (!builder) {
279
+ return 0;
280
+ }
281
+ // The point, verb and conic weight arrays of the builder. Snapshotting
282
+ // the path to measure it would copy them, and this runs on every round
283
+ // trip of the object to JS.
284
+ return builder->points().size_bytes() + builder->verbs().size_bytes() +
285
+ builder->conicWeights().size_bytes();
279
286
  }
280
287
 
281
288
  static jsi::Value toValue(jsi::Runtime &runtime,
@@ -58,7 +58,8 @@ public:
58
58
  &JsiSkPictureRecorder::finishRecordingAsPicture);
59
59
  }
60
60
 
61
- size_t getMemoryPressure() override { return 1024 * 1024; }
61
+ // The recorded picture reports its own size once finished.
62
+ size_t getMemoryPressure() override { return kMinMemoryPressure; }
62
63
 
63
64
  static const jsi::HostFunctionType
64
65
  createCtor(std::shared_ptr<RNSkPlatformContext> context) {
@@ -29,7 +29,9 @@ public:
29
29
  : JsiSkWrappingSkPtrNativeObject<JsiSkShader, SkShader>(
30
30
  std::move(context), std::move(shader)) {}
31
31
 
32
- size_t getMemoryPressure() override { return 1024 * 1024; }
32
+ // A shader node is a few hundred bytes; the images it may reference
33
+ // are reported by their own wrappers.
34
+ size_t getMemoryPressure() override { return kMinMemoryPressure; }
33
35
 
34
36
  static sk_sp<SkShader> fromValue(jsi::Runtime &runtime,
35
37
  const jsi::Value &obj) {
@@ -1,5 +1,6 @@
1
1
  #pragma once
2
2
 
3
+ #include <algorithm>
3
4
  #include <memory>
4
5
  #include <optional>
5
6
  #include <string>
@@ -31,9 +32,9 @@
31
32
  #pragma clang diagnostic pop
32
33
 
33
34
  namespace RNSkia {
34
- using namespace facebook;
35
+ namespace jsi = facebook::jsi;
35
36
 
36
- std::unique_ptr<SkCodec> DecodeImageData(sk_sp<SkData> data) {
37
+ inline std::unique_ptr<SkCodec> DecodeImageData(sk_sp<SkData> data) {
37
38
  if (data == nullptr) {
38
39
  return nullptr;
39
40
  }
@@ -74,6 +75,8 @@ public:
74
75
  if (!codec) {
75
76
  return nullptr;
76
77
  }
78
+ // The asset keeps its decoded frame for the lifetime of the animation.
79
+ _decodedImageBytes += codec->getInfo().computeMinByteSize();
77
80
  return skresources::MultiFrameImageAsset::Make(std::move(codec));
78
81
  }
79
82
 
@@ -102,11 +105,16 @@ public:
102
105
  return this->findAsset(name);
103
106
  }
104
107
 
108
+ // Bytes of the decoded images for the assets loaded so far.
109
+ size_t decodedImageBytes() const { return _decodedImageBytes; }
110
+
105
111
  private:
106
112
  explicit SkottieAssetProvider(AssetMap assets, sk_sp<SkFontMgr> fontMgr)
107
113
  : fAssets(std::move(assets)), fFontMgr(std::move(fontMgr)) {}
108
114
  const AssetMap fAssets;
109
115
  const sk_sp<SkFontMgr> fFontMgr;
116
+ // loadImageAsset() is const in skottie::ResourceProvider.
117
+ mutable size_t _decodedImageBytes = 0;
110
118
 
111
119
  sk_sp<SkData> findAsset(const char name[]) const {
112
120
  auto it = fAssets.find(name);
@@ -121,6 +129,12 @@ class ManagedAnimation {
121
129
  public:
122
130
  ManagedAnimation(std::string json, SkottieAssetProvider::AssetMap assets,
123
131
  sk_sp<SkFontMgr> fontMgr) {
132
+ _approximateBytesUsed = json.size();
133
+ for (const auto &asset : assets) {
134
+ if (asset.second) {
135
+ _approximateBytesUsed += asset.second->size();
136
+ }
137
+ }
124
138
  _propManager = std::make_unique<CustomPropertyManager>(
125
139
  CustomPropertyManager::Mode::kCollapseProperties, "");
126
140
  _resourceProvider =
@@ -132,6 +146,8 @@ public:
132
146
  builder->setPropertyObserver(_propManager->getPropertyObserver());
133
147
  _animation = builder->make(json.c_str(), json.size());
134
148
  _slotManager = builder->getSlotManager();
149
+ // Image assets are loaded while the animation is built.
150
+ _approximateBytesUsed += _resourceProvider->decodedImageBytes();
135
151
  }
136
152
 
137
153
  ~ManagedAnimation() {
@@ -151,6 +167,10 @@ public:
151
167
  sk_sp<skottie::SlotManager> _slotManager = nullptr;
152
168
  sk_sp<SkottieAssetProvider> _resourceProvider = nullptr;
153
169
  std::unique_ptr<CustomPropertyManager> _propManager = nullptr;
170
+ // Size of the animation JSON, its encoded assets and its decoded images:
171
+ // the memory the animation actually owns (the scene graph is in the same
172
+ // order as the JSON). Used as the GC hint for the wrapper.
173
+ size_t _approximateBytesUsed = 0;
154
174
  };
155
175
 
156
176
  class JsiSkSkottie
@@ -322,8 +342,7 @@ public:
322
342
  if (!slotID.has_value() || !scalar.has_value()) {
323
343
  return false;
324
344
  }
325
- return getObject()->_slotManager->setScalarSlot(SkString(*slotID),
326
- *scalar);
345
+ return getObject()->_slotManager->setScalarSlot(SkString(*slotID), *scalar);
327
346
  }
328
347
 
329
348
  bool setVec2Slot(JsiOptional<std::string> slotID,
@@ -579,31 +598,13 @@ public:
579
598
 
580
599
  size_t getMemoryPressure() override {
581
600
  auto animation = getObject();
582
- if (!animation || !animation->_animation) {
583
- return 1024; // Base size if no animation
601
+ if (!animation) {
602
+ return kMinMemoryPressure;
584
603
  }
585
-
586
- auto size = animation->_animation->size();
587
- auto duration = animation->_animation->duration();
588
- auto fps = animation->_animation->fps();
589
-
590
- // Estimate memory usage based on animation properties
591
- // Base calculation: width * height * 4 bytes per pixel * estimated frame
592
- // count
593
- size_t frameCount = static_cast<size_t>(duration * fps);
594
- size_t estimatedFrameSize =
595
- static_cast<size_t>(size.width() * size.height() * 4);
596
-
597
- // Conservative estimate: assume some frames are cached
598
- size_t cachedFrames =
599
- std::min(frameCount, static_cast<size_t>(60)); // Max 60 cached frames
600
- size_t animationMemory = estimatedFrameSize * cachedFrames;
601
-
602
- // Add base overhead for animation data structures
603
- size_t baseOverhead =
604
- 64 * 1024; // 64KB for metadata, property managers, etc.
605
-
606
- return animationMemory + baseOverhead;
604
+ // Skottie keeps no frame cache: report the bytes the animation owns.
605
+ // Estimating a pixel cache here (width * height * 4 * 60 frames) charged
606
+ // hundreds of MB per wrapper, and each capture in a worklet repeated it.
607
+ return std::max(animation->_approximateBytesUsed, kMinMemoryPressure);
607
608
  }
608
609
  };
609
610
  } // namespace RNSkia
@@ -20,7 +20,7 @@ namespace jsi = facebook::jsi;
20
20
 
21
21
  namespace para = skia::textlayout;
22
22
 
23
- bool asBool(jsi::Runtime &runtime, const jsi::Value &value) {
23
+ inline bool asBool(jsi::Runtime &runtime, const jsi::Value &value) {
24
24
  if (!value.isBool()) {
25
25
  throw jsi::JSError(runtime, "Expected boolean value");
26
26
  }