@shopify/react-native-skia 2.1.1 → 2.2.1

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 (129) hide show
  1. package/android/CMakeLists.txt +1 -1
  2. package/android/cpp/rnskia-android/OpenGLWindowContext.h +1 -1
  3. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +1 -1
  4. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +1 -1
  5. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +1 -1
  6. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +1 -1
  7. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureViewManager.java +6 -0
  8. package/android/src/paper/java/com/facebook/react/viewmanagers/SkiaPictureViewManagerInterface.java +1 -0
  9. package/apple/MetalContext.h +2 -2
  10. package/apple/MetalWindowContext.h +2 -2
  11. package/apple/MetalWindowContext.mm +7 -4
  12. package/apple/RNSkApplePlatformContext.mm +1 -1
  13. package/apple/RNSkAppleView.h +7 -1
  14. package/apple/RNSkMetalCanvasProvider.h +4 -1
  15. package/apple/RNSkMetalCanvasProvider.mm +9 -4
  16. package/apple/SkiaPictureView.mm +4 -0
  17. package/apple/SkiaUIView.h +1 -0
  18. package/apple/SkiaUIView.mm +9 -0
  19. package/cpp/api/JsiSkImage.h +1 -1
  20. package/cpp/api/JsiSkSurface.h +1 -1
  21. package/cpp/api/JsiSkiaContext.h +1 -1
  22. package/cpp/api/recorder/ImageFilters.h +3 -3
  23. package/cpp/api/recorder/Paint.h +4 -0
  24. package/cpp/rnskia/{DawnContext.h → RNDawnContext.h} +3 -3
  25. package/cpp/rnskia/{DawnWindowContext.cpp → RNDawnWindowContext.cpp} +3 -3
  26. package/cpp/rnskia/{DawnWindowContext.h → RNDawnWindowContext.h} +2 -2
  27. package/cpp/rnskia/RNSkJsiViewApi.h +36 -1
  28. package/cpp/rnskia/RNSkPlatformContext.h +1 -1
  29. package/cpp/rnskia/RNSkView.h +10 -0
  30. package/lib/commonjs/dom/types/Drawings.d.ts +1 -1
  31. package/lib/commonjs/dom/types/Drawings.js.map +1 -1
  32. package/lib/commonjs/renderer/Canvas.d.ts +12 -4
  33. package/lib/commonjs/renderer/Canvas.js +49 -25
  34. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  35. package/lib/commonjs/renderer/components/ImageFilter.js.map +1 -1
  36. package/lib/commonjs/skia/types/Matrix4.d.ts +4 -0
  37. package/lib/commonjs/skia/types/Matrix4.js +18 -1
  38. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  39. package/lib/commonjs/sksg/Container.d.ts +13 -7
  40. package/lib/commonjs/sksg/Container.js +44 -18
  41. package/lib/commonjs/sksg/Container.js.map +1 -1
  42. package/lib/commonjs/sksg/Reconciler.d.ts +3 -2
  43. package/lib/commonjs/sksg/Reconciler.js +2 -2
  44. package/lib/commonjs/sksg/Reconciler.js.map +1 -1
  45. package/lib/commonjs/sksg/Recorder/Player.js +9 -3
  46. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  47. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js +2 -2
  48. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  49. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  50. package/lib/commonjs/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  51. package/lib/commonjs/views/types.d.ts +1 -0
  52. package/lib/commonjs/views/types.js.map +1 -1
  53. package/lib/module/dom/types/Drawings.d.ts +1 -1
  54. package/lib/module/dom/types/Drawings.js.map +1 -1
  55. package/lib/module/renderer/Canvas.d.ts +12 -4
  56. package/lib/module/renderer/Canvas.js +48 -25
  57. package/lib/module/renderer/Canvas.js.map +1 -1
  58. package/lib/module/renderer/components/ImageFilter.js.map +1 -1
  59. package/lib/module/skia/types/Matrix4.d.ts +4 -0
  60. package/lib/module/skia/types/Matrix4.js +16 -0
  61. package/lib/module/skia/types/Matrix4.js.map +1 -1
  62. package/lib/module/sksg/Container.d.ts +13 -7
  63. package/lib/module/sksg/Container.js +44 -18
  64. package/lib/module/sksg/Container.js.map +1 -1
  65. package/lib/module/sksg/Reconciler.d.ts +3 -2
  66. package/lib/module/sksg/Reconciler.js +2 -2
  67. package/lib/module/sksg/Reconciler.js.map +1 -1
  68. package/lib/module/sksg/Recorder/Player.js +9 -3
  69. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  70. package/lib/module/sksg/Recorder/commands/ImageFilters.js +2 -2
  71. package/lib/module/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  72. package/lib/module/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  73. package/lib/module/specs/SkiaPictureViewNativeComponent.js.map +1 -1
  74. package/lib/module/views/types.d.ts +1 -0
  75. package/lib/module/views/types.js.map +1 -1
  76. package/lib/typescript/lib/commonjs/renderer/Canvas.d.ts +8 -2
  77. package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +1 -0
  78. package/lib/typescript/lib/commonjs/sksg/Container.d.ts +11 -3
  79. package/lib/typescript/lib/commonjs/sksg/Reconciler.d.ts +7 -4
  80. package/lib/typescript/lib/module/mock/index.d.ts +1 -0
  81. package/lib/typescript/lib/module/renderer/Canvas.d.ts +11 -2
  82. package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
  83. package/lib/typescript/lib/module/sksg/Container.d.ts +11 -3
  84. package/lib/typescript/lib/module/sksg/Reconciler.d.ts +7 -4
  85. package/lib/typescript/src/dom/types/Drawings.d.ts +1 -1
  86. package/lib/typescript/src/renderer/Canvas.d.ts +12 -4
  87. package/lib/typescript/src/skia/types/Matrix4.d.ts +4 -0
  88. package/lib/typescript/src/sksg/Container.d.ts +13 -7
  89. package/lib/typescript/src/sksg/Reconciler.d.ts +3 -2
  90. package/lib/typescript/src/specs/SkiaPictureViewNativeComponent.d.ts +1 -0
  91. package/lib/typescript/src/views/types.d.ts +1 -0
  92. package/libs/android/arm64-v8a/libskia.a +0 -0
  93. package/libs/android/armeabi-v7a/libskia.a +0 -0
  94. package/libs/android/x86/libskia.a +0 -0
  95. package/libs/android/x86_64/libskia.a +0 -0
  96. package/libs/apple/libpathops.xcframework/Info.plist +15 -15
  97. package/libs/apple/libskia.xcframework/Info.plist +11 -11
  98. package/libs/apple/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  99. package/libs/apple/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  100. package/libs/apple/libskia.xcframework/macos-arm64_x86_64/libskia.a +0 -0
  101. package/libs/apple/libskia.xcframework/tvos-arm64_arm64e/libskia.a +0 -0
  102. package/libs/apple/libskia.xcframework/tvos-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  103. package/libs/apple/libskottie.xcframework/Info.plist +16 -16
  104. package/libs/apple/libskparagraph.xcframework/Info.plist +8 -8
  105. package/libs/apple/libsksg.xcframework/Info.plist +6 -6
  106. package/libs/apple/libskshaper.xcframework/Info.plist +10 -10
  107. package/libs/apple/libskunicode_core.xcframework/Info.plist +10 -10
  108. package/libs/apple/libskunicode_libgrapheme.xcframework/Info.plist +14 -14
  109. package/libs/apple/libsvg.xcframework/Info.plist +15 -15
  110. package/package.json +1 -1
  111. package/react-native-skia.podspec +5 -5
  112. package/src/dom/types/Drawings.ts +1 -1
  113. package/src/renderer/Canvas.tsx +53 -30
  114. package/src/renderer/__tests__/FitBox.spec.tsx +556 -4
  115. package/src/renderer/__tests__/e2e/ImageFilter.spec.tsx +4 -4
  116. package/src/renderer/__tests__/e2e/Paint.spec.tsx +18 -0
  117. package/src/renderer/__tests__/e2e/Skottie.spec.tsx +24 -1
  118. package/src/renderer/__tests__/setup.tsx +2 -0
  119. package/src/renderer/components/ImageFilter.tsx +1 -1
  120. package/src/skia/types/Matrix4.ts +16 -0
  121. package/src/sksg/Container.ts +73 -20
  122. package/src/sksg/Reconciler.ts +5 -3
  123. package/src/sksg/Recorder/Player.ts +7 -7
  124. package/src/sksg/Recorder/commands/ImageFilters.ts +3 -6
  125. package/src/specs/SkiaPictureViewNativeComponent.ts +1 -0
  126. package/src/views/types.ts +1 -0
  127. /package/cpp/rnskia/{DawnUtils.h → RNDawnUtils.h} +0 -0
  128. /package/cpp/rnskia/{ImageProvider.h → RNImageProvider.h} +0 -0
  129. /package/cpp/rnskia/{WindowContext.h → RNWindowContext.h} +0 -0
@@ -174,6 +174,7 @@ export const importSkia = (): typeof SkiaExports => {
174
174
  const skia = require("../../skia");
175
175
  const renderer = require("../../renderer");
176
176
  const offscreen = require("../Offscreen");
177
+ const nodes = require("../../dom/nodes");
177
178
  // TODO: to remove
178
179
  const animation = require("../../animation");
179
180
  return {
@@ -181,6 +182,7 @@ export const importSkia = (): typeof SkiaExports => {
181
182
  ...renderer,
182
183
  ...animation,
183
184
  ...offscreen,
185
+ ...nodes,
184
186
  };
185
187
  };
186
188
 
@@ -5,4 +5,4 @@ import type { SkiaProps } from "../processors";
5
5
 
6
6
  export const ImageFilter = (props: SkiaProps<ImageFilterProps>) => {
7
7
  return <skImageFilter {...props} />;
8
- };
8
+ };
@@ -354,6 +354,22 @@ export const convertToColumnMajor = (rowMajorMatrix: Matrix4) => {
354
354
  return colMajorMatrix as unknown as Matrix4;
355
355
  };
356
356
 
357
+ /**
358
+ * @worklet
359
+ */
360
+ export const convertToColumnMajor3 = (rowMajorMatrix: Matrix3 | number[]) => {
361
+ "worklet";
362
+
363
+ const colMajorMatrix = new Array<number>(9);
364
+ const size = 3;
365
+ for (let row = 0; row < size; row++) {
366
+ for (let col = 0; col < size; col++) {
367
+ colMajorMatrix[col * size + row] = rowMajorMatrix[row * size + col];
368
+ }
369
+ }
370
+ return colMajorMatrix as unknown as Matrix3;
371
+ };
372
+
357
373
  /**
358
374
  * @worklet
359
375
  */
@@ -1,5 +1,7 @@
1
+ import type { SharedValue } from "react-native-reanimated";
2
+
1
3
  import Rea from "../external/reanimated/ReanimatedProxy";
2
- import type { Skia, SkCanvas } from "../skia/types";
4
+ import type { Skia, SkCanvas, SkSize } from "../skia/types";
3
5
  import { HAS_REANIMATED_3 } from "../external/reanimated/renderHelpers";
4
6
  import type { JsiRecorder } from "../skia/types/Recorder";
5
7
 
@@ -13,9 +15,22 @@ import { ReanimatedRecorder } from "./Recorder/ReanimatedRecorder";
13
15
 
14
16
  import "../views/api";
15
17
 
16
- const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
18
+ const drawOnscreen = (
19
+ Skia: Skia,
20
+ nativeId: number,
21
+ recording: Recording,
22
+ onSize?: SharedValue<SkSize>
23
+ ) => {
17
24
  "worklet";
18
-
25
+ if (onSize) {
26
+ const size = SkiaViewApi.size(nativeId);
27
+ if (
28
+ size.width !== onSize.value.width ||
29
+ size.height !== onSize.value.height
30
+ ) {
31
+ onSize.value = size;
32
+ }
33
+ }
19
34
  const rec = Skia.PictureRecorder();
20
35
  const canvas = rec.beginRecording();
21
36
  //const start = performance.now();
@@ -28,11 +43,23 @@ const drawOnscreen = (Skia: Skia, nativeId: number, recording: Recording) => {
28
43
  SkiaViewApi.setJsiProperty(nativeId, "picture", picture);
29
44
  };
30
45
 
31
- const nativeDrawOnscreen = (nativeId: number, recorder: JsiRecorder) => {
46
+ const nativeDrawOnscreen = (
47
+ nativeId: number,
48
+ recorder: JsiRecorder,
49
+ onSize?: SharedValue<SkSize>
50
+ ) => {
32
51
  "worklet";
33
52
 
34
53
  //const start = performance.now();
35
-
54
+ if (onSize) {
55
+ const size = SkiaViewApi.size(nativeId);
56
+ if (
57
+ size.width !== onSize.value.width ||
58
+ size.height !== onSize.value.height
59
+ ) {
60
+ onSize.value = size;
61
+ }
62
+ }
36
63
  const picture = recorder.play();
37
64
  //const end = performance.now();
38
65
  //console.log("Recording time: ", end - start);
@@ -44,7 +71,7 @@ export abstract class Container {
44
71
  protected recording: Recording | null = null;
45
72
  protected unmounted = false;
46
73
 
47
- constructor(protected Skia: Skia, protected nativeId: number) {}
74
+ constructor(protected Skia: Skia) {}
48
75
 
49
76
  get root() {
50
77
  return this._root;
@@ -78,8 +105,12 @@ export abstract class Container {
78
105
  }
79
106
 
80
107
  class StaticContainer extends Container {
81
- constructor(Skia: Skia, nativeId: number) {
82
- super(Skia, nativeId);
108
+ constructor(
109
+ Skia: Skia,
110
+ private nativeId: number,
111
+ private onSize?: SharedValue<SkSize>
112
+ ) {
113
+ super(Skia);
83
114
  }
84
115
 
85
116
  redraw() {
@@ -88,6 +119,15 @@ class StaticContainer extends Container {
88
119
  this.recording = recorder.getRecording();
89
120
  const isOnScreen = this.nativeId !== -1;
90
121
  if (isOnScreen) {
122
+ if (this.onSize) {
123
+ const size = SkiaViewApi.size(this.nativeId);
124
+ if (
125
+ size.width !== this.onSize.value.width ||
126
+ size.height !== this.onSize.value.height
127
+ ) {
128
+ this.onSize.value = size;
129
+ }
130
+ }
91
131
  const rec = this.Skia.PictureRecorder();
92
132
  const canvas = rec.beginRecording();
93
133
  this.drawOnCanvas(canvas);
@@ -100,8 +140,12 @@ class StaticContainer extends Container {
100
140
  class ReanimatedContainer extends Container {
101
141
  private mapperId: number | null = null;
102
142
 
103
- constructor(Skia: Skia, nativeId: number) {
104
- super(Skia, nativeId);
143
+ constructor(
144
+ Skia: Skia,
145
+ private nativeId: number,
146
+ private onSize?: SharedValue<SkSize>
147
+ ) {
148
+ super(Skia);
105
149
  }
106
150
 
107
151
  redraw() {
@@ -128,7 +172,7 @@ class ReanimatedContainer extends Container {
128
172
  }
129
173
  Rea.runOnUI(() => {
130
174
  "worklet";
131
- drawOnscreen(Skia, nativeId, recording!);
175
+ drawOnscreen(Skia, nativeId, recording!, this.onSize);
132
176
  })();
133
177
  }
134
178
  }
@@ -136,8 +180,12 @@ class ReanimatedContainer extends Container {
136
180
  class NativeReanimatedContainer extends Container {
137
181
  private mapperId: number | null = null;
138
182
 
139
- constructor(Skia: Skia, nativeId: number) {
140
- super(Skia, nativeId);
183
+ constructor(
184
+ Skia: Skia,
185
+ private nativeId: number,
186
+ private onSize?: SharedValue<SkSize>
187
+ ) {
188
+ super(Skia);
141
189
  }
142
190
 
143
191
  redraw() {
@@ -152,27 +200,32 @@ class NativeReanimatedContainer extends Container {
152
200
  visit(recorder, this.root);
153
201
  const sharedValues = recorder.getSharedValues();
154
202
  const sharedRecorder = recorder.getRecorder();
155
- Rea.runOnUI(() => {
203
+ Rea.runOnUI((onSize?: SharedValue<SkSize>) => {
156
204
  "worklet";
157
- nativeDrawOnscreen(nativeId, sharedRecorder);
158
- })();
205
+ nativeDrawOnscreen(nativeId, sharedRecorder, onSize);
206
+ })(this.onSize);
159
207
  if (sharedValues.length > 0) {
208
+ const { onSize } = this;
160
209
  this.mapperId = Rea.startMapper(() => {
161
210
  "worklet";
162
211
  sharedRecorder.applyUpdates(sharedValues);
163
- nativeDrawOnscreen(nativeId, sharedRecorder);
212
+ nativeDrawOnscreen(nativeId, sharedRecorder, onSize);
164
213
  }, sharedValues);
165
214
  }
166
215
  }
167
216
  }
168
217
 
169
- export const createContainer = (Skia: Skia, nativeId: number) => {
218
+ export const createContainer = (
219
+ Skia: Skia,
220
+ nativeId: number,
221
+ onSize?: SharedValue<SkSize>
222
+ ) => {
170
223
  const web = global.SkiaViewApi && global.SkiaViewApi.web;
171
224
  if (HAS_REANIMATED_3 && nativeId !== -1) {
172
225
  if (!web) {
173
- return new NativeReanimatedContainer(Skia, nativeId);
226
+ return new NativeReanimatedContainer(Skia, nativeId, onSize);
174
227
  } else {
175
- return new ReanimatedContainer(Skia, nativeId);
228
+ return new ReanimatedContainer(Skia, nativeId, onSize);
176
229
  }
177
230
  } else {
178
231
  return new StaticContainer(Skia, nativeId);
@@ -1,13 +1,15 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { OpaqueRoot } from "react-reconciler";
3
+ import type { SharedValue } from "react-native-reanimated";
3
4
  import ReactReconciler from "react-reconciler";
4
5
 
5
- import type { SkCanvas, Skia } from "../skia/types";
6
+ import type { SkCanvas, Skia, SkSize } from "../skia/types";
6
7
  import { NodeType } from "../dom/types";
7
8
 
8
9
  import { debug, sksgHostConfig } from "./HostConfig";
9
10
  import type { Container } from "./Container";
10
11
  import { createContainer } from "./Container";
12
+
11
13
  import "./Elements";
12
14
 
13
15
  const skiaReconciler = ReactReconciler(sksgHostConfig);
@@ -22,8 +24,8 @@ export class SkiaSGRoot {
22
24
  private root: OpaqueRoot;
23
25
  private container: Container;
24
26
 
25
- constructor(public Skia: Skia, nativeId = -1) {
26
- this.container = createContainer(Skia, nativeId);
27
+ constructor(public Skia: Skia, nativeId = -1, onSize?: SharedValue<SkSize>) {
28
+ this.container = createContainer(Skia, nativeId, onSize);
27
29
  this.root = skiaReconciler.createContainer(
28
30
  this.container,
29
31
  0,
@@ -67,14 +67,14 @@ function play(ctx: DrawingContext, _command: Command) {
67
67
  if (command.props.paint) {
68
68
  ctx.paints.push(command.props.paint);
69
69
  } else {
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ const { standalone } = command as any;
70
72
  ctx.savePaint();
71
- setPaintProperties(
72
- ctx.Skia,
73
- ctx,
74
- command.props,
75
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
- (command as any).standalone
77
- );
73
+ if (standalone) {
74
+ const freshPaint = ctx.Skia.Paint();
75
+ ctx.paint.assign(freshPaint);
76
+ }
77
+ setPaintProperties(ctx.Skia, ctx, command.props, standalone);
78
78
  }
79
79
  } else if (isCommand(command, CommandType.RestorePaint)) {
80
80
  ctx.restorePaint();
@@ -177,13 +177,10 @@ const declareRuntimeShaderImageFilter = (
177
177
  ctx.imageFilters.push(imgf);
178
178
  };
179
179
 
180
- const declareImageFilter = (
181
- ctx: DrawingContext,
182
- props: ImageFilterProps
183
- ) => {
180
+ const declareImageFilter = (ctx: DrawingContext, props: ImageFilterProps) => {
184
181
  "worklet";
185
- const { imageFilter } = props;
186
- ctx.imageFilters.push(imageFilter);
182
+ const { filter } = props;
183
+ ctx.imageFilters.push(filter);
187
184
  };
188
185
 
189
186
  export const composeImageFilters = (ctx: DrawingContext) => {
@@ -4,6 +4,7 @@ import type { ViewProps } from "react-native";
4
4
  export interface NativeProps extends ViewProps {
5
5
  debug?: boolean;
6
6
  opaque?: boolean;
7
+ colorSpace?: string;
7
8
  }
8
9
 
9
10
  // eslint-disable-next-line import/no-default-export
@@ -15,6 +15,7 @@ export interface ISkiaViewApi {
15
15
  requestRedraw: (nativeId: number) => void;
16
16
  makeImageSnapshot: (nativeId: number, rect?: SkRect) => SkImage;
17
17
  makeImageSnapshotAsync: (nativeId: number, rect?: SkRect) => Promise<SkImage>;
18
+ size: (nativeId: number) => SkSize;
18
19
  }
19
20
 
20
21
  export interface SkiaBaseViewProps extends ViewProps {
File without changes