@shopify/react-native-skia 2.7.0 → 2.9.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 (157) hide show
  1. package/android/build.gradle +10 -4
  2. package/android/cpp/rnskia-android/OpenGLContext.h +29 -3
  3. package/android/cpp/rnskia-android/OpenGLWindowContext.cpp +9 -2
  4. package/android/cpp/rnskia-android/gl/Context.h +3 -0
  5. package/android/cpp/rnskia-android/gl/Surface.h +1 -1
  6. package/cpp/api/JsiSkParagraph.h +114 -0
  7. package/cpp/api/JsiSkiaContext.h +4 -0
  8. package/cpp/rnskia/RNSkView.h +6 -0
  9. package/lib/commonjs/Platform/Platform.js +5 -2
  10. package/lib/commonjs/Platform/Platform.js.map +1 -1
  11. package/lib/commonjs/Platform/Platform.web.js +8 -7
  12. package/lib/commonjs/Platform/Platform.web.js.map +1 -1
  13. package/lib/commonjs/external/reanimated/useVideoLoading.js +11 -2
  14. package/lib/commonjs/external/reanimated/useVideoLoading.js.map +1 -1
  15. package/lib/commonjs/skia/core/Font.d.ts +21 -6
  16. package/lib/commonjs/skia/core/Font.js +24 -4
  17. package/lib/commonjs/skia/core/Font.js.map +1 -1
  18. package/lib/commonjs/skia/core/SVG.web.js +4 -5
  19. package/lib/commonjs/skia/core/SVG.web.js.map +1 -1
  20. package/lib/commonjs/skia/types/Data/Data.d.ts +5 -4
  21. package/lib/commonjs/skia/types/Data/Data.js +7 -1
  22. package/lib/commonjs/skia/types/Data/Data.js.map +1 -1
  23. package/lib/commonjs/skia/types/Paragraph/Paragraph.d.ts +62 -0
  24. package/lib/commonjs/skia/types/Paragraph/Paragraph.js.map +1 -1
  25. package/lib/commonjs/skia/web/Host.js +7 -0
  26. package/lib/commonjs/skia/web/Host.js.map +1 -1
  27. package/lib/commonjs/skia/web/JsiSkFont.d.ts +1 -1
  28. package/lib/commonjs/skia/web/JsiSkFont.js +43 -2
  29. package/lib/commonjs/skia/web/JsiSkFont.js.map +1 -1
  30. package/lib/commonjs/skia/web/JsiSkPaint.js +5 -0
  31. package/lib/commonjs/skia/web/JsiSkPaint.js.map +1 -1
  32. package/lib/commonjs/skia/web/JsiSkParagraph.d.ts +3 -1
  33. package/lib/commonjs/skia/web/JsiSkParagraph.js +6 -0
  34. package/lib/commonjs/skia/web/JsiSkParagraph.js.map +1 -1
  35. package/lib/commonjs/sksg/Container.web.js +34 -3
  36. package/lib/commonjs/sksg/Container.web.js.map +1 -1
  37. package/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +2 -0
  38. package/lib/commonjs/sksg/Recorder/DrawingContext.js +22 -6
  39. package/lib/commonjs/sksg/Recorder/DrawingContext.js.map +1 -1
  40. package/lib/commonjs/sksg/Recorder/FrameScope.d.ts +18 -0
  41. package/lib/commonjs/sksg/Recorder/FrameScope.js +66 -0
  42. package/lib/commonjs/sksg/Recorder/FrameScope.js.map +1 -0
  43. package/lib/commonjs/sksg/Recorder/FrameScope.native.d.ts +10 -0
  44. package/lib/commonjs/sksg/Recorder/FrameScope.native.js +26 -0
  45. package/lib/commonjs/sksg/Recorder/FrameScope.native.js.map +1 -0
  46. package/lib/commonjs/sksg/Recorder/Player.js +1 -2
  47. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  48. package/lib/commonjs/sksg/Recorder/Recorder.d.ts +3 -1
  49. package/lib/commonjs/sksg/Recorder/Recorder.js +12 -1
  50. package/lib/commonjs/sksg/Recorder/Recorder.js.map +1 -1
  51. package/lib/commonjs/sksg/Recorder/commands/Drawing.js +3 -3
  52. package/lib/commonjs/sksg/Recorder/commands/Drawing.js.map +1 -1
  53. package/lib/commonjs/sksg/Recorder/commands/Shaders.js +3 -3
  54. package/lib/commonjs/sksg/Recorder/commands/Shaders.js.map +1 -1
  55. package/lib/commonjs/sksg/StaticContainer.d.ts +1 -0
  56. package/lib/commonjs/sksg/StaticContainer.js +27 -1
  57. package/lib/commonjs/sksg/StaticContainer.js.map +1 -1
  58. package/lib/module/Platform/Platform.js +6 -3
  59. package/lib/module/Platform/Platform.js.map +1 -1
  60. package/lib/module/Platform/Platform.web.js +9 -8
  61. package/lib/module/Platform/Platform.web.js.map +1 -1
  62. package/lib/module/external/reanimated/useVideoLoading.js +12 -2
  63. package/lib/module/external/reanimated/useVideoLoading.js.map +1 -1
  64. package/lib/module/skia/core/Font.d.ts +21 -6
  65. package/lib/module/skia/core/Font.js +26 -5
  66. package/lib/module/skia/core/Font.js.map +1 -1
  67. package/lib/module/skia/core/SVG.web.js +4 -5
  68. package/lib/module/skia/core/SVG.web.js.map +1 -1
  69. package/lib/module/skia/types/Data/Data.d.ts +5 -4
  70. package/lib/module/skia/types/Data/Data.js +5 -0
  71. package/lib/module/skia/types/Data/Data.js.map +1 -1
  72. package/lib/module/skia/types/Paragraph/Paragraph.d.ts +62 -0
  73. package/lib/module/skia/types/Paragraph/Paragraph.js.map +1 -1
  74. package/lib/module/skia/web/Host.js +7 -0
  75. package/lib/module/skia/web/Host.js.map +1 -1
  76. package/lib/module/skia/web/JsiSkFont.d.ts +1 -1
  77. package/lib/module/skia/web/JsiSkFont.js +44 -3
  78. package/lib/module/skia/web/JsiSkFont.js.map +1 -1
  79. package/lib/module/skia/web/JsiSkPaint.js +5 -0
  80. package/lib/module/skia/web/JsiSkPaint.js.map +1 -1
  81. package/lib/module/skia/web/JsiSkParagraph.d.ts +3 -1
  82. package/lib/module/skia/web/JsiSkParagraph.js +7 -1
  83. package/lib/module/skia/web/JsiSkParagraph.js.map +1 -1
  84. package/lib/module/sksg/Container.web.js +35 -4
  85. package/lib/module/sksg/Container.web.js.map +1 -1
  86. package/lib/module/sksg/Recorder/DrawingContext.d.ts +2 -0
  87. package/lib/module/sksg/Recorder/DrawingContext.js +22 -6
  88. package/lib/module/sksg/Recorder/DrawingContext.js.map +1 -1
  89. package/lib/module/sksg/Recorder/FrameScope.d.ts +18 -0
  90. package/lib/module/sksg/Recorder/FrameScope.js +59 -0
  91. package/lib/module/sksg/Recorder/FrameScope.js.map +1 -0
  92. package/lib/module/sksg/Recorder/FrameScope.native.d.ts +10 -0
  93. package/lib/module/sksg/Recorder/FrameScope.native.js +19 -0
  94. package/lib/module/sksg/Recorder/FrameScope.native.js.map +1 -0
  95. package/lib/module/sksg/Recorder/Player.js +1 -2
  96. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  97. package/lib/module/sksg/Recorder/Recorder.d.ts +3 -1
  98. package/lib/module/sksg/Recorder/Recorder.js +10 -0
  99. package/lib/module/sksg/Recorder/Recorder.js.map +1 -1
  100. package/lib/module/sksg/Recorder/commands/Drawing.js +3 -3
  101. package/lib/module/sksg/Recorder/commands/Drawing.js.map +1 -1
  102. package/lib/module/sksg/Recorder/commands/Shaders.js +3 -3
  103. package/lib/module/sksg/Recorder/commands/Shaders.js.map +1 -1
  104. package/lib/module/sksg/StaticContainer.d.ts +1 -0
  105. package/lib/module/sksg/StaticContainer.js +28 -2
  106. package/lib/module/sksg/StaticContainer.js.map +1 -1
  107. package/lib/typescript/lib/commonjs/skia/types/Data/Data.d.ts +1 -0
  108. package/lib/typescript/lib/commonjs/skia/web/JsiSkFont.d.ts +1 -1
  109. package/lib/typescript/lib/commonjs/skia/web/JsiSkParagraph.d.ts +2 -0
  110. package/lib/typescript/lib/commonjs/sksg/Container.web.d.ts +2 -2
  111. package/lib/typescript/lib/commonjs/sksg/Recorder/DrawingContext.d.ts +2 -0
  112. package/lib/typescript/lib/commonjs/sksg/Recorder/FrameScope.d.ts +17 -0
  113. package/lib/typescript/lib/commonjs/sksg/Recorder/FrameScope.native.d.ts +13 -0
  114. package/lib/typescript/lib/commonjs/sksg/Recorder/Recorder.d.ts +1 -0
  115. package/lib/typescript/lib/commonjs/sksg/StaticContainer.d.ts +2 -2
  116. package/lib/typescript/lib/module/mock/index.d.ts +1 -0
  117. package/lib/typescript/lib/module/skia/types/Data/Data.d.ts +1 -0
  118. package/lib/typescript/lib/module/skia/web/JsiSkFont.d.ts +1 -1
  119. package/lib/typescript/lib/module/skia/web/JsiSkParagraph.d.ts +2 -0
  120. package/lib/typescript/lib/module/sksg/Container.web.d.ts +2 -2
  121. package/lib/typescript/lib/module/sksg/Recorder/DrawingContext.d.ts +2 -0
  122. package/lib/typescript/lib/module/sksg/Recorder/FrameScope.d.ts +5 -0
  123. package/lib/typescript/lib/module/sksg/Recorder/FrameScope.native.d.ts +5 -0
  124. package/lib/typescript/lib/module/sksg/Recorder/Recorder.d.ts +1 -0
  125. package/lib/typescript/lib/module/sksg/StaticContainer.d.ts +2 -2
  126. package/lib/typescript/src/skia/core/Font.d.ts +21 -6
  127. package/lib/typescript/src/skia/types/Data/Data.d.ts +5 -4
  128. package/lib/typescript/src/skia/types/Paragraph/Paragraph.d.ts +62 -0
  129. package/lib/typescript/src/skia/web/JsiSkFont.d.ts +1 -1
  130. package/lib/typescript/src/skia/web/JsiSkParagraph.d.ts +3 -1
  131. package/lib/typescript/src/sksg/Recorder/DrawingContext.d.ts +2 -0
  132. package/lib/typescript/src/sksg/Recorder/FrameScope.d.ts +18 -0
  133. package/lib/typescript/src/sksg/Recorder/FrameScope.native.d.ts +10 -0
  134. package/lib/typescript/src/sksg/Recorder/Recorder.d.ts +3 -1
  135. package/lib/typescript/src/sksg/StaticContainer.d.ts +1 -0
  136. package/package.json +8 -2
  137. package/react-native-skia.podspec +18 -10
  138. package/src/Platform/Platform.ts +6 -7
  139. package/src/Platform/Platform.web.tsx +9 -8
  140. package/src/external/reanimated/useVideoLoading.ts +12 -2
  141. package/src/skia/core/Font.ts +34 -13
  142. package/src/skia/core/SVG.web.ts +5 -14
  143. package/src/skia/types/Data/Data.ts +14 -4
  144. package/src/skia/types/Paragraph/Paragraph.ts +67 -0
  145. package/src/skia/web/Host.ts +7 -0
  146. package/src/skia/web/JsiSkFont.ts +48 -4
  147. package/src/skia/web/JsiSkPaint.ts +5 -0
  148. package/src/skia/web/JsiSkParagraph.ts +9 -1
  149. package/src/sksg/Container.web.ts +31 -4
  150. package/src/sksg/Recorder/DrawingContext.ts +19 -6
  151. package/src/sksg/Recorder/FrameScope.native.ts +21 -0
  152. package/src/sksg/Recorder/FrameScope.ts +69 -0
  153. package/src/sksg/Recorder/Player.ts +1 -2
  154. package/src/sksg/Recorder/Recorder.ts +15 -1
  155. package/src/sksg/Recorder/commands/Drawing.ts +3 -3
  156. package/src/sksg/Recorder/commands/Shaders.ts +22 -16
  157. package/src/sksg/StaticContainer.ts +29 -2
@@ -1,17 +1,18 @@
1
1
  import type { SkJSIInstance } from "../JsiInstance";
2
2
  export type SkData = SkJSIInstance<"Data">;
3
3
  type RNModule = number;
4
- type ESModule = {
5
- __esModule: true;
6
- default: string;
7
- };
8
4
  type MetroAsset = {
9
5
  uri: string;
10
6
  width: number;
11
7
  height: number;
12
8
  };
9
+ type ESModule = {
10
+ __esModule: true;
11
+ default: RNModule | MetroAsset | string;
12
+ };
13
13
  export type DataModule = RNModule | ESModule | MetroAsset;
14
14
  export type DataSource = DataModule | string | Uint8Array;
15
15
  export type DataSourceParam = DataSource | null | undefined;
16
16
  export declare const isRNModule: (mod: DataModule) => mod is RNModule;
17
+ export declare const unwrapModule: (mod: DataModule) => RNModule | MetroAsset | string;
17
18
  export {};
@@ -3,7 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isRNModule = void 0;
6
+ exports.unwrapModule = exports.isRNModule = void 0;
7
7
  const isRNModule = mod => typeof mod === "number";
8
+
9
+ // Since Expo SDK 52, on web, require() may return an ES module interop
10
+ // object ({ default: <asset> }) instead of the asset itself.
11
+ // See https://github.com/Shopify/react-native-skia/issues/2784
8
12
  exports.isRNModule = isRNModule;
13
+ const unwrapModule = mod => typeof mod === "object" && mod !== null && "default" in mod ? mod.default : mod;
14
+ exports.unwrapModule = unwrapModule;
9
15
  //# sourceMappingURL=Data.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["isRNModule","mod","exports"],"sources":["Data.ts"],"sourcesContent":["import type { SkJSIInstance } from \"../JsiInstance\";\n\nexport type SkData = SkJSIInstance<\"Data\">;\n\ntype RNModule = number;\ntype ESModule = {\n __esModule: true;\n default: string;\n};\ntype MetroAsset = {\n uri: string;\n width: number;\n height: number;\n};\n\nexport type DataModule = RNModule | ESModule | MetroAsset;\nexport type DataSource = DataModule | string | Uint8Array;\nexport type DataSourceParam = DataSource | null | undefined;\n\nexport const isRNModule = (mod: DataModule): mod is RNModule =>\n typeof mod === \"number\";\n"],"mappings":";;;;;;AAmBO,MAAMA,UAAU,GAAIC,GAAe,IACxC,OAAOA,GAAG,KAAK,QAAQ;AAACC,OAAA,CAAAF,UAAA,GAAAA,UAAA","ignoreList":[]}
1
+ {"version":3,"names":["isRNModule","mod","exports","unwrapModule","default"],"sources":["Data.ts"],"sourcesContent":["import type { SkJSIInstance } from \"../JsiInstance\";\n\nexport type SkData = SkJSIInstance<\"Data\">;\n\ntype RNModule = number;\ntype MetroAsset = {\n uri: string;\n width: number;\n height: number;\n};\ntype ESModule = {\n __esModule: true;\n default: RNModule | MetroAsset | string;\n};\n\nexport type DataModule = RNModule | ESModule | MetroAsset;\nexport type DataSource = DataModule | string | Uint8Array;\nexport type DataSourceParam = DataSource | null | undefined;\n\nexport const isRNModule = (mod: DataModule): mod is RNModule =>\n typeof mod === \"number\";\n\n// Since Expo SDK 52, on web, require() may return an ES module interop\n// object ({ default: <asset> }) instead of the asset itself.\n// See https://github.com/Shopify/react-native-skia/issues/2784\nexport const unwrapModule = (\n mod: DataModule\n): RNModule | MetroAsset | string =>\n typeof mod === \"object\" && mod !== null && \"default\" in mod\n ? mod.default\n : mod;\n"],"mappings":";;;;;;AAmBO,MAAMA,UAAU,GAAIC,GAAe,IACxC,OAAOA,GAAG,KAAK,QAAQ;;AAEzB;AACA;AACA;AAAAC,OAAA,CAAAF,UAAA,GAAAA,UAAA;AACO,MAAMG,YAAY,GACvBF,GAAe,IAEf,OAAOA,GAAG,KAAK,QAAQ,IAAIA,GAAG,KAAK,IAAI,IAAI,SAAS,IAAIA,GAAG,GACvDA,GAAG,CAACG,OAAO,GACXH,GAAG;AAACC,OAAA,CAAAC,YAAA,GAAAA,YAAA","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":[]}
@@ -5,7 +5,7 @@ import { JsiSkRect } from "./JsiSkRect";
5
5
  import { JsiSkTypeface } from "./JsiSkTypeface";
6
6
  export declare class JsiSkFont extends HostObject<Font, "Font"> implements SkFont {
7
7
  constructor(CanvasKit: CanvasKit, ref: Font);
8
- measureText(_text: string, _paint?: SkPaint | undefined): SkRect;
8
+ measureText(text: string, paint?: SkPaint | undefined): SkRect;
9
9
  getTextWidth(text: string, paint?: SkPaint | undefined): number;
10
10
  getMetrics(): {
11
11
  ascent: number;
@@ -13,8 +13,49 @@ class JsiSkFont extends _Host.HostObject {
13
13
  constructor(CanvasKit, ref) {
14
14
  super(CanvasKit, ref, "Font");
15
15
  }
16
- measureText(_text, _paint) {
17
- return (0, _Host.throwNotImplementedOnRNWeb)();
16
+ measureText(text, paint) {
17
+ // CanvasKit doesn't expose SkFont::measureText directly, so we polyfill
18
+ // it: for each glyph we take its ink bounds (relative to its own origin),
19
+ // offset it by the accumulated advance, and union the results. This
20
+ // matches the bounds computed natively by SkFont::measureText.
21
+ const glyphs = this.ref.getGlyphIDs(text);
22
+ if (glyphs.length === 0) {
23
+ return new _JsiSkRect.JsiSkRect(this.CanvasKit, this.CanvasKit.XYWHRect(0, 0, 0, 0));
24
+ }
25
+ const skPaint = paint ? _JsiSkPaint.JsiSkPaint.fromValue(paint) : null;
26
+ // Flattened rectangles: 4 floats (left, top, right, bottom) per glyph.
27
+ const bounds = this.ref.getGlyphBounds(glyphs, skPaint);
28
+ const advances = this.ref.getGlyphWidths(glyphs, skPaint);
29
+ let left = 0;
30
+ let top = 0;
31
+ let right = 0;
32
+ let bottom = 0;
33
+ let isEmpty = true;
34
+ let xPos = 0;
35
+ for (let i = 0; i < glyphs.length; i++) {
36
+ const l = bounds[i * 4] + xPos;
37
+ const t = bounds[i * 4 + 1];
38
+ const r = bounds[i * 4 + 2] + xPos;
39
+ const b = bounds[i * 4 + 3];
40
+ xPos += advances[i];
41
+ // Skip empty glyph bounds (e.g. whitespace), like SkRect::join does.
42
+ if (l >= r || t >= b) {
43
+ continue;
44
+ }
45
+ if (isEmpty) {
46
+ left = l;
47
+ top = t;
48
+ right = r;
49
+ bottom = b;
50
+ isEmpty = false;
51
+ } else {
52
+ left = Math.min(left, l);
53
+ top = Math.min(top, t);
54
+ right = Math.max(right, r);
55
+ bottom = Math.max(bottom, b);
56
+ }
57
+ }
58
+ return new _JsiSkRect.JsiSkRect(this.CanvasKit, this.CanvasKit.LTRBRect(left, top, right, bottom));
18
59
  }
19
60
  getTextWidth(text, paint) {
20
61
  const ids = this.getGlyphIDs(text);
@@ -1 +1 @@
1
- {"version":3,"names":["_Host","require","_JsiSkPaint","_JsiSkPoint","_JsiSkRect","_JsiSkTypeface","JsiSkFont","HostObject","constructor","CanvasKit","ref","measureText","_text","_paint","throwNotImplementedOnRNWeb","getTextWidth","text","paint","ids","getGlyphIDs","widths","getGlyphWidths","reduce","a","b","getMetrics","result","ascent","descent","leading","bounds","JsiSkRect","undefined","str","numCodePoints","glyphs","JsiSkPaint","fromValue","getGlyphIntercepts","positions","top","bottom","map","p","Array","from","JsiSkPoint","flat","getScaleX","getSize","getSkewX","isEmbolden","getTypeface","tf","JsiSkTypeface","setEdging","edging","getEnum","setEmbeddedBitmaps","embeddedBitmaps","setHinting","hinting","setLinearMetrics","linearMetrics","setScaleX","sx","setSize","points","setSkewX","setEmbolden","embolden","setSubpixel","subpixel","setTypeface","face","exports"],"sources":["JsiSkFont.ts"],"sourcesContent":["import type { CanvasKit, Font } from \"canvaskit-wasm\";\n\nimport type {\n FontEdging,\n FontHinting,\n SkFont,\n SkPaint,\n SkPoint,\n SkRect,\n SkTypeface,\n} from \"../types\";\n\nimport { HostObject, getEnum, throwNotImplementedOnRNWeb } from \"./Host\";\nimport { JsiSkPaint } from \"./JsiSkPaint\";\nimport { JsiSkPoint } from \"./JsiSkPoint\";\nimport { JsiSkRect } from \"./JsiSkRect\";\nimport { JsiSkTypeface } from \"./JsiSkTypeface\";\n\nexport class JsiSkFont extends HostObject<Font, \"Font\"> implements SkFont {\n constructor(CanvasKit: CanvasKit, ref: Font) {\n super(CanvasKit, ref, \"Font\");\n }\n\n measureText(_text: string, _paint?: SkPaint | undefined) {\n return throwNotImplementedOnRNWeb<SkRect>();\n }\n\n getTextWidth(text: string, paint?: SkPaint | undefined) {\n const ids = this.getGlyphIDs(text);\n const widths = this.getGlyphWidths(ids, paint);\n return widths.reduce((a, b) => a + b, 0);\n }\n\n getMetrics() {\n const result = this.ref.getMetrics();\n return {\n ascent: result.ascent,\n descent: result.descent,\n leading: result.leading,\n bounds: result.bounds\n ? new JsiSkRect(this.CanvasKit, result.bounds)\n : undefined,\n };\n }\n\n getGlyphIDs(str: string, numCodePoints?: number) {\n // TODO: Fix return value in the C++ implementation\n return [...this.ref.getGlyphIDs(str, numCodePoints)];\n }\n\n // TODO: Fix return value in the C++ implementation, it return float32\n getGlyphWidths(glyphs: number[], paint?: SkPaint | null) {\n return [\n ...this.ref.getGlyphWidths(\n glyphs,\n paint ? JsiSkPaint.fromValue(paint) : null\n ),\n ];\n }\n\n getGlyphIntercepts(\n glyphs: number[],\n positions: SkPoint[],\n top: number,\n bottom: number\n ) {\n return [\n ...this.ref.getGlyphIntercepts(\n glyphs,\n positions.map((p) => Array.from(JsiSkPoint.fromValue(p))).flat(),\n top,\n bottom\n ),\n ];\n }\n\n getScaleX() {\n return this.ref.getScaleX();\n }\n\n getSize() {\n return this.ref.getSize();\n }\n\n getSkewX() {\n return this.ref.getSkewX();\n }\n\n isEmbolden() {\n return this.ref.isEmbolden();\n }\n\n getTypeface() {\n const tf = this.ref.getTypeface();\n return tf ? new JsiSkTypeface(this.CanvasKit, tf) : null;\n }\n\n setEdging(edging: FontEdging) {\n this.ref.setEdging(getEnum(this.CanvasKit, \"FontEdging\", edging));\n }\n\n setEmbeddedBitmaps(embeddedBitmaps: boolean) {\n this.ref.setEmbeddedBitmaps(embeddedBitmaps);\n }\n\n setHinting(hinting: FontHinting) {\n this.ref.setHinting(getEnum(this.CanvasKit, \"FontHinting\", hinting));\n }\n\n setLinearMetrics(linearMetrics: boolean) {\n this.ref.setLinearMetrics(linearMetrics);\n }\n\n setScaleX(sx: number) {\n this.ref.setScaleX(sx);\n }\n\n setSize(points: number) {\n this.ref.setSize(points);\n }\n\n setSkewX(sx: number) {\n this.ref.setSkewX(sx);\n }\n\n setEmbolden(embolden: boolean) {\n this.ref.setEmbolden(embolden);\n }\n\n setSubpixel(subpixel: boolean) {\n this.ref.setSubpixel(subpixel);\n }\n\n setTypeface(face: SkTypeface | null) {\n this.ref.setTypeface(face ? JsiSkTypeface.fromValue(face) : null);\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_Host","require","_JsiSkPaint","_JsiSkPoint","_JsiSkRect","_JsiSkTypeface","JsiSkFont","HostObject","constructor","CanvasKit","ref","measureText","text","paint","glyphs","getGlyphIDs","length","JsiSkRect","XYWHRect","skPaint","JsiSkPaint","fromValue","bounds","getGlyphBounds","advances","getGlyphWidths","left","top","right","bottom","isEmpty","xPos","i","l","t","r","b","Math","min","max","LTRBRect","getTextWidth","ids","widths","reduce","a","getMetrics","result","ascent","descent","leading","undefined","str","numCodePoints","getGlyphIntercepts","positions","map","p","Array","from","JsiSkPoint","flat","getScaleX","getSize","getSkewX","isEmbolden","getTypeface","tf","JsiSkTypeface","setEdging","edging","getEnum","setEmbeddedBitmaps","embeddedBitmaps","setHinting","hinting","setLinearMetrics","linearMetrics","setScaleX","sx","setSize","points","setSkewX","setEmbolden","embolden","setSubpixel","subpixel","setTypeface","face","exports"],"sources":["JsiSkFont.ts"],"sourcesContent":["import type { CanvasKit, Font, Paint } from \"canvaskit-wasm\";\n\nimport type {\n FontEdging,\n FontHinting,\n SkFont,\n SkPaint,\n SkPoint,\n SkRect,\n SkTypeface,\n} from \"../types\";\n\nimport { HostObject, getEnum } from \"./Host\";\nimport { JsiSkPaint } from \"./JsiSkPaint\";\nimport { JsiSkPoint } from \"./JsiSkPoint\";\nimport { JsiSkRect } from \"./JsiSkRect\";\nimport { JsiSkTypeface } from \"./JsiSkTypeface\";\n\nexport class JsiSkFont extends HostObject<Font, \"Font\"> implements SkFont {\n constructor(CanvasKit: CanvasKit, ref: Font) {\n super(CanvasKit, ref, \"Font\");\n }\n\n measureText(text: string, paint?: SkPaint | undefined): SkRect {\n // CanvasKit doesn't expose SkFont::measureText directly, so we polyfill\n // it: for each glyph we take its ink bounds (relative to its own origin),\n // offset it by the accumulated advance, and union the results. This\n // matches the bounds computed natively by SkFont::measureText.\n const glyphs = this.ref.getGlyphIDs(text);\n if (glyphs.length === 0) {\n return new JsiSkRect(this.CanvasKit, this.CanvasKit.XYWHRect(0, 0, 0, 0));\n }\n const skPaint = paint ? JsiSkPaint.fromValue<Paint>(paint) : null;\n // Flattened rectangles: 4 floats (left, top, right, bottom) per glyph.\n const bounds = this.ref.getGlyphBounds(glyphs, skPaint);\n const advances = this.ref.getGlyphWidths(glyphs, skPaint);\n let left = 0;\n let top = 0;\n let right = 0;\n let bottom = 0;\n let isEmpty = true;\n let xPos = 0;\n for (let i = 0; i < glyphs.length; i++) {\n const l = bounds[i * 4] + xPos;\n const t = bounds[i * 4 + 1];\n const r = bounds[i * 4 + 2] + xPos;\n const b = bounds[i * 4 + 3];\n xPos += advances[i];\n // Skip empty glyph bounds (e.g. whitespace), like SkRect::join does.\n if (l >= r || t >= b) {\n continue;\n }\n if (isEmpty) {\n left = l;\n top = t;\n right = r;\n bottom = b;\n isEmpty = false;\n } else {\n left = Math.min(left, l);\n top = Math.min(top, t);\n right = Math.max(right, r);\n bottom = Math.max(bottom, b);\n }\n }\n return new JsiSkRect(\n this.CanvasKit,\n this.CanvasKit.LTRBRect(left, top, right, bottom)\n );\n }\n\n getTextWidth(text: string, paint?: SkPaint | undefined) {\n const ids = this.getGlyphIDs(text);\n const widths = this.getGlyphWidths(ids, paint);\n return widths.reduce((a, b) => a + b, 0);\n }\n\n getMetrics() {\n const result = this.ref.getMetrics();\n return {\n ascent: result.ascent,\n descent: result.descent,\n leading: result.leading,\n bounds: result.bounds\n ? new JsiSkRect(this.CanvasKit, result.bounds)\n : undefined,\n };\n }\n\n getGlyphIDs(str: string, numCodePoints?: number) {\n // TODO: Fix return value in the C++ implementation\n return [...this.ref.getGlyphIDs(str, numCodePoints)];\n }\n\n // TODO: Fix return value in the C++ implementation, it return float32\n getGlyphWidths(glyphs: number[], paint?: SkPaint | null) {\n return [\n ...this.ref.getGlyphWidths(\n glyphs,\n paint ? JsiSkPaint.fromValue(paint) : null\n ),\n ];\n }\n\n getGlyphIntercepts(\n glyphs: number[],\n positions: SkPoint[],\n top: number,\n bottom: number\n ) {\n return [\n ...this.ref.getGlyphIntercepts(\n glyphs,\n positions.map((p) => Array.from(JsiSkPoint.fromValue(p))).flat(),\n top,\n bottom\n ),\n ];\n }\n\n getScaleX() {\n return this.ref.getScaleX();\n }\n\n getSize() {\n return this.ref.getSize();\n }\n\n getSkewX() {\n return this.ref.getSkewX();\n }\n\n isEmbolden() {\n return this.ref.isEmbolden();\n }\n\n getTypeface() {\n const tf = this.ref.getTypeface();\n return tf ? new JsiSkTypeface(this.CanvasKit, tf) : null;\n }\n\n setEdging(edging: FontEdging) {\n this.ref.setEdging(getEnum(this.CanvasKit, \"FontEdging\", edging));\n }\n\n setEmbeddedBitmaps(embeddedBitmaps: boolean) {\n this.ref.setEmbeddedBitmaps(embeddedBitmaps);\n }\n\n setHinting(hinting: FontHinting) {\n this.ref.setHinting(getEnum(this.CanvasKit, \"FontHinting\", hinting));\n }\n\n setLinearMetrics(linearMetrics: boolean) {\n this.ref.setLinearMetrics(linearMetrics);\n }\n\n setScaleX(sx: number) {\n this.ref.setScaleX(sx);\n }\n\n setSize(points: number) {\n this.ref.setSize(points);\n }\n\n setSkewX(sx: number) {\n this.ref.setSkewX(sx);\n }\n\n setEmbolden(embolden: boolean) {\n this.ref.setEmbolden(embolden);\n }\n\n setSubpixel(subpixel: boolean) {\n this.ref.setSubpixel(subpixel);\n }\n\n setTypeface(face: SkTypeface | null) {\n this.ref.setTypeface(face ? JsiSkTypeface.fromValue(face) : null);\n }\n}\n"],"mappings":"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","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":[]}
@@ -2,6 +2,8 @@ import type { Skia, SkCanvas, SkColorFilter, SkPaint, SkShader, SkImageFilter, S
2
2
  export declare const createDrawingContext: (Skia: Skia, paintPool: SkPaint[], canvas: SkCanvas) => {
3
3
  Skia: Skia;
4
4
  canvas: SkCanvas;
5
+ track: <T>(value: T) => T;
6
+ dispose: () => void;
5
7
  paints: SkPaint[];
6
8
  colorFilters: SkColorFilter[];
7
9
  shaders: SkShader[];