@shopify/react-native-skia 2.7.0 → 2.8.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 (110) hide show
  1. package/cpp/api/JsiSkParagraph.h +114 -0
  2. package/lib/commonjs/external/reanimated/useVideoLoading.js +11 -2
  3. package/lib/commonjs/external/reanimated/useVideoLoading.js.map +1 -1
  4. package/lib/commonjs/skia/core/SVG.web.js +4 -5
  5. package/lib/commonjs/skia/core/SVG.web.js.map +1 -1
  6. package/lib/commonjs/skia/types/Paragraph/Paragraph.d.ts +62 -0
  7. package/lib/commonjs/skia/types/Paragraph/Paragraph.js.map +1 -1
  8. package/lib/commonjs/skia/web/Host.js +7 -0
  9. package/lib/commonjs/skia/web/Host.js.map +1 -1
  10. package/lib/commonjs/skia/web/JsiSkPaint.js +5 -0
  11. package/lib/commonjs/skia/web/JsiSkPaint.js.map +1 -1
  12. package/lib/commonjs/skia/web/JsiSkParagraph.d.ts +3 -1
  13. package/lib/commonjs/skia/web/JsiSkParagraph.js +6 -0
  14. package/lib/commonjs/skia/web/JsiSkParagraph.js.map +1 -1
  15. package/lib/commonjs/sksg/Container.web.js +34 -3
  16. package/lib/commonjs/sksg/Container.web.js.map +1 -1
  17. package/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +2 -0
  18. package/lib/commonjs/sksg/Recorder/DrawingContext.js +22 -6
  19. package/lib/commonjs/sksg/Recorder/DrawingContext.js.map +1 -1
  20. package/lib/commonjs/sksg/Recorder/FrameScope.d.ts +18 -0
  21. package/lib/commonjs/sksg/Recorder/FrameScope.js +66 -0
  22. package/lib/commonjs/sksg/Recorder/FrameScope.js.map +1 -0
  23. package/lib/commonjs/sksg/Recorder/FrameScope.native.d.ts +10 -0
  24. package/lib/commonjs/sksg/Recorder/FrameScope.native.js +26 -0
  25. package/lib/commonjs/sksg/Recorder/FrameScope.native.js.map +1 -0
  26. package/lib/commonjs/sksg/Recorder/Player.js +1 -2
  27. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  28. package/lib/commonjs/sksg/Recorder/Recorder.d.ts +3 -1
  29. package/lib/commonjs/sksg/Recorder/Recorder.js +12 -1
  30. package/lib/commonjs/sksg/Recorder/Recorder.js.map +1 -1
  31. package/lib/commonjs/sksg/Recorder/commands/Drawing.js +3 -3
  32. package/lib/commonjs/sksg/Recorder/commands/Drawing.js.map +1 -1
  33. package/lib/commonjs/sksg/Recorder/commands/Shaders.js +3 -3
  34. package/lib/commonjs/sksg/Recorder/commands/Shaders.js.map +1 -1
  35. package/lib/commonjs/sksg/StaticContainer.d.ts +1 -0
  36. package/lib/commonjs/sksg/StaticContainer.js +27 -1
  37. package/lib/commonjs/sksg/StaticContainer.js.map +1 -1
  38. package/lib/module/external/reanimated/useVideoLoading.js +12 -2
  39. package/lib/module/external/reanimated/useVideoLoading.js.map +1 -1
  40. package/lib/module/skia/core/SVG.web.js +4 -5
  41. package/lib/module/skia/core/SVG.web.js.map +1 -1
  42. package/lib/module/skia/types/Paragraph/Paragraph.d.ts +62 -0
  43. package/lib/module/skia/types/Paragraph/Paragraph.js.map +1 -1
  44. package/lib/module/skia/web/Host.js +7 -0
  45. package/lib/module/skia/web/Host.js.map +1 -1
  46. package/lib/module/skia/web/JsiSkPaint.js +5 -0
  47. package/lib/module/skia/web/JsiSkPaint.js.map +1 -1
  48. package/lib/module/skia/web/JsiSkParagraph.d.ts +3 -1
  49. package/lib/module/skia/web/JsiSkParagraph.js +7 -1
  50. package/lib/module/skia/web/JsiSkParagraph.js.map +1 -1
  51. package/lib/module/sksg/Container.web.js +35 -4
  52. package/lib/module/sksg/Container.web.js.map +1 -1
  53. package/lib/module/sksg/Recorder/DrawingContext.d.ts +2 -0
  54. package/lib/module/sksg/Recorder/DrawingContext.js +22 -6
  55. package/lib/module/sksg/Recorder/DrawingContext.js.map +1 -1
  56. package/lib/module/sksg/Recorder/FrameScope.d.ts +18 -0
  57. package/lib/module/sksg/Recorder/FrameScope.js +59 -0
  58. package/lib/module/sksg/Recorder/FrameScope.js.map +1 -0
  59. package/lib/module/sksg/Recorder/FrameScope.native.d.ts +10 -0
  60. package/lib/module/sksg/Recorder/FrameScope.native.js +19 -0
  61. package/lib/module/sksg/Recorder/FrameScope.native.js.map +1 -0
  62. package/lib/module/sksg/Recorder/Player.js +1 -2
  63. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  64. package/lib/module/sksg/Recorder/Recorder.d.ts +3 -1
  65. package/lib/module/sksg/Recorder/Recorder.js +10 -0
  66. package/lib/module/sksg/Recorder/Recorder.js.map +1 -1
  67. package/lib/module/sksg/Recorder/commands/Drawing.js +3 -3
  68. package/lib/module/sksg/Recorder/commands/Drawing.js.map +1 -1
  69. package/lib/module/sksg/Recorder/commands/Shaders.js +3 -3
  70. package/lib/module/sksg/Recorder/commands/Shaders.js.map +1 -1
  71. package/lib/module/sksg/StaticContainer.d.ts +1 -0
  72. package/lib/module/sksg/StaticContainer.js +28 -2
  73. package/lib/module/sksg/StaticContainer.js.map +1 -1
  74. package/lib/typescript/lib/commonjs/skia/web/JsiSkParagraph.d.ts +2 -0
  75. package/lib/typescript/lib/commonjs/sksg/Container.web.d.ts +2 -2
  76. package/lib/typescript/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +2 -0
  77. package/lib/typescript/lib/commonjs/sksg/Recorder/FrameScope.d.ts +17 -0
  78. package/lib/typescript/lib/commonjs/sksg/Recorder/FrameScope.native.d.ts +13 -0
  79. package/lib/typescript/lib/commonjs/sksg/Recorder/Recorder.d.ts +1 -0
  80. package/lib/typescript/lib/commonjs/sksg/StaticContainer.d.ts +2 -2
  81. package/lib/typescript/lib/module/skia/web/JsiSkParagraph.d.ts +2 -0
  82. package/lib/typescript/lib/module/sksg/Container.web.d.ts +2 -2
  83. package/lib/typescript/lib/module/sksg/Recorder/DrawingContext.d.ts +2 -0
  84. package/lib/typescript/lib/module/sksg/Recorder/FrameScope.d.ts +5 -0
  85. package/lib/typescript/lib/module/sksg/Recorder/FrameScope.native.d.ts +5 -0
  86. package/lib/typescript/lib/module/sksg/Recorder/Recorder.d.ts +1 -0
  87. package/lib/typescript/lib/module/sksg/StaticContainer.d.ts +2 -2
  88. package/lib/typescript/src/skia/types/Paragraph/Paragraph.d.ts +62 -0
  89. package/lib/typescript/src/skia/web/JsiSkParagraph.d.ts +3 -1
  90. package/lib/typescript/src/sksg/Recorder/DrawingContext.d.ts +2 -0
  91. package/lib/typescript/src/sksg/Recorder/FrameScope.d.ts +18 -0
  92. package/lib/typescript/src/sksg/Recorder/FrameScope.native.d.ts +10 -0
  93. package/lib/typescript/src/sksg/Recorder/Recorder.d.ts +3 -1
  94. package/lib/typescript/src/sksg/StaticContainer.d.ts +1 -0
  95. package/package.json +1 -1
  96. package/src/external/reanimated/useVideoLoading.ts +12 -2
  97. package/src/skia/core/SVG.web.ts +5 -14
  98. package/src/skia/types/Paragraph/Paragraph.ts +67 -0
  99. package/src/skia/web/Host.ts +7 -0
  100. package/src/skia/web/JsiSkPaint.ts +5 -0
  101. package/src/skia/web/JsiSkParagraph.ts +9 -1
  102. package/src/sksg/Container.web.ts +31 -4
  103. package/src/sksg/Recorder/DrawingContext.ts +19 -6
  104. package/src/sksg/Recorder/FrameScope.native.ts +21 -0
  105. package/src/sksg/Recorder/FrameScope.ts +69 -0
  106. package/src/sksg/Recorder/Player.ts +1 -2
  107. package/src/sksg/Recorder/Recorder.ts +15 -1
  108. package/src/sksg/Recorder/commands/Drawing.ts +3 -3
  109. package/src/sksg/Recorder/commands/Shaders.ts +22 -16
  110. package/src/sksg/StaticContainer.ts +29 -2
@@ -8,6 +8,7 @@
8
8
  #include <jsi/jsi.h>
9
9
 
10
10
  #include "JsiSkCanvas.h"
11
+ #include "JsiSkFont.h"
11
12
  #include "JsiSkHostObjects.h"
12
13
  #include "JsiSkPath.h"
13
14
  #include "JsiSkRect.h"
@@ -141,6 +142,117 @@ public:
141
142
  return returnValue;
142
143
  }
143
144
 
145
+ JSI_HOST_FUNCTION(getPath) {
146
+ auto lineNumber =
147
+ static_cast<int>(getArgumentAsNumber(runtime, arguments, count, 0));
148
+ auto paragraph = getObject();
149
+ // Paragraph::getPath does not bounds-check the line number.
150
+ if (lineNumber < 0 ||
151
+ static_cast<size_t>(lineNumber) >= paragraph->lineNumber()) {
152
+ return jsi::Value::null();
153
+ }
154
+ // Paragraph::getPath resets its path builder after every visual run, so
155
+ // for lines shaped as multiple runs (e.g. through font fallback) it only
156
+ // returns the glyphs of the last run. Build the path from the per-glyph
157
+ // data exposed by extendedVisit instead.
158
+ SkPathBuilder builder;
159
+ paragraph->extendedVisit(
160
+ [lineNumber, &builder](
161
+ int visitedLine, const para::Paragraph::ExtendedVisitorInfo *info) {
162
+ if (visitedLine != lineNumber || info == nullptr) {
163
+ return;
164
+ }
165
+ struct Rec {
166
+ SkPathBuilder *builder;
167
+ SkPoint origin;
168
+ const SkPoint *pos;
169
+ } rec = {&builder, info->origin, info->positions};
170
+ info->font.getPaths(
171
+ {info->glyphs, static_cast<size_t>(info->count)},
172
+ [](const SkPath *src, const SkMatrix &mx, void *ctx) {
173
+ auto *rec = static_cast<Rec *>(ctx);
174
+ if (src != nullptr) {
175
+ SkMatrix total = mx;
176
+ total.postTranslate(rec->origin.fX + rec->pos->fX,
177
+ rec->origin.fY + rec->pos->fY);
178
+ rec->builder->addPath(*src, total);
179
+ }
180
+ rec->pos += 1;
181
+ },
182
+ &rec);
183
+ });
184
+ SkPath path = builder.detach();
185
+ auto hostObjectInstance =
186
+ std::make_shared<JsiSkPath>(getContext(), std::move(path));
187
+ return JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
188
+ runtime, hostObjectInstance, getContext());
189
+ }
190
+
191
+ JSI_HOST_FUNCTION(extendedVisit) {
192
+ auto visitorObject = getArgumentAsFunction(runtime, arguments, count, 0);
193
+ auto visitor = visitorObject.asFunction(runtime);
194
+ auto context = getContext();
195
+ getObject()->extendedVisit(
196
+ [&runtime, &visitor, &context](
197
+ int lineNumber, const para::Paragraph::ExtendedVisitorInfo *info) {
198
+ if (info == nullptr) {
199
+ // Signals the end of the line
200
+ visitor.call(runtime, static_cast<double>(lineNumber),
201
+ jsi::Value::null());
202
+ return;
203
+ }
204
+ auto value = jsi::Object(runtime);
205
+
206
+ auto fontInstance = std::make_shared<JsiSkFont>(context, info->font);
207
+ value.setProperty(runtime, "font",
208
+ JSI_CREATE_HOST_OBJECT_WITH_MEMORY_PRESSURE(
209
+ runtime, fontInstance, context));
210
+
211
+ auto origin = jsi::Object(runtime);
212
+ origin.setProperty(runtime, "x",
213
+ static_cast<double>(info->origin.x()));
214
+ origin.setProperty(runtime, "y",
215
+ static_cast<double>(info->origin.y()));
216
+ value.setProperty(runtime, "origin", origin);
217
+
218
+ auto advance = jsi::Object(runtime);
219
+ advance.setProperty(runtime, "width",
220
+ static_cast<double>(info->advance.width()));
221
+ advance.setProperty(runtime, "height",
222
+ static_cast<double>(info->advance.height()));
223
+ value.setProperty(runtime, "advance", advance);
224
+
225
+ auto size = info->count;
226
+ auto glyphs = jsi::Array(runtime, size);
227
+ auto positions = jsi::Array(runtime, size);
228
+ auto bounds = jsi::Array(runtime, size);
229
+ auto utf8Starts = jsi::Array(runtime, size);
230
+ for (int i = 0; i < size; ++i) {
231
+ glyphs.setValueAtIndex(runtime, i,
232
+ static_cast<double>(info->glyphs[i]));
233
+ auto position = jsi::Object(runtime);
234
+ position.setProperty(runtime, "x",
235
+ static_cast<double>(info->positions[i].x()));
236
+ position.setProperty(runtime, "y",
237
+ static_cast<double>(info->positions[i].y()));
238
+ positions.setValueAtIndex(runtime, i, position);
239
+ bounds.setValueAtIndex(
240
+ runtime, i,
241
+ JsiSkRect::toValue(runtime, context, info->bounds[i]));
242
+ utf8Starts.setValueAtIndex(
243
+ runtime, i, static_cast<double>(info->utf8Starts[i]));
244
+ }
245
+ value.setProperty(runtime, "glyphs", glyphs);
246
+ value.setProperty(runtime, "positions", positions);
247
+ value.setProperty(runtime, "bounds", bounds);
248
+ value.setProperty(runtime, "utf8Starts", utf8Starts);
249
+ value.setProperty(runtime, "flags", static_cast<double>(info->flags));
250
+
251
+ visitor.call(runtime, static_cast<double>(lineNumber), value);
252
+ });
253
+ return jsi::Value::undefined();
254
+ }
255
+
144
256
  JSI_HOST_FUNCTION(getRectsForPlaceholders) {
145
257
  std::vector<para::TextBox> placeholderInfos =
146
258
  getObject()->getRectsForPlaceholders();
@@ -169,6 +281,8 @@ public:
169
281
  getGlyphPositionAtCoordinate),
170
282
  JSI_EXPORT_FUNC(JsiSkParagraph, getRectsForRange),
171
283
  JSI_EXPORT_FUNC(JsiSkParagraph, getLineMetrics),
284
+ JSI_EXPORT_FUNC(JsiSkParagraph, getPath),
285
+ JSI_EXPORT_FUNC(JsiSkParagraph, extendedVisit),
172
286
  JSI_EXPORT_FUNC(JsiSkParagraph, dispose))
173
287
 
174
288
  size_t getMemoryPressure() const override { return 1024 * 1024; }
@@ -8,7 +8,16 @@ var _react = require("react");
8
8
  var _skia = require("../../skia");
9
9
  var _ReanimatedProxy = _interopRequireDefault(require("./ReanimatedProxy"));
10
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
- const runtime = _ReanimatedProxy.default.createWorkletRuntime("video-metadata-runtime");
11
+ // Created lazily: accessing the proxy at module scope would require
12
+ // react-native-reanimated as soon as the package is imported, and would spawn
13
+ // the runtime even for apps that never load a video.
14
+ let runtime;
15
+ const getRuntime = () => {
16
+ if (runtime === undefined) {
17
+ runtime = _ReanimatedProxy.default.createWorkletRuntime("video-metadata-runtime");
18
+ }
19
+ return runtime;
20
+ };
12
21
  const useVideoLoading = source => {
13
22
  const {
14
23
  runOnJS
@@ -22,7 +31,7 @@ const useVideoLoading = source => {
22
31
  }, [runOnJS]);
23
32
  (0, _react.useEffect)(() => {
24
33
  if (source) {
25
- _ReanimatedProxy.default.runOnRuntime(runtime, cb)(source);
34
+ _ReanimatedProxy.default.runOnRuntime(getRuntime(), cb)(source);
26
35
  }
27
36
  }, [cb, source]);
28
37
  return video;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_skia","_ReanimatedProxy","_interopRequireDefault","e","__esModule","default","runtime","Rea","createWorkletRuntime","useVideoLoading","source","runOnJS","video","setVideo","useState","cb","useCallback","src","vid","Skia","Video","useEffect","runOnRuntime","exports"],"sources":["useVideoLoading.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\nimport type { Video } from \"../../skia/types\";\nimport { Skia } from \"../../skia\";\n\nimport Rea from \"./ReanimatedProxy\";\n\nconst runtime = Rea.createWorkletRuntime(\"video-metadata-runtime\");\n\ntype VideoSource = string | null;\n\nexport const useVideoLoading = (source: VideoSource) => {\n const { runOnJS } = Rea;\n const [video, setVideo] = useState<Video | null>(null);\n const cb = useCallback(\n (src: string) => {\n \"worklet\";\n const vid = Skia.Video(src) as Video;\n runOnJS(setVideo)(vid);\n },\n [runOnJS]\n );\n useEffect(() => {\n if (source) {\n Rea.runOnRuntime(runtime, cb)(source);\n }\n }, [cb, source]);\n return video;\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAGA,IAAAC,KAAA,GAAAD,OAAA;AAEA,IAAAE,gBAAA,GAAAC,sBAAA,CAAAH,OAAA;AAAoC,SAAAG,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEpC,MAAMG,OAAO,GAAGC,wBAAG,CAACC,oBAAoB,CAAC,wBAAwB,CAAC;AAI3D,MAAMC,eAAe,GAAIC,MAAmB,IAAK;EACtD,MAAM;IAAEC;EAAQ,CAAC,GAAGJ,wBAAG;EACvB,MAAM,CAACK,KAAK,EAAEC,QAAQ,CAAC,GAAG,IAAAC,eAAQ,EAAe,IAAI,CAAC;EACtD,MAAMC,EAAE,GAAG,IAAAC,kBAAW,EACnBC,GAAW,IAAK;IACf,SAAS;;IACT,MAAMC,GAAG,GAAGC,UAAI,CAACC,KAAK,CAACH,GAAG,CAAU;IACpCN,OAAO,CAACE,QAAQ,CAAC,CAACK,GAAG,CAAC;EACxB,CAAC,EACD,CAACP,OAAO,CACV,CAAC;EACD,IAAAU,gBAAS,EAAC,MAAM;IACd,IAAIX,MAAM,EAAE;MACVH,wBAAG,CAACe,YAAY,CAAChB,OAAO,EAAES,EAAE,CAAC,CAACL,MAAM,CAAC;IACvC;EACF,CAAC,EAAE,CAACK,EAAE,EAAEL,MAAM,CAAC,CAAC;EAChB,OAAOE,KAAK;AACd,CAAC;AAACW,OAAA,CAAAd,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_skia","_ReanimatedProxy","_interopRequireDefault","e","__esModule","default","runtime","getRuntime","undefined","Rea","createWorkletRuntime","useVideoLoading","source","runOnJS","video","setVideo","useState","cb","useCallback","src","vid","Skia","Video","useEffect","runOnRuntime","exports"],"sources":["useVideoLoading.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport type { WorkletRuntime } from \"react-native-reanimated\";\n\nimport type { Video } from \"../../skia/types\";\nimport { Skia } from \"../../skia\";\n\nimport Rea from \"./ReanimatedProxy\";\n\n// Created lazily: accessing the proxy at module scope would require\n// react-native-reanimated as soon as the package is imported, and would spawn\n// the runtime even for apps that never load a video.\nlet runtime: WorkletRuntime | undefined;\nconst getRuntime = () => {\n if (runtime === undefined) {\n runtime = Rea.createWorkletRuntime(\"video-metadata-runtime\");\n }\n return runtime;\n};\n\ntype VideoSource = string | null;\n\nexport const useVideoLoading = (source: VideoSource) => {\n const { runOnJS } = Rea;\n const [video, setVideo] = useState<Video | null>(null);\n const cb = useCallback(\n (src: string) => {\n \"worklet\";\n const vid = Skia.Video(src) as Video;\n runOnJS(setVideo)(vid);\n },\n [runOnJS]\n );\n useEffect(() => {\n if (source) {\n Rea.runOnRuntime(getRuntime(), cb)(source);\n }\n }, [cb, source]);\n return video;\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAIA,IAAAC,KAAA,GAAAD,OAAA;AAEA,IAAAE,gBAAA,GAAAC,sBAAA,CAAAH,OAAA;AAAoC,SAAAG,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEpC;AACA;AACA;AACA,IAAIG,OAAmC;AACvC,MAAMC,UAAU,GAAGA,CAAA,KAAM;EACvB,IAAID,OAAO,KAAKE,SAAS,EAAE;IACzBF,OAAO,GAAGG,wBAAG,CAACC,oBAAoB,CAAC,wBAAwB,CAAC;EAC9D;EACA,OAAOJ,OAAO;AAChB,CAAC;AAIM,MAAMK,eAAe,GAAIC,MAAmB,IAAK;EACtD,MAAM;IAAEC;EAAQ,CAAC,GAAGJ,wBAAG;EACvB,MAAM,CAACK,KAAK,EAAEC,QAAQ,CAAC,GAAG,IAAAC,eAAQ,EAAe,IAAI,CAAC;EACtD,MAAMC,EAAE,GAAG,IAAAC,kBAAW,EACnBC,GAAW,IAAK;IACf,SAAS;;IACT,MAAMC,GAAG,GAAGC,UAAI,CAACC,KAAK,CAACH,GAAG,CAAU;IACpCN,OAAO,CAACE,QAAQ,CAAC,CAACK,GAAG,CAAC;EACxB,CAAC,EACD,CAACP,OAAO,CACV,CAAC;EACD,IAAAU,gBAAS,EAAC,MAAM;IACd,IAAIX,MAAM,EAAE;MACVH,wBAAG,CAACe,YAAY,CAACjB,UAAU,CAAC,CAAC,EAAEU,EAAE,CAAC,CAACL,MAAM,CAAC;IAC5C;EACF,CAAC,EAAE,CAACK,EAAE,EAAEL,MAAM,CAAC,CAAC;EAChB,OAAOE,KAAK;AACd,CAAC;AAACW,OAAA,CAAAd,eAAA,GAAAA,eAAA","ignoreList":[]}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.useSVG = void 0;
7
7
  var _react = require("react");
8
8
  var _Skia = require("../Skia");
9
+ var _Platform = require("../../Platform");
9
10
  const useSVG = (source, onError) => {
10
11
  const [svg, setSVG] = (0, _react.useState)(null);
11
12
  if (source === null || source === undefined) {
@@ -16,12 +17,10 @@ const useSVG = (source, onError) => {
16
17
  let src;
17
18
  if (typeof source === "string") {
18
19
  src = source;
19
- } else if (typeof source === "object" && "default" in source && typeof source.default === "string") {
20
- src = source.default;
21
- } else if (typeof source === "object" && "uri" in source) {
22
- src = source.uri;
20
+ } else if (source instanceof Uint8Array) {
21
+ throw new Error(`Invalid svg data source. Make sure that the source resolves to a string. Got: ${source}`);
23
22
  } else {
24
- throw new Error(`Invalid svg data source. Make sure that the source resolves to a string. Got: ${JSON.stringify(source, null, 2)}`);
23
+ src = _Platform.Platform.resolveAsset(source);
25
24
  }
26
25
  const result = await fetch(src);
27
26
  const svgStr = await result.text();
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_Skia","useSVG","source","onError","svg","setSVG","useState","undefined","Error","useEffect","src","default","uri","JSON","stringify","result","fetch","svgStr","text","newSvg","Skia","SVG","MakeFromString","exports"],"sources":["SVG.web.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { Skia } from \"../Skia\";\nimport type { DataSourceParam, SkSVG } from \"../types\";\n\nexport const useSVG = (\n source: DataSourceParam,\n onError?: (err: Error) => void\n) => {\n const [svg, setSVG] = useState<SkSVG | null>(null);\n if (source === null || source === undefined) {\n throw new Error(`Invalid svg data source. Got: ${source}`);\n }\n useEffect(() => {\n (async () => {\n let src: string;\n if (typeof source === \"string\") {\n src = source;\n } else if (\n typeof source === \"object\" &&\n \"default\" in source &&\n typeof source.default === \"string\"\n ) {\n src = source.default;\n } else if (typeof source === \"object\" && \"uri\" in source) {\n src = source.uri;\n } else {\n throw new Error(\n `Invalid svg data source. Make sure that the source resolves to a string. Got: ${JSON.stringify(\n source,\n null,\n 2\n )}`\n );\n }\n const result = await fetch(src);\n const svgStr = await result.text();\n const newSvg = Skia.SVG.MakeFromString(svgStr);\n setSVG(newSvg);\n if (newSvg === null && onError !== undefined) {\n onError(new Error(\"Failed to create SVG from source.\"));\n }\n })();\n }, [onError, source]);\n return svg;\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AAGO,MAAME,MAAM,GAAGA,CACpBC,MAAuB,EACvBC,OAA8B,KAC3B;EACH,MAAM,CAACC,GAAG,EAAEC,MAAM,CAAC,GAAG,IAAAC,eAAQ,EAAe,IAAI,CAAC;EAClD,IAAIJ,MAAM,KAAK,IAAI,IAAIA,MAAM,KAAKK,SAAS,EAAE;IAC3C,MAAM,IAAIC,KAAK,CAAC,iCAAiCN,MAAM,EAAE,CAAC;EAC5D;EACA,IAAAO,gBAAS,EAAC,MAAM;IACd,CAAC,YAAY;MACX,IAAIC,GAAW;MACf,IAAI,OAAOR,MAAM,KAAK,QAAQ,EAAE;QAC9BQ,GAAG,GAAGR,MAAM;MACd,CAAC,MAAM,IACL,OAAOA,MAAM,KAAK,QAAQ,IAC1B,SAAS,IAAIA,MAAM,IACnB,OAAOA,MAAM,CAACS,OAAO,KAAK,QAAQ,EAClC;QACAD,GAAG,GAAGR,MAAM,CAACS,OAAO;MACtB,CAAC,MAAM,IAAI,OAAOT,MAAM,KAAK,QAAQ,IAAI,KAAK,IAAIA,MAAM,EAAE;QACxDQ,GAAG,GAAGR,MAAM,CAACU,GAAG;MAClB,CAAC,MAAM;QACL,MAAM,IAAIJ,KAAK,CACb,iFAAiFK,IAAI,CAACC,SAAS,CAC7FZ,MAAM,EACN,IAAI,EACJ,CACF,CAAC,EACH,CAAC;MACH;MACA,MAAMa,MAAM,GAAG,MAAMC,KAAK,CAACN,GAAG,CAAC;MAC/B,MAAMO,MAAM,GAAG,MAAMF,MAAM,CAACG,IAAI,CAAC,CAAC;MAClC,MAAMC,MAAM,GAAGC,UAAI,CAACC,GAAG,CAACC,cAAc,CAACL,MAAM,CAAC;MAC9CZ,MAAM,CAACc,MAAM,CAAC;MACd,IAAIA,MAAM,KAAK,IAAI,IAAIhB,OAAO,KAAKI,SAAS,EAAE;QAC5CJ,OAAO,CAAC,IAAIK,KAAK,CAAC,mCAAmC,CAAC,CAAC;MACzD;IACF,CAAC,EAAE,CAAC;EACN,CAAC,EAAE,CAACL,OAAO,EAAED,MAAM,CAAC,CAAC;EACrB,OAAOE,GAAG;AACZ,CAAC;AAACmB,OAAA,CAAAtB,MAAA,GAAAA,MAAA","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_Skia","_Platform","useSVG","source","onError","svg","setSVG","useState","undefined","Error","useEffect","src","Uint8Array","Platform","resolveAsset","result","fetch","svgStr","text","newSvg","Skia","SVG","MakeFromString","exports"],"sources":["SVG.web.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\nimport { Skia } from \"../Skia\";\nimport type { DataSourceParam, SkSVG } from \"../types\";\nimport { Platform } from \"../../Platform\";\n\nexport const useSVG = (\n source: DataSourceParam,\n onError?: (err: Error) => void\n) => {\n const [svg, setSVG] = useState<SkSVG | null>(null);\n if (source === null || source === undefined) {\n throw new Error(`Invalid svg data source. Got: ${source}`);\n }\n useEffect(() => {\n (async () => {\n let src: string;\n if (typeof source === \"string\") {\n src = source;\n } else if (source instanceof Uint8Array) {\n throw new Error(\n `Invalid svg data source. Make sure that the source resolves to a string. Got: ${source}`\n );\n } else {\n src = Platform.resolveAsset(source);\n }\n const result = await fetch(src);\n const svgStr = await result.text();\n const newSvg = Skia.SVG.MakeFromString(svgStr);\n setSVG(newSvg);\n if (newSvg === null && onError !== undefined) {\n onError(new Error(\"Failed to create SVG from source.\"));\n }\n })();\n }, [onError, source]);\n return svg;\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AAEA,IAAAE,SAAA,GAAAF,OAAA;AAEO,MAAMG,MAAM,GAAGA,CACpBC,MAAuB,EACvBC,OAA8B,KAC3B;EACH,MAAM,CAACC,GAAG,EAAEC,MAAM,CAAC,GAAG,IAAAC,eAAQ,EAAe,IAAI,CAAC;EAClD,IAAIJ,MAAM,KAAK,IAAI,IAAIA,MAAM,KAAKK,SAAS,EAAE;IAC3C,MAAM,IAAIC,KAAK,CAAC,iCAAiCN,MAAM,EAAE,CAAC;EAC5D;EACA,IAAAO,gBAAS,EAAC,MAAM;IACd,CAAC,YAAY;MACX,IAAIC,GAAW;MACf,IAAI,OAAOR,MAAM,KAAK,QAAQ,EAAE;QAC9BQ,GAAG,GAAGR,MAAM;MACd,CAAC,MAAM,IAAIA,MAAM,YAAYS,UAAU,EAAE;QACvC,MAAM,IAAIH,KAAK,CACb,iFAAiFN,MAAM,EACzF,CAAC;MACH,CAAC,MAAM;QACLQ,GAAG,GAAGE,kBAAQ,CAACC,YAAY,CAACX,MAAM,CAAC;MACrC;MACA,MAAMY,MAAM,GAAG,MAAMC,KAAK,CAACL,GAAG,CAAC;MAC/B,MAAMM,MAAM,GAAG,MAAMF,MAAM,CAACG,IAAI,CAAC,CAAC;MAClC,MAAMC,MAAM,GAAGC,UAAI,CAACC,GAAG,CAACC,cAAc,CAACL,MAAM,CAAC;MAC9CX,MAAM,CAACa,MAAM,CAAC;MACd,IAAIA,MAAM,KAAK,IAAI,IAAIf,OAAO,KAAKI,SAAS,EAAE;QAC5CJ,OAAO,CAAC,IAAIK,KAAK,CAAC,mCAAmC,CAAC,CAAC;MACzD;IACF,CAAC,EAAE,CAAC;EACN,CAAC,EAAE,CAACL,OAAO,EAAED,MAAM,CAAC,CAAC;EACrB,OAAOE,GAAG;AACZ,CAAC;AAACkB,OAAA,CAAArB,MAAA,GAAAA,MAAA","ignoreList":[]}
@@ -1,6 +1,10 @@
1
1
  import type { SkCanvas } from "../Canvas";
2
+ import type { SkFont } from "../Font";
2
3
  import type { SkJSIInstance } from "../JsiInstance";
4
+ import type { SkPath } from "../Path";
5
+ import type { SkPoint } from "../Point";
3
6
  import type { SkRect } from "../Rect";
7
+ import type { SkSize } from "../Size";
4
8
  import type { TextDirection } from "./ParagraphStyle";
5
9
  export interface LineMetrics {
6
10
  /** The index in the text buffer the line begins. */
@@ -36,6 +40,42 @@ export interface SkRectWithDirection {
36
40
  rect: SkRect;
37
41
  direction: TextDirection;
38
42
  }
43
+ /**
44
+ * Information about a run of glyphs passed to the visitor of
45
+ * `SkParagraph.extendedVisit`. All glyphs in a run share the same font: for
46
+ * text shaped through font fallback, each fallback font produces its own
47
+ * run(s).
48
+ */
49
+ export interface ParagraphVisitorInfo {
50
+ /** The font used to shape this run (the resolved fallback font, if any). */
51
+ font: SkFont;
52
+ /** Origin of the run within the paragraph (baseline corrected). */
53
+ origin: SkPoint;
54
+ /** Advance of the run. */
55
+ advance: SkSize;
56
+ /** The glyph ids of the run. */
57
+ glyphs: number[];
58
+ /**
59
+ * The position of each glyph, relative to the run `origin`. Add `origin`
60
+ * to obtain paragraph coordinates: for a run shaped through font fallback,
61
+ * the run placement is carried by `origin`, not by the positions.
62
+ */
63
+ positions: SkPoint[];
64
+ /**
65
+ * The tight ink bounds of each glyph, relative to the glyph's origin.
66
+ * Combine with `positions` to compute the exact painted bounds of the run.
67
+ */
68
+ bounds: SkRect[];
69
+ /** The UTF-8 text index of the cluster each glyph belongs to. */
70
+ utf8Starts: number[];
71
+ /** Reserved flags (currently always 0). */
72
+ flags: number;
73
+ }
74
+ /**
75
+ * Visitor for `SkParagraph.extendedVisit`. Called once per run of glyphs;
76
+ * `info` is null to signal the end of a line.
77
+ */
78
+ export type ParagraphExtendedVisitor = (lineNumber: number, info: ParagraphVisitorInfo | null) => void;
39
79
  export interface SkParagraph extends SkJSIInstance<"Paragraph"> {
40
80
  /**
41
81
  * Calculates the position of the the glyphs in the paragraph
@@ -106,4 +146,26 @@ export interface SkParagraph extends SkJSIInstance<"Paragraph"> {
106
146
  * to the paragraph.
107
147
  */
108
148
  getRectsForPlaceholders(): SkRectWithDirection[];
149
+ /**
150
+ * Converts the glyphs of the given line into an SkPath, with all font
151
+ * fallbacks already applied. Use `computeTightBounds()` on the resulting
152
+ * path to measure the exact ink bounds of the rendered text (as opposed to
153
+ * the font-metrics based bounds returned by `getRectsForRange`).
154
+ * Note that color glyphs (e.g. emojis) cannot be converted to a path and
155
+ * are skipped. Returns null if the line number is out of bounds.
156
+ * This method requires the layout method to have been called first.
157
+ * Not implemented on React Native Web.
158
+ * @param lineNumber The line number (zero indexed, see `getLineMetrics`)
159
+ */
160
+ getPath(lineNumber: number): SkPath | null;
161
+ /**
162
+ * Visits the laid out paragraph, calling the visitor once for every run of
163
+ * glyphs with the resolved font, glyph ids, positions and per-glyph tight
164
+ * ink bounds. The visitor is called with a null info to signal the end of
165
+ * each line. This exposes the exact layout that would be painted.
166
+ * This method requires the layout method to have been called first.
167
+ * Not implemented on React Native Web.
168
+ * @param visitor Called once per glyph run, and once per line end
169
+ */
170
+ extendedVisit(visitor: ParagraphExtendedVisitor): void;
109
171
  }
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["Paragraph.ts"],"sourcesContent":["import type { SkCanvas } from \"../Canvas\";\nimport type { SkJSIInstance } from \"../JsiInstance\";\nimport type { SkRect } from \"../Rect\";\n\nimport type { TextDirection } from \"./ParagraphStyle\";\n\nexport interface LineMetrics {\n /** The index in the text buffer the line begins. */\n startIndex: number;\n /** The index in the text buffer the line ends. */\n endIndex: number;\n endExcludingWhitespaces: number;\n endIncludingNewline: number;\n /** True if the line ends in a hard break (e.g. newline) */\n isHardBreak: boolean;\n /**\n * The final computed ascent for the line. This can be impacted by\n * the strut, height, scaling, as well as outlying runs that are very tall.\n */\n ascent: number;\n /**\n * The final computed descent for the line. This can be impacted by\n * the strut, height, scaling, as well as outlying runs that are very tall.\n */\n descent: number;\n /** round(ascent + descent) */\n height: number;\n /** width of the line */\n width: number;\n /** The left edge of the line. The right edge can be obtained with `left + width` */\n left: number;\n /** The y position of the baseline for this line from the top of the paragraph. */\n baseline: number;\n /** Zero indexed line number. */\n lineNumber: number;\n}\n\nexport interface SkRectWithDirection {\n rect: SkRect;\n direction: TextDirection;\n}\n\nexport interface SkParagraph extends SkJSIInstance<\"Paragraph\"> {\n /**\n * Calculates the position of the the glyphs in the paragraph\n * @param width Max width of the paragraph\n */\n layout(width: number): void;\n /**\n * Paints the paragraph to the provded canvas\n * @param canvas Canvas to paint into\n * @param x X coordinate to paint at\n * @param y Y coordinate to paint at\n */\n paint(canvas: SkCanvas, x: number, y: number): void;\n /**\n * Returns the height of the paragraph. This method requires the layout\n * method to have been called first.\n */\n getHeight(): number;\n /**\n * Returns the max width of the paragraph. This method requires the layout\n * method to have been called first.\n */\n getMaxWidth(): number;\n /**\n * Returns the minimum intrinsic width of the paragraph.\n * The minimum intrinsic width is the width beyond which increasing the width of the paragraph\n * does not decrease the height. This is effectively the width at which the paragraph\n * can no longer wrap lines and is forced to overflow.\n * This method requires the layout method to have been called first.\n * @returns {number} The minimum intrinsic width of the paragraph.\n */\n getMinIntrinsicWidth(): number;\n /**\n * Returns the maximum intrinsic width of the paragraph.\n * The maximum intrinsic width is the width at which the paragraph can layout its content without line breaks,\n * meaning it's the width of the widest line or the widest word if the widest line is shorter than that.\n * This width represents the ideal width for the paragraph to display all content in a single line without overflow.\n * This method requires the layout method to have been called first.\n * @returns {number} The maximum intrinsic width of the paragraph.\n */\n getMaxIntrinsicWidth(): number;\n\n /**\n * Returns the width of the longest line in the paragraph.\n * This method requires the layout method to have been called first.\n */\n getLongestLine(): number;\n\n /**\n * Returns the index of the glyph at the given position. This method requires\n * the layout method to have been called first.\n * @param x X coordinate of the position\n * @param y Y coordinate of the position\n */\n getGlyphPositionAtCoordinate(x: number, y: number): number;\n /**\n * Returns the bounding boxes of the glyphs in the given range. This method\n * requires the layout method to have been called first.\n * @param start Start index of the range\n * @param end End index of the range\n */\n getRectsForRange(start: number, end: number): SkRect[];\n /**\n * Returns the bounding boxes for all lines in the paragraph. This method\n * requires the layout method to have been called first.\n */\n getLineMetrics(): LineMetrics[];\n /**\n * Returns a list of rects with direction info for the placeholders added\n * to the paragraph.\n */\n getRectsForPlaceholders(): SkRectWithDirection[];\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["Paragraph.ts"],"sourcesContent":["import type { SkCanvas } from \"../Canvas\";\nimport type { SkFont } from \"../Font\";\nimport type { SkJSIInstance } from \"../JsiInstance\";\nimport type { SkPath } from \"../Path\";\nimport type { SkPoint } from \"../Point\";\nimport type { SkRect } from \"../Rect\";\nimport type { SkSize } from \"../Size\";\n\nimport type { TextDirection } from \"./ParagraphStyle\";\n\nexport interface LineMetrics {\n /** The index in the text buffer the line begins. */\n startIndex: number;\n /** The index in the text buffer the line ends. */\n endIndex: number;\n endExcludingWhitespaces: number;\n endIncludingNewline: number;\n /** True if the line ends in a hard break (e.g. newline) */\n isHardBreak: boolean;\n /**\n * The final computed ascent for the line. This can be impacted by\n * the strut, height, scaling, as well as outlying runs that are very tall.\n */\n ascent: number;\n /**\n * The final computed descent for the line. This can be impacted by\n * the strut, height, scaling, as well as outlying runs that are very tall.\n */\n descent: number;\n /** round(ascent + descent) */\n height: number;\n /** width of the line */\n width: number;\n /** The left edge of the line. The right edge can be obtained with `left + width` */\n left: number;\n /** The y position of the baseline for this line from the top of the paragraph. */\n baseline: number;\n /** Zero indexed line number. */\n lineNumber: number;\n}\n\nexport interface SkRectWithDirection {\n rect: SkRect;\n direction: TextDirection;\n}\n\n/**\n * Information about a run of glyphs passed to the visitor of\n * `SkParagraph.extendedVisit`. All glyphs in a run share the same font: for\n * text shaped through font fallback, each fallback font produces its own\n * run(s).\n */\nexport interface ParagraphVisitorInfo {\n /** The font used to shape this run (the resolved fallback font, if any). */\n font: SkFont;\n /** Origin of the run within the paragraph (baseline corrected). */\n origin: SkPoint;\n /** Advance of the run. */\n advance: SkSize;\n /** The glyph ids of the run. */\n glyphs: number[];\n /**\n * The position of each glyph, relative to the run `origin`. Add `origin`\n * to obtain paragraph coordinates: for a run shaped through font fallback,\n * the run placement is carried by `origin`, not by the positions.\n */\n positions: SkPoint[];\n /**\n * The tight ink bounds of each glyph, relative to the glyph's origin.\n * Combine with `positions` to compute the exact painted bounds of the run.\n */\n bounds: SkRect[];\n /** The UTF-8 text index of the cluster each glyph belongs to. */\n utf8Starts: number[];\n /** Reserved flags (currently always 0). */\n flags: number;\n}\n\n/**\n * Visitor for `SkParagraph.extendedVisit`. Called once per run of glyphs;\n * `info` is null to signal the end of a line.\n */\nexport type ParagraphExtendedVisitor = (\n lineNumber: number,\n info: ParagraphVisitorInfo | null\n) => void;\n\nexport interface SkParagraph extends SkJSIInstance<\"Paragraph\"> {\n /**\n * Calculates the position of the the glyphs in the paragraph\n * @param width Max width of the paragraph\n */\n layout(width: number): void;\n /**\n * Paints the paragraph to the provded canvas\n * @param canvas Canvas to paint into\n * @param x X coordinate to paint at\n * @param y Y coordinate to paint at\n */\n paint(canvas: SkCanvas, x: number, y: number): void;\n /**\n * Returns the height of the paragraph. This method requires the layout\n * method to have been called first.\n */\n getHeight(): number;\n /**\n * Returns the max width of the paragraph. This method requires the layout\n * method to have been called first.\n */\n getMaxWidth(): number;\n /**\n * Returns the minimum intrinsic width of the paragraph.\n * The minimum intrinsic width is the width beyond which increasing the width of the paragraph\n * does not decrease the height. This is effectively the width at which the paragraph\n * can no longer wrap lines and is forced to overflow.\n * This method requires the layout method to have been called first.\n * @returns {number} The minimum intrinsic width of the paragraph.\n */\n getMinIntrinsicWidth(): number;\n /**\n * Returns the maximum intrinsic width of the paragraph.\n * The maximum intrinsic width is the width at which the paragraph can layout its content without line breaks,\n * meaning it's the width of the widest line or the widest word if the widest line is shorter than that.\n * This width represents the ideal width for the paragraph to display all content in a single line without overflow.\n * This method requires the layout method to have been called first.\n * @returns {number} The maximum intrinsic width of the paragraph.\n */\n getMaxIntrinsicWidth(): number;\n\n /**\n * Returns the width of the longest line in the paragraph.\n * This method requires the layout method to have been called first.\n */\n getLongestLine(): number;\n\n /**\n * Returns the index of the glyph at the given position. This method requires\n * the layout method to have been called first.\n * @param x X coordinate of the position\n * @param y Y coordinate of the position\n */\n getGlyphPositionAtCoordinate(x: number, y: number): number;\n /**\n * Returns the bounding boxes of the glyphs in the given range. This method\n * requires the layout method to have been called first.\n * @param start Start index of the range\n * @param end End index of the range\n */\n getRectsForRange(start: number, end: number): SkRect[];\n /**\n * Returns the bounding boxes for all lines in the paragraph. This method\n * requires the layout method to have been called first.\n */\n getLineMetrics(): LineMetrics[];\n /**\n * Returns a list of rects with direction info for the placeholders added\n * to the paragraph.\n */\n getRectsForPlaceholders(): SkRectWithDirection[];\n /**\n * Converts the glyphs of the given line into an SkPath, with all font\n * fallbacks already applied. Use `computeTightBounds()` on the resulting\n * path to measure the exact ink bounds of the rendered text (as opposed to\n * the font-metrics based bounds returned by `getRectsForRange`).\n * Note that color glyphs (e.g. emojis) cannot be converted to a path and\n * are skipped. Returns null if the line number is out of bounds.\n * This method requires the layout method to have been called first.\n * Not implemented on React Native Web.\n * @param lineNumber The line number (zero indexed, see `getLineMetrics`)\n */\n getPath(lineNumber: number): SkPath | null;\n /**\n * Visits the laid out paragraph, calling the visitor once for every run of\n * glyphs with the resolved font, glyph ids, positions and per-glyph tight\n * ink bounds. The visitor is called with a null info to signal the end of\n * each line. This exposes the exact layout that would be painted.\n * This method requires the layout method to have been called first.\n * Not implemented on React Native Web.\n * @param visitor Called once per glyph run, and once per line end\n */\n extendedVisit(visitor: ParagraphExtendedVisitor): void;\n}\n"],"mappings":"","ignoreList":[]}
@@ -34,6 +34,13 @@ class BaseHostObject extends Host {
34
34
  }
35
35
  [Symbol.dispose]() {
36
36
  if (this.ref !== null && typeof this.ref === "object" && "delete" in this.ref && typeof this.ref.delete === "function") {
37
+ // Renderer-owned and user-owned disposal can overlap (and emscripten
38
+ // throws on double delete) — make disposing an already-deleted object
39
+ // a no-op.
40
+ const ref = this.ref;
41
+ if (typeof ref.isDeleted === "function" && ref.isDeleted()) {
42
+ return;
43
+ }
37
44
  this.ref.delete();
38
45
  }
39
46
  }
@@ -1 +1 @@
1
- {"version":3,"names":["throwNotImplementedOnRNWeb","jest","fn","Error","exports","Host","constructor","CanvasKit","_defineProperty","BaseHostObject","ref","typename","__typename__","dispose","Symbol","delete","HostObject","fromValue","value","getEnum","name","v","e","result","Object","values","find","entry","optEnum","undefined"],"sources":["Host.ts"],"sourcesContent":["import type { CanvasKit, EmbindEnumEntity } from \"canvaskit-wasm\";\n\nimport type { SkJSIInstance } from \"../types\";\n\nexport const throwNotImplementedOnRNWeb = <T>(): T => {\n if (typeof jest !== \"undefined\") {\n return jest.fn() as unknown as T;\n }\n throw new Error(\"Not implemented on React Native Web\");\n};\n\nexport abstract class Host {\n readonly CanvasKit: CanvasKit;\n\n constructor(CanvasKit: CanvasKit) {\n this.CanvasKit = CanvasKit;\n }\n}\n\nexport abstract class BaseHostObject<T, N extends string>\n extends Host\n implements SkJSIInstance<N>\n{\n readonly __typename__: N;\n ref: T;\n\n constructor(CanvasKit: CanvasKit, ref: T, typename: N) {\n super(CanvasKit);\n this.ref = ref;\n this.__typename__ = typename;\n }\n\n dispose() {\n this[Symbol.dispose]();\n }\n\n [Symbol.dispose](): void {\n if (\n this.ref !== null &&\n typeof this.ref === \"object\" &&\n \"delete\" in this.ref &&\n typeof this.ref.delete === \"function\"\n ) {\n this.ref.delete();\n }\n }\n}\n\nexport abstract class HostObject<T, N extends string> extends BaseHostObject<\n T,\n N\n> {\n static fromValue<T>(value: SkJSIInstance<string>) {\n return (value as HostObject<T, string>).ref;\n }\n}\n\nexport const getEnum = (\n CanvasKit: CanvasKit,\n name: keyof CanvasKit,\n v: number\n): EmbindEnumEntity => {\n const e = CanvasKit[name];\n if (typeof e !== \"function\") {\n throw new Error(`${name} is not an number`);\n }\n const result = Object.values(e).find(\n (entry) =>\n entry !== null &&\n typeof entry === \"object\" &&\n \"value\" in entry &&\n entry.value === v\n );\n if (!result) {\n throw new Error(\n `Enum ${name} does not have value ${v} on React Native Web`\n );\n }\n return result;\n};\n\nexport const optEnum = (\n CanvasKit: CanvasKit,\n name: keyof CanvasKit,\n v: number | undefined\n): EmbindEnumEntity | undefined => {\n return v === undefined ? undefined : getEnum(CanvasKit, name, v);\n};\n"],"mappings":";;;;;;;;;AAIO,MAAMA,0BAA0B,GAAGA,CAAA,KAAY;EACpD,IAAI,OAAOC,IAAI,KAAK,WAAW,EAAE;IAC/B,OAAOA,IAAI,CAACC,EAAE,CAAC,CAAC;EAClB;EACA,MAAM,IAAIC,KAAK,CAAC,qCAAqC,CAAC;AACxD,CAAC;AAACC,OAAA,CAAAJ,0BAAA,GAAAA,0BAAA;AAEK,MAAeK,IAAI,CAAC;EAGzBC,WAAWA,CAACC,SAAoB,EAAE;IAAAC,eAAA;IAChC,IAAI,CAACD,SAAS,GAAGA,SAAS;EAC5B;AACF;AAACH,OAAA,CAAAC,IAAA,GAAAA,IAAA;AAEM,MAAeI,cAAc,SAC1BJ,IAAI,CAEd;EAIEC,WAAWA,CAACC,SAAoB,EAAEG,GAAM,EAAEC,QAAW,EAAE;IACrD,KAAK,CAACJ,SAAS,CAAC;IAACC,eAAA;IAAAA,eAAA;IACjB,IAAI,CAACE,GAAG,GAAGA,GAAG;IACd,IAAI,CAACE,YAAY,GAAGD,QAAQ;EAC9B;EAEAE,OAAOA,CAAA,EAAG;IACR,IAAI,CAACC,MAAM,CAACD,OAAO,CAAC,CAAC,CAAC;EACxB;EAEA,CAACC,MAAM,CAACD,OAAO,IAAU;IACvB,IACE,IAAI,CAACH,GAAG,KAAK,IAAI,IACjB,OAAO,IAAI,CAACA,GAAG,KAAK,QAAQ,IAC5B,QAAQ,IAAI,IAAI,CAACA,GAAG,IACpB,OAAO,IAAI,CAACA,GAAG,CAACK,MAAM,KAAK,UAAU,EACrC;MACA,IAAI,CAACL,GAAG,CAACK,MAAM,CAAC,CAAC;IACnB;EACF;AACF;AAACX,OAAA,CAAAK,cAAA,GAAAA,cAAA;AAEM,MAAeO,UAAU,SAA8BP,cAAc,CAG1E;EACA,OAAOQ,SAASA,CAAIC,KAA4B,EAAE;IAChD,OAAQA,KAAK,CAA2BR,GAAG;EAC7C;AACF;AAACN,OAAA,CAAAY,UAAA,GAAAA,UAAA;AAEM,MAAMG,OAAO,GAAGA,CACrBZ,SAAoB,EACpBa,IAAqB,EACrBC,CAAS,KACY;EACrB,MAAMC,CAAC,GAAGf,SAAS,CAACa,IAAI,CAAC;EACzB,IAAI,OAAOE,CAAC,KAAK,UAAU,EAAE;IAC3B,MAAM,IAAInB,KAAK,CAAC,GAAGiB,IAAI,mBAAmB,CAAC;EAC7C;EACA,MAAMG,MAAM,GAAGC,MAAM,CAACC,MAAM,CAACH,CAAC,CAAC,CAACI,IAAI,CACjCC,KAAK,IACJA,KAAK,KAAK,IAAI,IACd,OAAOA,KAAK,KAAK,QAAQ,IACzB,OAAO,IAAIA,KAAK,IAChBA,KAAK,CAACT,KAAK,KAAKG,CACpB,CAAC;EACD,IAAI,CAACE,MAAM,EAAE;IACX,MAAM,IAAIpB,KAAK,CACb,QAAQiB,IAAI,wBAAwBC,CAAC,sBACvC,CAAC;EACH;EACA,OAAOE,MAAM;AACf,CAAC;AAACnB,OAAA,CAAAe,OAAA,GAAAA,OAAA;AAEK,MAAMS,OAAO,GAAGA,CACrBrB,SAAoB,EACpBa,IAAqB,EACrBC,CAAqB,KACY;EACjC,OAAOA,CAAC,KAAKQ,SAAS,GAAGA,SAAS,GAAGV,OAAO,CAACZ,SAAS,EAAEa,IAAI,EAAEC,CAAC,CAAC;AAClE,CAAC;AAACjB,OAAA,CAAAwB,OAAA,GAAAA,OAAA","ignoreList":[]}
1
+ {"version":3,"names":["throwNotImplementedOnRNWeb","jest","fn","Error","exports","Host","constructor","CanvasKit","_defineProperty","BaseHostObject","ref","typename","__typename__","dispose","Symbol","delete","isDeleted","HostObject","fromValue","value","getEnum","name","v","e","result","Object","values","find","entry","optEnum","undefined"],"sources":["Host.ts"],"sourcesContent":["import type { CanvasKit, EmbindEnumEntity } from \"canvaskit-wasm\";\n\nimport type { SkJSIInstance } from \"../types\";\n\nexport const throwNotImplementedOnRNWeb = <T>(): T => {\n if (typeof jest !== \"undefined\") {\n return jest.fn() as unknown as T;\n }\n throw new Error(\"Not implemented on React Native Web\");\n};\n\nexport abstract class Host {\n readonly CanvasKit: CanvasKit;\n\n constructor(CanvasKit: CanvasKit) {\n this.CanvasKit = CanvasKit;\n }\n}\n\nexport abstract class BaseHostObject<T, N extends string>\n extends Host\n implements SkJSIInstance<N>\n{\n readonly __typename__: N;\n ref: T;\n\n constructor(CanvasKit: CanvasKit, ref: T, typename: N) {\n super(CanvasKit);\n this.ref = ref;\n this.__typename__ = typename;\n }\n\n dispose() {\n this[Symbol.dispose]();\n }\n\n [Symbol.dispose](): void {\n if (\n this.ref !== null &&\n typeof this.ref === \"object\" &&\n \"delete\" in this.ref &&\n typeof this.ref.delete === \"function\"\n ) {\n // Renderer-owned and user-owned disposal can overlap (and emscripten\n // throws on double delete) — make disposing an already-deleted object\n // a no-op.\n const ref = this.ref as unknown as { isDeleted?: () => boolean };\n if (typeof ref.isDeleted === \"function\" && ref.isDeleted()) {\n return;\n }\n this.ref.delete();\n }\n }\n}\n\nexport abstract class HostObject<T, N extends string> extends BaseHostObject<\n T,\n N\n> {\n static fromValue<T>(value: SkJSIInstance<string>) {\n return (value as HostObject<T, string>).ref;\n }\n}\n\nexport const getEnum = (\n CanvasKit: CanvasKit,\n name: keyof CanvasKit,\n v: number\n): EmbindEnumEntity => {\n const e = CanvasKit[name];\n if (typeof e !== \"function\") {\n throw new Error(`${name} is not an number`);\n }\n const result = Object.values(e).find(\n (entry) =>\n entry !== null &&\n typeof entry === \"object\" &&\n \"value\" in entry &&\n entry.value === v\n );\n if (!result) {\n throw new Error(\n `Enum ${name} does not have value ${v} on React Native Web`\n );\n }\n return result;\n};\n\nexport const optEnum = (\n CanvasKit: CanvasKit,\n name: keyof CanvasKit,\n v: number | undefined\n): EmbindEnumEntity | undefined => {\n return v === undefined ? undefined : getEnum(CanvasKit, name, v);\n};\n"],"mappings":";;;;;;;;;AAIO,MAAMA,0BAA0B,GAAGA,CAAA,KAAY;EACpD,IAAI,OAAOC,IAAI,KAAK,WAAW,EAAE;IAC/B,OAAOA,IAAI,CAACC,EAAE,CAAC,CAAC;EAClB;EACA,MAAM,IAAIC,KAAK,CAAC,qCAAqC,CAAC;AACxD,CAAC;AAACC,OAAA,CAAAJ,0BAAA,GAAAA,0BAAA;AAEK,MAAeK,IAAI,CAAC;EAGzBC,WAAWA,CAACC,SAAoB,EAAE;IAAAC,eAAA;IAChC,IAAI,CAACD,SAAS,GAAGA,SAAS;EAC5B;AACF;AAACH,OAAA,CAAAC,IAAA,GAAAA,IAAA;AAEM,MAAeI,cAAc,SAC1BJ,IAAI,CAEd;EAIEC,WAAWA,CAACC,SAAoB,EAAEG,GAAM,EAAEC,QAAW,EAAE;IACrD,KAAK,CAACJ,SAAS,CAAC;IAACC,eAAA;IAAAA,eAAA;IACjB,IAAI,CAACE,GAAG,GAAGA,GAAG;IACd,IAAI,CAACE,YAAY,GAAGD,QAAQ;EAC9B;EAEAE,OAAOA,CAAA,EAAG;IACR,IAAI,CAACC,MAAM,CAACD,OAAO,CAAC,CAAC,CAAC;EACxB;EAEA,CAACC,MAAM,CAACD,OAAO,IAAU;IACvB,IACE,IAAI,CAACH,GAAG,KAAK,IAAI,IACjB,OAAO,IAAI,CAACA,GAAG,KAAK,QAAQ,IAC5B,QAAQ,IAAI,IAAI,CAACA,GAAG,IACpB,OAAO,IAAI,CAACA,GAAG,CAACK,MAAM,KAAK,UAAU,EACrC;MACA;MACA;MACA;MACA,MAAML,GAAG,GAAG,IAAI,CAACA,GAA+C;MAChE,IAAI,OAAOA,GAAG,CAACM,SAAS,KAAK,UAAU,IAAIN,GAAG,CAACM,SAAS,CAAC,CAAC,EAAE;QAC1D;MACF;MACA,IAAI,CAACN,GAAG,CAACK,MAAM,CAAC,CAAC;IACnB;EACF;AACF;AAACX,OAAA,CAAAK,cAAA,GAAAA,cAAA;AAEM,MAAeQ,UAAU,SAA8BR,cAAc,CAG1E;EACA,OAAOS,SAASA,CAAIC,KAA4B,EAAE;IAChD,OAAQA,KAAK,CAA2BT,GAAG;EAC7C;AACF;AAACN,OAAA,CAAAa,UAAA,GAAAA,UAAA;AAEM,MAAMG,OAAO,GAAGA,CACrBb,SAAoB,EACpBc,IAAqB,EACrBC,CAAS,KACY;EACrB,MAAMC,CAAC,GAAGhB,SAAS,CAACc,IAAI,CAAC;EACzB,IAAI,OAAOE,CAAC,KAAK,UAAU,EAAE;IAC3B,MAAM,IAAIpB,KAAK,CAAC,GAAGkB,IAAI,mBAAmB,CAAC;EAC7C;EACA,MAAMG,MAAM,GAAGC,MAAM,CAACC,MAAM,CAACH,CAAC,CAAC,CAACI,IAAI,CACjCC,KAAK,IACJA,KAAK,KAAK,IAAI,IACd,OAAOA,KAAK,KAAK,QAAQ,IACzB,OAAO,IAAIA,KAAK,IAChBA,KAAK,CAACT,KAAK,KAAKG,CACpB,CAAC;EACD,IAAI,CAACE,MAAM,EAAE;IACX,MAAM,IAAIrB,KAAK,CACb,QAAQkB,IAAI,wBAAwBC,CAAC,sBACvC,CAAC;EACH;EACA,OAAOE,MAAM;AACf,CAAC;AAACpB,OAAA,CAAAgB,OAAA,GAAAA,OAAA;AAEK,MAAMS,OAAO,GAAGA,CACrBtB,SAAoB,EACpBc,IAAqB,EACrBC,CAAqB,KACY;EACjC,OAAOA,CAAC,KAAKQ,SAAS,GAAGA,SAAS,GAAGV,OAAO,CAACb,SAAS,EAAEc,IAAI,EAAEC,CAAC,CAAC;AAClE,CAAC;AAAClB,OAAA,CAAAyB,OAAA,GAAAA,OAAA","ignoreList":[]}
@@ -61,10 +61,15 @@ class JsiSkPaint extends _Host.HostObject {
61
61
  return new JsiSkPaint(this.CanvasKit, this.ref.copy());
62
62
  }
63
63
  assign(paint) {
64
+ const previous = this.ref;
64
65
  this.ref = paint.ref.copy();
66
+ // The replaced ref is a WASM object the GC will not reclaim.
67
+ previous.delete();
65
68
  }
66
69
  reset() {
70
+ const previous = this.ref;
67
71
  this.ref = new this.CanvasKit.Paint();
72
+ previous.delete();
68
73
  }
69
74
  getAlphaf() {
70
75
  return this.getColor()[3];
@@ -1 +1 @@
1
- {"version":3,"names":["_Host","require","_JsiSkColorFilter","_JsiSkImageFilter","_JsiSkMaskFilter","_JsiSkPathEffect","_JsiSkShader","kBlendModePlusDarker","kBlendModePlusLighter","plusDarkerSkSL","plusLighterSkSL","blenderCache","WeakMap","getBlenderCache","ck","cache","get","plusDarker","plusLighter","set","JsiSkPaint","HostObject","constructor","CanvasKit","ref","copy","assign","paint","reset","Paint","getAlphaf","getColor","getStrokeCap","value","getStrokeJoin","getStrokeMiter","getStrokeWidth","setAlphaf","alpha","setAntiAlias","aa","setDither","dither","setBlendMode","blendMode","effect","RuntimeEffect","MakeForBlender","makeBlender","setBlender","getEnum","setColor","color","setColorFilter","filter","JsiSkColorFilter","fromValue","setImageFilter","JsiSkImageFilter","setMaskFilter","JsiSkMaskFilter","setPathEffect","JsiSkPathEffect","setShader","shader","JsiSkShader","setStrokeCap","cap","setStrokeJoin","join","setStrokeMiter","limit","setStrokeWidth","width","setStyle","style","exports"],"sources":["JsiSkPaint.ts"],"sourcesContent":["import type { Blender, CanvasKit, Paint } from \"canvaskit-wasm\";\n\nimport type {\n StrokeJoin,\n BlendMode,\n SkColor,\n SkColorFilter,\n SkImageFilter,\n SkPaint,\n SkShader,\n StrokeCap,\n PaintStyle,\n SkMaskFilter,\n SkPathEffect,\n} from \"../types\";\n\nimport { HostObject, getEnum } from \"./Host\";\nimport { JsiSkColorFilter } from \"./JsiSkColorFilter\";\nimport { JsiSkImageFilter } from \"./JsiSkImageFilter\";\nimport { JsiSkMaskFilter } from \"./JsiSkMaskFilter\";\nimport { JsiSkPathEffect } from \"./JsiSkPathEffect\";\nimport { JsiSkShader } from \"./JsiSkShader\";\n\n// Custom blend mode values (must match TypeScript BlendMode enum)\nconst kBlendModePlusDarker = 1001;\nconst kBlendModePlusLighter = 1002;\n\n// SkSL for PlusDarker blend mode\n// Formula: rc = max(0, 1 - ((1-dst) + (1-src))) = max(0, src + dst - 1)\nconst plusDarkerSkSL = `\n vec4 main(vec4 src, vec4 dst) {\n float outAlpha = src.a + dst.a - src.a * dst.a;\n vec3 srcUnpremul = src.a > 0.0 ? src.rgb / src.a : vec3(0.0);\n vec3 dstUnpremul = dst.a > 0.0 ? dst.rgb / dst.a : vec3(0.0);\n vec3 blended = max(vec3(0.0), srcUnpremul + dstUnpremul - vec3(1.0));\n return vec4(blended * outAlpha, outAlpha);\n }\n`;\n\n// SkSL for PlusLighter blend mode\n// Formula: rc = min(1, dst + src)\nconst plusLighterSkSL = `\n vec4 main(vec4 src, vec4 dst) {\n float outAlpha = src.a + dst.a - src.a * dst.a;\n vec3 srcUnpremul = src.a > 0.0 ? src.rgb / src.a : vec3(0.0);\n vec3 dstUnpremul = dst.a > 0.0 ? dst.rgb / dst.a : vec3(0.0);\n vec3 blended = min(vec3(1.0), srcUnpremul + dstUnpremul);\n return vec4(blended * outAlpha, outAlpha);\n }\n`;\n\n// Cache for custom blenders per CanvasKit instance\n// Using WeakMap ensures blenders are cleaned up when CanvasKit instance is garbage collected\ninterface BlenderCache {\n plusDarker: Blender | null;\n plusLighter: Blender | null;\n}\nconst blenderCache = new WeakMap<CanvasKit, BlenderCache>();\n\nconst getBlenderCache = (ck: CanvasKit): BlenderCache => {\n let cache = blenderCache.get(ck);\n if (!cache) {\n cache = { plusDarker: null, plusLighter: null };\n blenderCache.set(ck, cache);\n }\n return cache;\n};\n\nexport class JsiSkPaint extends HostObject<Paint, \"Paint\"> implements SkPaint {\n constructor(CanvasKit: CanvasKit, ref: Paint) {\n super(CanvasKit, ref, \"Paint\");\n }\n\n copy() {\n return new JsiSkPaint(this.CanvasKit, this.ref.copy());\n }\n\n assign(paint: JsiSkPaint) {\n this.ref = paint.ref.copy();\n }\n\n reset() {\n this.ref = new this.CanvasKit.Paint();\n }\n\n getAlphaf() {\n return this.getColor()[3];\n }\n\n getColor() {\n return this.ref.getColor();\n }\n\n getStrokeCap() {\n return this.ref.getStrokeCap().value;\n }\n\n getStrokeJoin() {\n return this.ref.getStrokeJoin().value;\n }\n\n getStrokeMiter() {\n return this.ref.getStrokeMiter();\n }\n\n getStrokeWidth() {\n return this.ref.getStrokeWidth();\n }\n\n setAlphaf(alpha: number) {\n this.ref.setAlphaf(alpha);\n }\n\n setAntiAlias(aa: boolean) {\n this.ref.setAntiAlias(aa);\n }\n\n setDither(dither: boolean) {\n this.ref.setDither(dither);\n }\n\n setBlendMode(blendMode: BlendMode) {\n if (blendMode === kBlendModePlusDarker) {\n // Use custom PlusDarker blender via SkRuntimeEffect\n const cache = getBlenderCache(this.CanvasKit);\n if (!cache.plusDarker) {\n const effect =\n this.CanvasKit.RuntimeEffect.MakeForBlender(plusDarkerSkSL);\n if (effect) {\n cache.plusDarker = effect.makeBlender([]);\n }\n }\n if (cache.plusDarker) {\n this.ref.setBlender(cache.plusDarker);\n }\n } else if (blendMode === kBlendModePlusLighter) {\n // Use custom PlusLighter blender via SkRuntimeEffect\n const cache = getBlenderCache(this.CanvasKit);\n if (!cache.plusLighter) {\n const effect =\n this.CanvasKit.RuntimeEffect.MakeForBlender(plusLighterSkSL);\n if (effect) {\n cache.plusLighter = effect.makeBlender([]);\n }\n }\n if (cache.plusLighter) {\n this.ref.setBlender(cache.plusLighter);\n }\n } else {\n this.ref.setBlendMode(getEnum(this.CanvasKit, \"BlendMode\", blendMode));\n }\n }\n\n setColor(color: SkColor) {\n this.ref.setColor(color);\n }\n\n setColorFilter(filter: SkColorFilter | null) {\n this.ref.setColorFilter(filter ? JsiSkColorFilter.fromValue(filter) : null);\n }\n\n setImageFilter(filter: SkImageFilter | null) {\n this.ref.setImageFilter(filter ? JsiSkImageFilter.fromValue(filter) : null);\n }\n\n setMaskFilter(filter: SkMaskFilter | null) {\n this.ref.setMaskFilter(filter ? JsiSkMaskFilter.fromValue(filter) : null);\n }\n\n setPathEffect(effect: SkPathEffect | null) {\n this.ref.setPathEffect(effect ? JsiSkPathEffect.fromValue(effect) : null);\n }\n\n setShader(shader: SkShader | null) {\n this.ref.setShader(shader ? JsiSkShader.fromValue(shader) : null);\n }\n\n setStrokeCap(cap: StrokeCap) {\n this.ref.setStrokeCap(getEnum(this.CanvasKit, \"StrokeCap\", cap));\n }\n\n setStrokeJoin(join: StrokeJoin) {\n this.ref.setStrokeJoin(getEnum(this.CanvasKit, \"StrokeJoin\", join));\n }\n\n setStrokeMiter(limit: number) {\n this.ref.setStrokeMiter(limit);\n }\n\n setStrokeWidth(width: number) {\n this.ref.setStrokeWidth(width);\n }\n\n setStyle(style: PaintStyle) {\n this.ref.setStyle({ value: style });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_Host","require","_JsiSkColorFilter","_JsiSkImageFilter","_JsiSkMaskFilter","_JsiSkPathEffect","_JsiSkShader","kBlendModePlusDarker","kBlendModePlusLighter","plusDarkerSkSL","plusLighterSkSL","blenderCache","WeakMap","getBlenderCache","ck","cache","get","plusDarker","plusLighter","set","JsiSkPaint","HostObject","constructor","CanvasKit","ref","copy","assign","paint","previous","delete","reset","Paint","getAlphaf","getColor","getStrokeCap","value","getStrokeJoin","getStrokeMiter","getStrokeWidth","setAlphaf","alpha","setAntiAlias","aa","setDither","dither","setBlendMode","blendMode","effect","RuntimeEffect","MakeForBlender","makeBlender","setBlender","getEnum","setColor","color","setColorFilter","filter","JsiSkColorFilter","fromValue","setImageFilter","JsiSkImageFilter","setMaskFilter","JsiSkMaskFilter","setPathEffect","JsiSkPathEffect","setShader","shader","JsiSkShader","setStrokeCap","cap","setStrokeJoin","join","setStrokeMiter","limit","setStrokeWidth","width","setStyle","style","exports"],"sources":["JsiSkPaint.ts"],"sourcesContent":["import type { Blender, CanvasKit, Paint } from \"canvaskit-wasm\";\n\nimport type {\n StrokeJoin,\n BlendMode,\n SkColor,\n SkColorFilter,\n SkImageFilter,\n SkPaint,\n SkShader,\n StrokeCap,\n PaintStyle,\n SkMaskFilter,\n SkPathEffect,\n} from \"../types\";\n\nimport { HostObject, getEnum } from \"./Host\";\nimport { JsiSkColorFilter } from \"./JsiSkColorFilter\";\nimport { JsiSkImageFilter } from \"./JsiSkImageFilter\";\nimport { JsiSkMaskFilter } from \"./JsiSkMaskFilter\";\nimport { JsiSkPathEffect } from \"./JsiSkPathEffect\";\nimport { JsiSkShader } from \"./JsiSkShader\";\n\n// Custom blend mode values (must match TypeScript BlendMode enum)\nconst kBlendModePlusDarker = 1001;\nconst kBlendModePlusLighter = 1002;\n\n// SkSL for PlusDarker blend mode\n// Formula: rc = max(0, 1 - ((1-dst) + (1-src))) = max(0, src + dst - 1)\nconst plusDarkerSkSL = `\n vec4 main(vec4 src, vec4 dst) {\n float outAlpha = src.a + dst.a - src.a * dst.a;\n vec3 srcUnpremul = src.a > 0.0 ? src.rgb / src.a : vec3(0.0);\n vec3 dstUnpremul = dst.a > 0.0 ? dst.rgb / dst.a : vec3(0.0);\n vec3 blended = max(vec3(0.0), srcUnpremul + dstUnpremul - vec3(1.0));\n return vec4(blended * outAlpha, outAlpha);\n }\n`;\n\n// SkSL for PlusLighter blend mode\n// Formula: rc = min(1, dst + src)\nconst plusLighterSkSL = `\n vec4 main(vec4 src, vec4 dst) {\n float outAlpha = src.a + dst.a - src.a * dst.a;\n vec3 srcUnpremul = src.a > 0.0 ? src.rgb / src.a : vec3(0.0);\n vec3 dstUnpremul = dst.a > 0.0 ? dst.rgb / dst.a : vec3(0.0);\n vec3 blended = min(vec3(1.0), srcUnpremul + dstUnpremul);\n return vec4(blended * outAlpha, outAlpha);\n }\n`;\n\n// Cache for custom blenders per CanvasKit instance\n// Using WeakMap ensures blenders are cleaned up when CanvasKit instance is garbage collected\ninterface BlenderCache {\n plusDarker: Blender | null;\n plusLighter: Blender | null;\n}\nconst blenderCache = new WeakMap<CanvasKit, BlenderCache>();\n\nconst getBlenderCache = (ck: CanvasKit): BlenderCache => {\n let cache = blenderCache.get(ck);\n if (!cache) {\n cache = { plusDarker: null, plusLighter: null };\n blenderCache.set(ck, cache);\n }\n return cache;\n};\n\nexport class JsiSkPaint extends HostObject<Paint, \"Paint\"> implements SkPaint {\n constructor(CanvasKit: CanvasKit, ref: Paint) {\n super(CanvasKit, ref, \"Paint\");\n }\n\n copy() {\n return new JsiSkPaint(this.CanvasKit, this.ref.copy());\n }\n\n assign(paint: JsiSkPaint) {\n const previous = this.ref;\n this.ref = paint.ref.copy();\n // The replaced ref is a WASM object the GC will not reclaim.\n previous.delete();\n }\n\n reset() {\n const previous = this.ref;\n this.ref = new this.CanvasKit.Paint();\n previous.delete();\n }\n\n getAlphaf() {\n return this.getColor()[3];\n }\n\n getColor() {\n return this.ref.getColor();\n }\n\n getStrokeCap() {\n return this.ref.getStrokeCap().value;\n }\n\n getStrokeJoin() {\n return this.ref.getStrokeJoin().value;\n }\n\n getStrokeMiter() {\n return this.ref.getStrokeMiter();\n }\n\n getStrokeWidth() {\n return this.ref.getStrokeWidth();\n }\n\n setAlphaf(alpha: number) {\n this.ref.setAlphaf(alpha);\n }\n\n setAntiAlias(aa: boolean) {\n this.ref.setAntiAlias(aa);\n }\n\n setDither(dither: boolean) {\n this.ref.setDither(dither);\n }\n\n setBlendMode(blendMode: BlendMode) {\n if (blendMode === kBlendModePlusDarker) {\n // Use custom PlusDarker blender via SkRuntimeEffect\n const cache = getBlenderCache(this.CanvasKit);\n if (!cache.plusDarker) {\n const effect =\n this.CanvasKit.RuntimeEffect.MakeForBlender(plusDarkerSkSL);\n if (effect) {\n cache.plusDarker = effect.makeBlender([]);\n }\n }\n if (cache.plusDarker) {\n this.ref.setBlender(cache.plusDarker);\n }\n } else if (blendMode === kBlendModePlusLighter) {\n // Use custom PlusLighter blender via SkRuntimeEffect\n const cache = getBlenderCache(this.CanvasKit);\n if (!cache.plusLighter) {\n const effect =\n this.CanvasKit.RuntimeEffect.MakeForBlender(plusLighterSkSL);\n if (effect) {\n cache.plusLighter = effect.makeBlender([]);\n }\n }\n if (cache.plusLighter) {\n this.ref.setBlender(cache.plusLighter);\n }\n } else {\n this.ref.setBlendMode(getEnum(this.CanvasKit, \"BlendMode\", blendMode));\n }\n }\n\n setColor(color: SkColor) {\n this.ref.setColor(color);\n }\n\n setColorFilter(filter: SkColorFilter | null) {\n this.ref.setColorFilter(filter ? JsiSkColorFilter.fromValue(filter) : null);\n }\n\n setImageFilter(filter: SkImageFilter | null) {\n this.ref.setImageFilter(filter ? JsiSkImageFilter.fromValue(filter) : null);\n }\n\n setMaskFilter(filter: SkMaskFilter | null) {\n this.ref.setMaskFilter(filter ? JsiSkMaskFilter.fromValue(filter) : null);\n }\n\n setPathEffect(effect: SkPathEffect | null) {\n this.ref.setPathEffect(effect ? JsiSkPathEffect.fromValue(effect) : null);\n }\n\n setShader(shader: SkShader | null) {\n this.ref.setShader(shader ? JsiSkShader.fromValue(shader) : null);\n }\n\n setStrokeCap(cap: StrokeCap) {\n this.ref.setStrokeCap(getEnum(this.CanvasKit, \"StrokeCap\", cap));\n }\n\n setStrokeJoin(join: StrokeJoin) {\n this.ref.setStrokeJoin(getEnum(this.CanvasKit, \"StrokeJoin\", join));\n }\n\n setStrokeMiter(limit: number) {\n this.ref.setStrokeMiter(limit);\n }\n\n setStrokeWidth(width: number) {\n this.ref.setStrokeWidth(width);\n }\n\n setStyle(style: PaintStyle) {\n this.ref.setStyle({ value: style });\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  import type { CanvasKit, Paragraph } from "canvaskit-wasm";
2
- import type { SkRect, SkRectWithDirection, SkParagraph, LineMetrics } from "../types";
2
+ import type { SkRect, SkRectWithDirection, SkParagraph, SkPath, LineMetrics, ParagraphExtendedVisitor } from "../types";
3
3
  import { HostObject } from "./Host";
4
4
  import type { JsiSkCanvas } from "./JsiSkCanvas";
5
5
  export declare class JsiSkParagraph extends HostObject<Paragraph, "Paragraph"> implements SkParagraph {
@@ -15,4 +15,6 @@ export declare class JsiSkParagraph extends HostObject<Paragraph, "Paragraph"> i
15
15
  getRectsForPlaceholders(): SkRectWithDirection[];
16
16
  getRectsForRange(start: number, end: number): SkRect[];
17
17
  getLineMetrics(): LineMetrics[];
18
+ getPath(_lineNumber: number): SkPath | null;
19
+ extendedVisit(_visitor: ParagraphExtendedVisitor): void;
18
20
  }
@@ -55,6 +55,12 @@ class JsiSkParagraph extends _Host.HostObject {
55
55
  getLineMetrics() {
56
56
  return this.ref.getLineMetrics();
57
57
  }
58
+ getPath(_lineNumber) {
59
+ return (0, _Host.throwNotImplementedOnRNWeb)();
60
+ }
61
+ extendedVisit(_visitor) {
62
+ return (0, _Host.throwNotImplementedOnRNWeb)();
63
+ }
58
64
  }
59
65
  exports.JsiSkParagraph = JsiSkParagraph;
60
66
  //# sourceMappingURL=JsiSkParagraph.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_Host","require","_JsiSkRect","JsiSkParagraph","HostObject","constructor","CanvasKit","ref","getMinIntrinsicWidth","getMaxIntrinsicWidth","getLongestLine","layout","width","paint","canvas","x","y","drawParagraph","getHeight","getMaxWidth","getGlyphPositionAtCoordinate","pos","getRectsForPlaceholders","map","rect","dir","JsiSkRect","direction","value","getRectsForRange","start","end","getLineMetrics","exports"],"sources":["JsiSkParagraph.ts"],"sourcesContent":["import type { CanvasKit, Paragraph } from \"canvaskit-wasm\";\n\nimport type {\n SkRect,\n SkRectWithDirection,\n SkParagraph,\n LineMetrics,\n} from \"../types\";\n\nimport { HostObject } from \"./Host\";\nimport type { JsiSkCanvas } from \"./JsiSkCanvas\";\nimport { JsiSkRect } from \"./JsiSkRect\";\n\nexport class JsiSkParagraph\n extends HostObject<Paragraph, \"Paragraph\">\n implements SkParagraph\n{\n constructor(CanvasKit: CanvasKit, ref: Paragraph) {\n super(CanvasKit, ref, \"Paragraph\");\n }\n getMinIntrinsicWidth() {\n return this.ref.getMinIntrinsicWidth();\n }\n\n getMaxIntrinsicWidth() {\n return this.ref.getMaxIntrinsicWidth();\n }\n\n getLongestLine() {\n return this.ref.getLongestLine();\n }\n\n layout(width: number) {\n this.ref.layout(width);\n }\n paint(canvas: JsiSkCanvas, x: number, y: number) {\n canvas.ref.drawParagraph(this.ref, x, y);\n }\n getHeight() {\n return this.ref.getHeight();\n }\n getMaxWidth() {\n return this.ref.getMaxWidth();\n }\n getGlyphPositionAtCoordinate(x: number, y: number) {\n return this.ref.getGlyphPositionAtCoordinate(x, y).pos;\n }\n getRectsForPlaceholders(): SkRectWithDirection[] {\n return this.ref.getRectsForPlaceholders().map(({ rect, dir }) => ({\n rect: new JsiSkRect(this.CanvasKit, rect),\n direction: dir.value,\n }));\n }\n getRectsForRange(start: number, end: number): SkRect[] {\n return this.ref\n .getRectsForRange(\n start,\n end,\n { value: 0 } /** kTight */,\n { value: 0 } /** kTight */\n )\n .map(({ rect }) => new JsiSkRect(this.CanvasKit, rect));\n }\n getLineMetrics(): LineMetrics[] {\n return this.ref.getLineMetrics();\n }\n}\n"],"mappings":";;;;;;AASA,IAAAA,KAAA,GAAAC,OAAA;AAEA,IAAAC,UAAA,GAAAD,OAAA;AAEO,MAAME,cAAc,SACjBC,gBAAU,CAEpB;EACEC,WAAWA,CAACC,SAAoB,EAAEC,GAAc,EAAE;IAChD,KAAK,CAACD,SAAS,EAAEC,GAAG,EAAE,WAAW,CAAC;EACpC;EACAC,oBAAoBA,CAAA,EAAG;IACrB,OAAO,IAAI,CAACD,GAAG,CAACC,oBAAoB,CAAC,CAAC;EACxC;EAEAC,oBAAoBA,CAAA,EAAG;IACrB,OAAO,IAAI,CAACF,GAAG,CAACE,oBAAoB,CAAC,CAAC;EACxC;EAEAC,cAAcA,CAAA,EAAG;IACf,OAAO,IAAI,CAACH,GAAG,CAACG,cAAc,CAAC,CAAC;EAClC;EAEAC,MAAMA,CAACC,KAAa,EAAE;IACpB,IAAI,CAACL,GAAG,CAACI,MAAM,CAACC,KAAK,CAAC;EACxB;EACAC,KAAKA,CAACC,MAAmB,EAAEC,CAAS,EAAEC,CAAS,EAAE;IAC/CF,MAAM,CAACP,GAAG,CAACU,aAAa,CAAC,IAAI,CAACV,GAAG,EAAEQ,CAAC,EAAEC,CAAC,CAAC;EAC1C;EACAE,SAASA,CAAA,EAAG;IACV,OAAO,IAAI,CAACX,GAAG,CAACW,SAAS,CAAC,CAAC;EAC7B;EACAC,WAAWA,CAAA,EAAG;IACZ,OAAO,IAAI,CAACZ,GAAG,CAACY,WAAW,CAAC,CAAC;EAC/B;EACAC,4BAA4BA,CAACL,CAAS,EAAEC,CAAS,EAAE;IACjD,OAAO,IAAI,CAACT,GAAG,CAACa,4BAA4B,CAACL,CAAC,EAAEC,CAAC,CAAC,CAACK,GAAG;EACxD;EACAC,uBAAuBA,CAAA,EAA0B;IAC/C,OAAO,IAAI,CAACf,GAAG,CAACe,uBAAuB,CAAC,CAAC,CAACC,GAAG,CAAC,CAAC;MAAEC,IAAI;MAAEC;IAAI,CAAC,MAAM;MAChED,IAAI,EAAE,IAAIE,oBAAS,CAAC,IAAI,CAACpB,SAAS,EAAEkB,IAAI,CAAC;MACzCG,SAAS,EAAEF,GAAG,CAACG;IACjB,CAAC,CAAC,CAAC;EACL;EACAC,gBAAgBA,CAACC,KAAa,EAAEC,GAAW,EAAY;IACrD,OAAO,IAAI,CAACxB,GAAG,CACZsB,gBAAgB,CACfC,KAAK,EACLC,GAAG,EACH;MAAEH,KAAK,EAAE;IAAE,CAAC,CAAC,eACb;MAAEA,KAAK,EAAE;IAAE,CAAC,CAAC,aACf,CAAC,CACAL,GAAG,CAAC,CAAC;MAAEC;IAAK,CAAC,KAAK,IAAIE,oBAAS,CAAC,IAAI,CAACpB,SAAS,EAAEkB,IAAI,CAAC,CAAC;EAC3D;EACAQ,cAAcA,CAAA,EAAkB;IAC9B,OAAO,IAAI,CAACzB,GAAG,CAACyB,cAAc,CAAC,CAAC;EAClC;AACF;AAACC,OAAA,CAAA9B,cAAA,GAAAA,cAAA","ignoreList":[]}
1
+ {"version":3,"names":["_Host","require","_JsiSkRect","JsiSkParagraph","HostObject","constructor","CanvasKit","ref","getMinIntrinsicWidth","getMaxIntrinsicWidth","getLongestLine","layout","width","paint","canvas","x","y","drawParagraph","getHeight","getMaxWidth","getGlyphPositionAtCoordinate","pos","getRectsForPlaceholders","map","rect","dir","JsiSkRect","direction","value","getRectsForRange","start","end","getLineMetrics","getPath","_lineNumber","throwNotImplementedOnRNWeb","extendedVisit","_visitor","exports"],"sources":["JsiSkParagraph.ts"],"sourcesContent":["import type { CanvasKit, Paragraph } from \"canvaskit-wasm\";\n\nimport type {\n SkRect,\n SkRectWithDirection,\n SkParagraph,\n SkPath,\n LineMetrics,\n ParagraphExtendedVisitor,\n} from \"../types\";\n\nimport { HostObject, throwNotImplementedOnRNWeb } from \"./Host\";\nimport type { JsiSkCanvas } from \"./JsiSkCanvas\";\nimport { JsiSkRect } from \"./JsiSkRect\";\n\nexport class JsiSkParagraph\n extends HostObject<Paragraph, \"Paragraph\">\n implements SkParagraph\n{\n constructor(CanvasKit: CanvasKit, ref: Paragraph) {\n super(CanvasKit, ref, \"Paragraph\");\n }\n getMinIntrinsicWidth() {\n return this.ref.getMinIntrinsicWidth();\n }\n\n getMaxIntrinsicWidth() {\n return this.ref.getMaxIntrinsicWidth();\n }\n\n getLongestLine() {\n return this.ref.getLongestLine();\n }\n\n layout(width: number) {\n this.ref.layout(width);\n }\n paint(canvas: JsiSkCanvas, x: number, y: number) {\n canvas.ref.drawParagraph(this.ref, x, y);\n }\n getHeight() {\n return this.ref.getHeight();\n }\n getMaxWidth() {\n return this.ref.getMaxWidth();\n }\n getGlyphPositionAtCoordinate(x: number, y: number) {\n return this.ref.getGlyphPositionAtCoordinate(x, y).pos;\n }\n getRectsForPlaceholders(): SkRectWithDirection[] {\n return this.ref.getRectsForPlaceholders().map(({ rect, dir }) => ({\n rect: new JsiSkRect(this.CanvasKit, rect),\n direction: dir.value,\n }));\n }\n getRectsForRange(start: number, end: number): SkRect[] {\n return this.ref\n .getRectsForRange(\n start,\n end,\n { value: 0 } /** kTight */,\n { value: 0 } /** kTight */\n )\n .map(({ rect }) => new JsiSkRect(this.CanvasKit, rect));\n }\n getLineMetrics(): LineMetrics[] {\n return this.ref.getLineMetrics();\n }\n getPath(_lineNumber: number): SkPath | null {\n return throwNotImplementedOnRNWeb<SkPath | null>();\n }\n extendedVisit(_visitor: ParagraphExtendedVisitor): void {\n return throwNotImplementedOnRNWeb<void>();\n }\n}\n"],"mappings":";;;;;;AAWA,IAAAA,KAAA,GAAAC,OAAA;AAEA,IAAAC,UAAA,GAAAD,OAAA;AAEO,MAAME,cAAc,SACjBC,gBAAU,CAEpB;EACEC,WAAWA,CAACC,SAAoB,EAAEC,GAAc,EAAE;IAChD,KAAK,CAACD,SAAS,EAAEC,GAAG,EAAE,WAAW,CAAC;EACpC;EACAC,oBAAoBA,CAAA,EAAG;IACrB,OAAO,IAAI,CAACD,GAAG,CAACC,oBAAoB,CAAC,CAAC;EACxC;EAEAC,oBAAoBA,CAAA,EAAG;IACrB,OAAO,IAAI,CAACF,GAAG,CAACE,oBAAoB,CAAC,CAAC;EACxC;EAEAC,cAAcA,CAAA,EAAG;IACf,OAAO,IAAI,CAACH,GAAG,CAACG,cAAc,CAAC,CAAC;EAClC;EAEAC,MAAMA,CAACC,KAAa,EAAE;IACpB,IAAI,CAACL,GAAG,CAACI,MAAM,CAACC,KAAK,CAAC;EACxB;EACAC,KAAKA,CAACC,MAAmB,EAAEC,CAAS,EAAEC,CAAS,EAAE;IAC/CF,MAAM,CAACP,GAAG,CAACU,aAAa,CAAC,IAAI,CAACV,GAAG,EAAEQ,CAAC,EAAEC,CAAC,CAAC;EAC1C;EACAE,SAASA,CAAA,EAAG;IACV,OAAO,IAAI,CAACX,GAAG,CAACW,SAAS,CAAC,CAAC;EAC7B;EACAC,WAAWA,CAAA,EAAG;IACZ,OAAO,IAAI,CAACZ,GAAG,CAACY,WAAW,CAAC,CAAC;EAC/B;EACAC,4BAA4BA,CAACL,CAAS,EAAEC,CAAS,EAAE;IACjD,OAAO,IAAI,CAACT,GAAG,CAACa,4BAA4B,CAACL,CAAC,EAAEC,CAAC,CAAC,CAACK,GAAG;EACxD;EACAC,uBAAuBA,CAAA,EAA0B;IAC/C,OAAO,IAAI,CAACf,GAAG,CAACe,uBAAuB,CAAC,CAAC,CAACC,GAAG,CAAC,CAAC;MAAEC,IAAI;MAAEC;IAAI,CAAC,MAAM;MAChED,IAAI,EAAE,IAAIE,oBAAS,CAAC,IAAI,CAACpB,SAAS,EAAEkB,IAAI,CAAC;MACzCG,SAAS,EAAEF,GAAG,CAACG;IACjB,CAAC,CAAC,CAAC;EACL;EACAC,gBAAgBA,CAACC,KAAa,EAAEC,GAAW,EAAY;IACrD,OAAO,IAAI,CAACxB,GAAG,CACZsB,gBAAgB,CACfC,KAAK,EACLC,GAAG,EACH;MAAEH,KAAK,EAAE;IAAE,CAAC,CAAC,eACb;MAAEA,KAAK,EAAE;IAAE,CAAC,CAAC,aACf,CAAC,CACAL,GAAG,CAAC,CAAC;MAAEC;IAAK,CAAC,KAAK,IAAIE,oBAAS,CAAC,IAAI,CAACpB,SAAS,EAAEkB,IAAI,CAAC,CAAC;EAC3D;EACAQ,cAAcA,CAAA,EAAkB;IAC9B,OAAO,IAAI,CAACzB,GAAG,CAACyB,cAAc,CAAC,CAAC;EAClC;EACAC,OAAOA,CAACC,WAAmB,EAAiB;IAC1C,OAAO,IAAAC,gCAA0B,EAAgB,CAAC;EACpD;EACAC,aAAaA,CAACC,QAAkC,EAAQ;IACtD,OAAO,IAAAF,gCAA0B,EAAO,CAAC;EAC3C;AACF;AAACG,OAAA,CAAAnC,cAAA,GAAAA,cAAA","ignoreList":[]}
@@ -24,17 +24,30 @@ const {
24
24
  const drawOnscreen = (Skia, nativeId, recording) => {
25
25
  "worklet";
26
26
 
27
+ var _recording$lastPictur;
27
28
  const rec = Skia.PictureRecorder();
28
29
  const canvas = rec.beginRecording();
29
30
  //const start = performance.now();
30
31
 
31
32
  const ctx = (0, _DrawingContext.createDrawingContext)(Skia, recording.paintPool, canvas);
32
- (0, _Player.replay)(ctx, recording.commands);
33
- const picture = rec.finishRecordingAsPicture();
34
- rec.dispose();
33
+ let picture;
34
+ try {
35
+ (0, _Player.replay)(ctx, recording.commands);
36
+ picture = rec.finishRecordingAsPicture();
37
+ } finally {
38
+ // Frame-scoped objects (shaders, filters, paint copies, ...) are
39
+ // referenced by the picture once it is finished — delete the JS handles,
40
+ // otherwise they leak on Web where the GC cannot see WASM memory.
41
+ ctx.dispose();
42
+ rec.dispose();
43
+ }
35
44
  //const end = performance.now();
36
45
  //console.log("Recording time: ", end - start);
37
46
  SkiaViewApi.setJsiProperty(nativeId, "picture", picture);
47
+ // The view now references the new picture; the previous one is ours to
48
+ // delete.
49
+ (_recording$lastPictur = recording.lastPicture) === null || _recording$lastPictur === void 0 || _recording$lastPictur.dispose();
50
+ recording.lastPicture = picture;
38
51
  };
39
52
  class ReanimatedContainer extends _StaticContainer.Container {
40
53
  constructor(Skia, nativeId) {
@@ -51,6 +64,19 @@ class ReanimatedContainer extends _StaticContainer.Container {
51
64
  _ReanimatedProxy.default.stopMapper(this.mapperId);
52
65
  this.mapperId = null;
53
66
  }
67
+ const {
68
+ recording
69
+ } = this;
70
+ if (recording) {
71
+ this.recording = null;
72
+ // Deferred through the same channel as the draw calls so it runs after
73
+ // any of them that are still queued.
74
+ _ReanimatedProxy.default.runOnUI(() => {
75
+ "worklet";
76
+
77
+ (0, _Recorder.disposeRecording)(recording);
78
+ })();
79
+ }
54
80
  }
55
81
  redraw() {
56
82
  if (this.mapperId !== null) {
@@ -60,6 +86,7 @@ class ReanimatedContainer extends _StaticContainer.Container {
60
86
  if (this.unmounted) {
61
87
  return;
62
88
  }
89
+ const previousRecording = this.recording;
63
90
  const recorder = new _Recorder.Recorder();
64
91
  (0, _Visitor.visit)(recorder, this.root);
65
92
  const record = recorder.getRecording();
@@ -85,6 +112,10 @@ class ReanimatedContainer extends _StaticContainer.Container {
85
112
  _ReanimatedProxy.default.runOnUI(() => {
86
113
  "worklet";
87
114
 
115
+ if (previousRecording) {
116
+ // Runs after any still-queued draw of the previous recording.
117
+ (0, _Recorder.disposeRecording)(previousRecording);
118
+ }
88
119
  drawOnscreen(Skia, nativeId, recording);
89
120
  })();
90
121
  }
@@ -1 +1 @@
1
- {"version":3,"names":["_ReanimatedProxy","_interopRequireDefault","require","_renderHelpers","_Recorder","_Visitor","_Player","_DrawingContext","_StaticContainer","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","SkiaViewApi","globalThis","drawOnscreen","Skia","nativeId","recording","rec","PictureRecorder","canvas","beginRecording","ctx","createDrawingContext","paintPool","replay","commands","picture","finishRecordingAsPicture","dispose","setJsiProperty","ReanimatedContainer","Container","constructor","unmount","mapperId","Rea","stopMapper","redraw","unmounted","recorder","Recorder","visit","root","record","getRecording","animationValues","size","startMapper","Array","from","runOnUI","createContainer","HAS_REANIMATED_3","StaticContainer","exports"],"sources":["Container.web.ts"],"sourcesContent":["import Rea from \"../external/reanimated/ReanimatedProxy\";\nimport type { Skia } from \"../skia/types\";\nimport { HAS_REANIMATED_3 } from \"../external/reanimated/renderHelpers\";\n\nimport type { Recording } from \"./Recorder/Recorder\";\nimport { Recorder } from \"./Recorder/Recorder\";\nimport { visit } from \"./Recorder/Visitor\";\nimport { replay } from \"./Recorder/Player\";\nimport { createDrawingContext } from \"./Recorder/DrawingContext\";\nimport { Container, StaticContainer } from \"./StaticContainer\";\n\nimport \"../skia/NativeSetup\";\nimport \"../views/api\";\n\n// create local reference for `strictGlobal` option in Worklets\nconst { SkiaViewApi } = globalThis;\n\nconst drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {\n \"worklet\";\n const rec = Skia.PictureRecorder();\n const canvas = rec.beginRecording();\n //const start = performance.now();\n\n const ctx = createDrawingContext(Skia, recording.paintPool, canvas);\n replay(ctx, recording.commands);\n const picture = rec.finishRecordingAsPicture();\n rec.dispose();\n //const end = performance.now();\n //console.log(\"Recording time: \", end - start);\n SkiaViewApi.setJsiProperty(nativeId, \"picture\", picture);\n};\n\nclass ReanimatedContainer extends Container {\n private mapperId: number | null = null;\n\n constructor(\n Skia: Skia,\n private nativeId: number\n ) {\n super(Skia);\n }\n\n unmount() {\n super.unmount();\n if (this.mapperId !== null) {\n // The mapper closure retains the recording and keeps updating the\n // picture of an unmounted view — stop it or it leaks for the\n // lifetime of the app.\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n }\n\n redraw() {\n if (this.mapperId !== null) {\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n if (this.unmounted) {\n return;\n }\n const recorder = new Recorder();\n visit(recorder, this.root);\n const record = recorder.getRecording();\n const { animationValues } = record;\n this.recording = {\n commands: record.commands,\n paintPool: record.paintPool,\n };\n const { nativeId, Skia, recording } = this;\n if (animationValues.size > 0) {\n this.mapperId = Rea.startMapper(() => {\n \"worklet\";\n drawOnscreen(Skia, nativeId, recording!);\n }, Array.from(animationValues));\n }\n Rea.runOnUI(() => {\n \"worklet\";\n drawOnscreen(Skia, nativeId, recording!);\n })();\n }\n}\n\nexport const createContainer = (Skia: Skia, nativeId: number) => {\n if (HAS_REANIMATED_3 && nativeId !== -1) {\n return new ReanimatedContainer(Skia, nativeId);\n } else {\n return new StaticContainer(Skia, nativeId);\n }\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_ReanimatedProxy","_interopRequireDefault","require","_renderHelpers","_Recorder","_Visitor","_Player","_DrawingContext","_StaticContainer","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","SkiaViewApi","globalThis","drawOnscreen","Skia","nativeId","recording","_recording$lastPictur","rec","PictureRecorder","canvas","beginRecording","ctx","createDrawingContext","paintPool","picture","replay","commands","finishRecordingAsPicture","dispose","setJsiProperty","lastPicture","ReanimatedContainer","Container","constructor","unmount","mapperId","Rea","stopMapper","runOnUI","disposeRecording","redraw","unmounted","previousRecording","recorder","Recorder","visit","root","record","getRecording","animationValues","size","startMapper","Array","from","createContainer","HAS_REANIMATED_3","StaticContainer","exports"],"sources":["Container.web.ts"],"sourcesContent":["import Rea from \"../external/reanimated/ReanimatedProxy\";\nimport type { Skia } from \"../skia/types\";\nimport { HAS_REANIMATED_3 } from \"../external/reanimated/renderHelpers\";\n\nimport type { Recording } from \"./Recorder/Recorder\";\nimport { Recorder, disposeRecording } from \"./Recorder/Recorder\";\nimport { visit } from \"./Recorder/Visitor\";\nimport { replay } from \"./Recorder/Player\";\nimport { createDrawingContext } from \"./Recorder/DrawingContext\";\nimport { Container, StaticContainer } from \"./StaticContainer\";\n\nimport \"../skia/NativeSetup\";\nimport \"../views/api\";\n\n// create local reference for `strictGlobal` option in Worklets\nconst { SkiaViewApi } = globalThis;\n\nconst drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {\n \"worklet\";\n const rec = Skia.PictureRecorder();\n const canvas = rec.beginRecording();\n //const start = performance.now();\n\n const ctx = createDrawingContext(Skia, recording.paintPool, canvas);\n let picture;\n try {\n replay(ctx, recording.commands);\n picture = rec.finishRecordingAsPicture();\n } finally {\n // Frame-scoped objects (shaders, filters, paint copies, ...) are\n // referenced by the picture once it is finished — delete the JS handles,\n // otherwise they leak on Web where the GC cannot see WASM memory.\n ctx.dispose();\n rec.dispose();\n }\n //const end = performance.now();\n //console.log(\"Recording time: \", end - start);\n SkiaViewApi.setJsiProperty(nativeId, \"picture\", picture);\n // The view now references the new picture; the previous one is ours to\n // delete.\n recording.lastPicture?.dispose();\n recording.lastPicture = picture;\n};\n\nclass ReanimatedContainer extends Container {\n private mapperId: number | null = null;\n\n constructor(\n Skia: Skia,\n private nativeId: number\n ) {\n super(Skia);\n }\n\n unmount() {\n super.unmount();\n if (this.mapperId !== null) {\n // The mapper closure retains the recording and keeps updating the\n // picture of an unmounted view — stop it or it leaks for the\n // lifetime of the app.\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n const { recording } = this;\n if (recording) {\n this.recording = null;\n // Deferred through the same channel as the draw calls so it runs after\n // any of them that are still queued.\n Rea.runOnUI(() => {\n \"worklet\";\n disposeRecording(recording);\n })();\n }\n }\n\n redraw() {\n if (this.mapperId !== null) {\n Rea.stopMapper(this.mapperId);\n this.mapperId = null;\n }\n if (this.unmounted) {\n return;\n }\n const previousRecording = this.recording;\n const recorder = new Recorder();\n visit(recorder, this.root);\n const record = recorder.getRecording();\n const { animationValues } = record;\n this.recording = {\n commands: record.commands,\n paintPool: record.paintPool,\n };\n const { nativeId, Skia, recording } = this;\n if (animationValues.size > 0) {\n this.mapperId = Rea.startMapper(() => {\n \"worklet\";\n drawOnscreen(Skia, nativeId, recording!);\n }, Array.from(animationValues));\n }\n Rea.runOnUI(() => {\n \"worklet\";\n if (previousRecording) {\n // Runs after any still-queued draw of the previous recording.\n disposeRecording(previousRecording);\n }\n drawOnscreen(Skia, nativeId, recording!);\n })();\n }\n}\n\nexport const createContainer = (Skia: Skia, nativeId: number) => {\n if (HAS_REANIMATED_3 && nativeId !== -1) {\n return new ReanimatedContainer(Skia, nativeId);\n } else {\n return new StaticContainer(Skia, nativeId);\n }\n};\n"],"mappings":"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","ignoreList":[]}