@shopify/react-native-skia 1.10.1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -13
  2. package/android/src/main/java/com/shopify/reactnative/skia/SkiaTextureView.java +1 -24
  3. package/cpp/api/JsiSkApi.h +3 -0
  4. package/cpp/api/recorder/ColorFilters.h +133 -0
  5. package/cpp/api/recorder/Command.h +58 -0
  6. package/cpp/api/recorder/Convertor.h +1212 -0
  7. package/cpp/api/recorder/DataTypes.h +234 -0
  8. package/cpp/api/recorder/DrawingCtx.h +187 -0
  9. package/cpp/api/recorder/Drawings.h +949 -0
  10. package/cpp/api/recorder/Image.h +108 -0
  11. package/cpp/api/recorder/ImageFilters.h +292 -0
  12. package/cpp/api/recorder/JsiRecorder.h +314 -0
  13. package/cpp/api/recorder/Paint.h +191 -0
  14. package/cpp/api/recorder/PathEffects.h +194 -0
  15. package/cpp/api/recorder/RNRecorder.h +635 -0
  16. package/cpp/api/recorder/Shaders.h +406 -0
  17. package/cpp/rnskia/dom/nodes/JsiAtlasNode.h +3 -2
  18. package/cpp/rnskia/dom/nodes/JsiImageNode.h +3 -2
  19. package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +4 -8
  20. package/jestSetup.js +8 -0
  21. package/jestSetup.mjs +8 -0
  22. package/lib/commonjs/renderer/components/image/Image.d.ts +1 -1
  23. package/lib/commonjs/renderer/components/image/Image.js +8 -2
  24. package/lib/commonjs/renderer/components/image/Image.js.map +1 -1
  25. package/lib/commonjs/skia/types/Recorder.d.ts +52 -0
  26. package/lib/commonjs/skia/types/Recorder.js +6 -0
  27. package/lib/commonjs/skia/types/Recorder.js.map +1 -0
  28. package/lib/commonjs/skia/types/Skia.d.ts +2 -0
  29. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  30. package/lib/commonjs/skia/types/index.d.ts +1 -0
  31. package/lib/commonjs/skia/types/index.js +11 -0
  32. package/lib/commonjs/skia/types/index.js.map +1 -1
  33. package/lib/commonjs/skia/web/JsiSkia.js +3 -0
  34. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  35. package/lib/commonjs/sksg/Container.d.ts +6 -1
  36. package/lib/commonjs/sksg/Container.js +59 -2
  37. package/lib/commonjs/sksg/Container.js.map +1 -1
  38. package/lib/commonjs/sksg/Recorder/DrawingContext.js +1 -0
  39. package/lib/commonjs/sksg/Recorder/DrawingContext.js.map +1 -1
  40. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +53 -0
  41. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js +189 -0
  42. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js.map +1 -0
  43. package/lib/commonjs/sksg/Recorder/Recorder.d.ts +2 -2
  44. package/lib/commonjs/sksg/Recorder/Recorder.js.map +1 -1
  45. package/lib/commonjs/sksg/Recorder/Visitor.d.ts +2 -2
  46. package/lib/commonjs/sksg/Recorder/Visitor.js +2 -2
  47. package/lib/commonjs/sksg/Recorder/Visitor.js.map +1 -1
  48. package/lib/module/renderer/components/image/Image.d.ts +1 -1
  49. package/lib/module/renderer/components/image/Image.js +8 -2
  50. package/lib/module/renderer/components/image/Image.js.map +1 -1
  51. package/lib/module/skia/types/Recorder.d.ts +52 -0
  52. package/lib/module/skia/types/Recorder.js +2 -0
  53. package/lib/module/skia/types/Recorder.js.map +1 -0
  54. package/lib/module/skia/types/Skia.d.ts +2 -0
  55. package/lib/module/skia/types/Skia.js.map +1 -1
  56. package/lib/module/skia/types/index.d.ts +1 -0
  57. package/lib/module/skia/types/index.js +1 -0
  58. package/lib/module/skia/types/index.js.map +1 -1
  59. package/lib/module/skia/web/JsiSkia.js +3 -0
  60. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  61. package/lib/module/sksg/Container.d.ts +6 -1
  62. package/lib/module/sksg/Container.js +59 -2
  63. package/lib/module/sksg/Container.js.map +1 -1
  64. package/lib/module/sksg/Recorder/DrawingContext.js +1 -0
  65. package/lib/module/sksg/Recorder/DrawingContext.js.map +1 -1
  66. package/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +53 -0
  67. package/lib/module/sksg/Recorder/ReanimatedRecorder.js +182 -0
  68. package/lib/module/sksg/Recorder/ReanimatedRecorder.js.map +1 -0
  69. package/lib/module/sksg/Recorder/Recorder.d.ts +2 -2
  70. package/lib/module/sksg/Recorder/Recorder.js.map +1 -1
  71. package/lib/module/sksg/Recorder/Visitor.d.ts +2 -2
  72. package/lib/module/sksg/Recorder/Visitor.js +2 -2
  73. package/lib/module/sksg/Recorder/Visitor.js.map +1 -1
  74. package/lib/typescript/lib/commonjs/renderer/components/image/Image.d.ts +4 -1
  75. package/lib/typescript/lib/commonjs/skia/types/Recorder.d.ts +1 -0
  76. package/lib/typescript/lib/commonjs/skia/web/JsiSkia.d.ts +1 -0
  77. package/lib/typescript/lib/commonjs/sksg/Container.d.ts +5 -1
  78. package/lib/typescript/lib/commonjs/sksg/Reconciler.d.ts +6 -0
  79. package/lib/typescript/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +47 -0
  80. package/lib/typescript/lib/module/mock/index.d.ts +4 -1
  81. package/lib/typescript/lib/module/renderer/components/image/Image.d.ts +4 -1
  82. package/lib/typescript/lib/module/skia/Skia.web.d.ts +1 -0
  83. package/lib/typescript/lib/module/skia/types/Recorder.d.ts +1 -0
  84. package/lib/typescript/lib/module/skia/types/index.d.ts +1 -0
  85. package/lib/typescript/lib/module/skia/web/JsiSkia.d.ts +1 -0
  86. package/lib/typescript/lib/module/sksg/Container.d.ts +5 -1
  87. package/lib/typescript/lib/module/sksg/Reconciler.d.ts +6 -0
  88. package/lib/typescript/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +46 -0
  89. package/lib/typescript/src/renderer/components/image/Image.d.ts +1 -1
  90. package/lib/typescript/src/skia/types/Recorder.d.ts +52 -0
  91. package/lib/typescript/src/skia/types/Skia.d.ts +2 -0
  92. package/lib/typescript/src/skia/types/index.d.ts +1 -0
  93. package/lib/typescript/src/sksg/Container.d.ts +6 -1
  94. package/lib/typescript/src/sksg/Recorder/ReanimatedRecorder.d.ts +53 -0
  95. package/lib/typescript/src/sksg/Recorder/Recorder.d.ts +2 -2
  96. package/lib/typescript/src/sksg/Recorder/Visitor.d.ts +2 -2
  97. package/package.json +3 -2
  98. package/src/renderer/components/image/Image.tsx +2 -2
  99. package/src/skia/types/Recorder.ts +91 -0
  100. package/src/skia/types/Skia.ts +2 -0
  101. package/src/skia/types/index.ts +1 -0
  102. package/src/skia/web/JsiSkia.ts +3 -0
  103. package/src/sksg/Container.ts +63 -4
  104. package/src/sksg/Recorder/DrawingContext.ts +1 -0
  105. package/src/sksg/Recorder/ReanimatedRecorder.ts +271 -0
  106. package/src/sksg/Recorder/Recorder.ts +2 -2
  107. package/src/sksg/Recorder/Visitor.ts +17 -12
@@ -0,0 +1,635 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <optional>
5
+ #include <string>
6
+ #include <vector>
7
+
8
+ #include <jsi/jsi.h>
9
+
10
+ #include "ColorFilters.h"
11
+ #include "Command.h"
12
+ #include "Convertor.h"
13
+ #include "DrawingCtx.h"
14
+ #include "Drawings.h"
15
+ #include "ImageFilters.h"
16
+ #include "Paint.h"
17
+ #include "PathEffects.h"
18
+ #include "Shaders.h"
19
+
20
+ namespace RNSkia {
21
+
22
+ class Recorder {
23
+ private:
24
+ std::vector<std::unique_ptr<Command>> commands;
25
+
26
+ public:
27
+ Variables variables;
28
+
29
+ ~Recorder() = default;
30
+
31
+ void savePaint(jsi::Runtime &runtime, const jsi::Object &props) {
32
+ commands.push_back(
33
+ std::make_unique<SavePaintCmd>(runtime, props, variables));
34
+ }
35
+
36
+ void pushShader(jsi::Runtime &runtime, const std::string &nodeType,
37
+ const jsi::Object &props) {
38
+ if (nodeType == "skShader") {
39
+ commands.push_back(
40
+ std::make_unique<PushShaderCmd>(runtime, props, variables));
41
+ } else if (nodeType == "skImageShader") {
42
+ commands.push_back(
43
+ std::make_unique<PushImageShaderCmd>(runtime, props, variables));
44
+ } else if (nodeType == "skColorShader") {
45
+ commands.push_back(
46
+ std::make_unique<ColorShaderCmd>(runtime, props, variables));
47
+ } else if (nodeType == "skTurbulence") {
48
+ commands.push_back(
49
+ std::make_unique<TurbulenceCmd>(runtime, props, variables));
50
+ } else if (nodeType == "skFractalNoise") {
51
+ commands.push_back(
52
+ std::make_unique<FractalNoiseCmd>(runtime, props, variables));
53
+ } else if (nodeType == "skLinearGradient") {
54
+ commands.push_back(
55
+ std::make_unique<LinearGradientCmd>(runtime, props, variables));
56
+ } else if (nodeType == "skRadialGradient") {
57
+ commands.push_back(
58
+ std::make_unique<RadialGradientCmd>(runtime, props, variables));
59
+ } else if (nodeType == "skSweepGradient") {
60
+ commands.push_back(
61
+ std::make_unique<SweepGradientCmd>(runtime, props, variables));
62
+ } else if (nodeType == "skTwoPointConicalGradient") {
63
+ commands.push_back(std::make_unique<TwoPointConicalGradientCmd>(
64
+ runtime, props, variables));
65
+ // TODO: should receive skBlendShader here
66
+ } else if (nodeType == "skBlend") {
67
+ commands.push_back(std::make_unique<BlendShaderCmd>(runtime, props, variables));
68
+ }
69
+ }
70
+
71
+ void pushPathEffect(jsi::Runtime &runtime, const std::string &nodeType,
72
+ const jsi::Object &props) {
73
+ if (nodeType == "skDiscretePathEffect") {
74
+ commands.push_back(
75
+ std::make_unique<DiscretePathEffectCmd>(runtime, props, variables));
76
+ } else if (nodeType == "skDashPathEffect") {
77
+ commands.push_back(
78
+ std::make_unique<DashPathEffectCmd>(runtime, props, variables));
79
+ } else if (nodeType == "skPath1DPathEffect") {
80
+ commands.push_back(
81
+ std::make_unique<Path1DPathEffectCmd>(runtime, props, variables));
82
+ } else if (nodeType == "skPath2DPathEffect") {
83
+ commands.push_back(
84
+ std::make_unique<Path2DPathEffectCmd>(runtime, props, variables));
85
+ } else if (nodeType == "skCornerPathEffect") {
86
+ commands.push_back(
87
+ std::make_unique<CornerPathEffectCmd>(runtime, props, variables));
88
+ } else if (nodeType == "skSumPathEffect") {
89
+ commands.push_back(
90
+ std::make_unique<SumPathEffectCmd>(runtime, props, variables));
91
+ } else if (nodeType == "skLine2DPathEffect") {
92
+ commands.push_back(
93
+ std::make_unique<Line2DPathEffectCmd>(runtime, props, variables));
94
+ }
95
+ }
96
+
97
+ void pushColorFilter(jsi::Runtime &runtime, const std::string &nodeType,
98
+ const jsi::Object &props) {
99
+ if (nodeType == "skMatrixColorFilter") {
100
+ commands.push_back(
101
+ std::make_unique<MatrixColorFilterCmd>(runtime, props, variables));
102
+ } else if (nodeType == "skBlendColorFilter") {
103
+ commands.push_back(
104
+ std::make_unique<BlendColorFilterCmd>(runtime, props, variables));
105
+ } else if (nodeType == "skLinearToSRGBGammaColorFilter") {
106
+ commands.push_back(std::make_unique<LinearToSRGBGammaColorFilterCmd>(
107
+ runtime, props, variables));
108
+ } else if (nodeType == "skSRGBToLinearGammaColorFilter") {
109
+ commands.push_back(std::make_unique<SRGBToLinearGammaColorFilterCmd>(
110
+ runtime, props, variables));
111
+ } else if (nodeType == "skLumaColorFilter") {
112
+ commands.push_back(
113
+ std::make_unique<LumaColorFilterCmd>(runtime, props, variables));
114
+ } else if (nodeType == "skLerpColorFilter") {
115
+ commands.push_back(
116
+ std::make_unique<LerpColorFilterCmd>(runtime, props, variables));
117
+ }
118
+ }
119
+
120
+ void pushImageFilter(jsi::Runtime &runtime, const std::string &nodeType,
121
+ const jsi::Object &props) {
122
+ if (nodeType == "skOffsetImageFilter") {
123
+ commands.push_back(
124
+ std::make_unique<OffsetImageFilterCmd>(runtime, props, variables));
125
+ } else if (nodeType == "skDisplacementMapImageFilter") {
126
+ commands.push_back(std::make_unique<DisplacementMapImageFilterCmd>(
127
+ runtime, props, variables));
128
+ } else if (nodeType == "skBlurImageFilter") {
129
+ commands.push_back(
130
+ std::make_unique<BlurImageFilterCmd>(runtime, props, variables));
131
+ } else if (nodeType == "skDropShadowImageFilter") {
132
+ commands.push_back(std::make_unique<DropShadowImageFilterCmd>(
133
+ runtime, props, variables));
134
+ } else if (nodeType == "skMorphologyImageFilter") {
135
+ commands.push_back(std::make_unique<MorphologyImageFilterCmd>(
136
+ runtime, props, variables));
137
+ } else if (nodeType == "skBlendImageFilter") {
138
+ commands.push_back(
139
+ std::make_unique<BlendImageFilterCmd>(runtime, props, variables));
140
+ } else if (nodeType == "skRuntimeShaderImageFilter") {
141
+ commands.push_back(std::make_unique<RuntimeShaderImageFilterCmd>(
142
+ runtime, props, variables));
143
+ }
144
+ }
145
+
146
+ void composePathEffect() {
147
+ commands.push_back(
148
+ std::make_unique<Command>(CommandType::ComposePathEffect));
149
+ }
150
+
151
+ void composeImageFilter() {
152
+ commands.push_back(
153
+ std::make_unique<Command>(CommandType::ComposeImageFilter));
154
+ }
155
+
156
+ void composeColorFilter() {
157
+ commands.push_back(
158
+ std::make_unique<Command>(CommandType::ComposeColorFilter));
159
+ }
160
+
161
+ void pushBlurMaskFilter(jsi::Runtime &runtime, const jsi::Object &props) {
162
+ commands.push_back(
163
+ std::make_unique<BlurMaskFilterCmd>(runtime, props, variables));
164
+ }
165
+
166
+ void saveCTM(jsi::Runtime &runtime, const jsi::Object &props) {
167
+ commands.push_back(std::make_unique<SaveCTMCmd>(runtime, props, variables));
168
+ }
169
+
170
+ void restoreCTM() {
171
+ commands.push_back(std::make_unique<Command>(CommandType::RestoreCTM));
172
+ }
173
+
174
+ void restorePaint() {
175
+ commands.push_back(std::make_unique<Command>(CommandType::RestorePaint));
176
+ }
177
+
178
+ void drawRect(jsi::Runtime &runtime, const jsi::Object &props) {
179
+ commands.push_back(std::make_unique<RectCmd>(runtime, props, variables));
180
+ }
181
+
182
+ void drawCircle(jsi::Runtime &runtime, const jsi::Object &props) {
183
+ commands.push_back(std::make_unique<CircleCmd>(runtime, props, variables));
184
+ }
185
+
186
+ void drawLine(jsi::Runtime &runtime, const jsi::Object &props) {
187
+ commands.push_back(std::make_unique<LineCmd>(runtime, props, variables));
188
+ }
189
+
190
+ void drawTextPath(jsi::Runtime &runtime, const jsi::Object &props) {
191
+ commands.push_back(
192
+ std::make_unique<TextPathCmd>(runtime, props, variables));
193
+ }
194
+
195
+ void drawText(jsi::Runtime &runtime, const jsi::Object &props) {
196
+ commands.push_back(std::make_unique<TextCmd>(runtime, props, variables));
197
+ }
198
+
199
+ void drawPath(jsi::Runtime &runtime, const jsi::Object &props) {
200
+ commands.push_back(std::make_unique<PathCmd>(runtime, props, variables));
201
+ }
202
+
203
+ void drawPaint() {
204
+ commands.push_back(std::make_unique<Command>(CommandType::DrawPaint));
205
+ }
206
+
207
+ void drawBox(jsi::Runtime &runtime, const jsi::Object &props, const jsi::Array &shadows) {
208
+ commands.push_back(std::make_unique<BoxCmd>(runtime, props, shadows, variables));
209
+ }
210
+
211
+ void drawImage(jsi::Runtime &runtime, const jsi::Object &props) {
212
+ commands.push_back(std::make_unique<ImageCmd>(runtime, props, variables));
213
+ }
214
+
215
+ void drawPoints(jsi::Runtime &runtime, const jsi::Object &props) {
216
+ commands.push_back(std::make_unique<PointsCmd>(runtime, props, variables));
217
+ }
218
+
219
+ void drawRRect(jsi::Runtime &runtime, const jsi::Object &props) {
220
+ commands.push_back(std::make_unique<RRectCmd>(runtime, props, variables));
221
+ }
222
+
223
+ void drawOval(jsi::Runtime &runtime, const jsi::Object &props) {
224
+ commands.push_back(std::make_unique<OvalCmd>(runtime, props, variables));
225
+ }
226
+
227
+ void drawPatch(jsi::Runtime &runtime, const jsi::Object &props) {
228
+ commands.push_back(std::make_unique<PatchCmd>(runtime, props, variables));
229
+ }
230
+
231
+ void drawVertices(jsi::Runtime &runtime, const jsi::Object &props) {
232
+ commands.push_back(
233
+ std::make_unique<VerticesCmd>(runtime, props, variables));
234
+ }
235
+
236
+ void drawDiffRect(jsi::Runtime &runtime, const jsi::Object &props) {
237
+ commands.push_back(
238
+ std::make_unique<DiffRectCmd>(runtime, props, variables));
239
+ }
240
+
241
+ void drawTextBlob(jsi::Runtime &runtime, const jsi::Object &props) {
242
+ commands.push_back(
243
+ std::make_unique<TextBlobCmd>(runtime, props, variables));
244
+ }
245
+
246
+ void drawGlyphs(jsi::Runtime &runtime, const jsi::Object &props) {
247
+ commands.push_back(std::make_unique<GlyphsCmd>(runtime, props, variables));
248
+ }
249
+
250
+ void drawPicture(jsi::Runtime &runtime, const jsi::Object &props) {
251
+ commands.push_back(std::make_unique<PictureCmd>(runtime, props, variables));
252
+ }
253
+
254
+ void drawImageSVG(jsi::Runtime &runtime, const jsi::Object &props) {
255
+ commands.push_back(
256
+ std::make_unique<ImageSVGCmd>(runtime, props, variables));
257
+ }
258
+
259
+ void drawParagraph(jsi::Runtime &runtime, const jsi::Object &props) {
260
+ commands.push_back(
261
+ std::make_unique<ParagraphCmd>(runtime, props, variables));
262
+ }
263
+
264
+ void drawAtlas(jsi::Runtime &runtime, const jsi::Object &props) {
265
+ commands.push_back(std::make_unique<AtlasCmd>(runtime, props, variables));
266
+ }
267
+
268
+ void materializePaint() {
269
+ commands.push_back(
270
+ std::make_unique<Command>(CommandType::MaterializePaint));
271
+ }
272
+
273
+ void restorePaintDeclaration() {
274
+ commands.push_back(
275
+ std::make_unique<Command>(CommandType::RestorePaintDeclaration));
276
+ }
277
+
278
+ void saveLayer() {
279
+ commands.push_back(std::make_unique<Command>(CommandType::SaveLayer));
280
+ }
281
+
282
+ void saveBackdropFilter() {
283
+ commands.push_back(
284
+ std::make_unique<Command>(CommandType::SaveBackdropFilter));
285
+ }
286
+
287
+ void saveGroup() {}
288
+
289
+ void restoreGroup() {}
290
+
291
+ void play(DrawingCtx *ctx) {
292
+ for (const auto &cmd : commands) {
293
+ switch (cmd->type) {
294
+
295
+ case Group: {
296
+ // Do nothing here for now
297
+ break;
298
+ }
299
+
300
+ case CommandType::ComposeColorFilter: {
301
+ ctx->composeColorFilter();
302
+ break;
303
+ }
304
+
305
+ case CommandType::ComposeImageFilter: {
306
+ ctx->composeImageFilter();
307
+ break;
308
+ }
309
+
310
+ case CommandType::ComposePathEffect: {
311
+ ctx->composePathEffect();
312
+ break;
313
+ }
314
+
315
+ case CommandType::RestorePaintDeclaration: {
316
+ ctx->materializePaint();
317
+ auto paint = ctx->restorePaint();
318
+ ctx->paintDeclarations.push_back(paint);
319
+ break;
320
+ }
321
+
322
+ case CommandType::SaveBackdropFilter: {
323
+ ctx->saveBackdropFilter();
324
+ break;
325
+ }
326
+
327
+ case CommandType::SaveLayer: {
328
+ ctx->materializePaint();
329
+ auto paint = ctx->paintDeclarations.back();
330
+ ctx->paintDeclarations.pop_back();
331
+ ctx->canvas->saveLayer(
332
+ SkCanvas::SaveLayerRec(nullptr, &paint, nullptr, 0));
333
+ break;
334
+ }
335
+
336
+ case CommandType::MaterializePaint: {
337
+ ctx->materializePaint();
338
+ break;
339
+ }
340
+
341
+ case CommandType::SavePaint: {
342
+ auto *savePaintCmd = static_cast<SavePaintCmd *>(cmd.get());
343
+ savePaintCmd->savePaint(ctx);
344
+ break;
345
+ }
346
+
347
+ case CommandType::PushShader: {
348
+ auto nodeType = cmd->nodeType;
349
+ if (nodeType == "skShader") {
350
+ auto *pushShaderCmd = static_cast<PushShaderCmd *>(cmd.get());
351
+ pushShaderCmd->pushShader(ctx);
352
+ } else if (nodeType == "skImageShader") {
353
+ auto *pushImageShaderCmd =
354
+ static_cast<PushImageShaderCmd *>(cmd.get());
355
+ pushImageShaderCmd->pushShader(ctx);
356
+ } else if (nodeType == "skColorShader") {
357
+ auto *colorShaderCmd = static_cast<ColorShaderCmd *>(cmd.get());
358
+ colorShaderCmd->pushShader(ctx);
359
+ } else if (nodeType == "skTurbulence") {
360
+ auto *turbulenceCmd = static_cast<TurbulenceCmd *>(cmd.get());
361
+ turbulenceCmd->pushShader(ctx);
362
+ } else if (nodeType == "skFractalNoise") {
363
+ auto *fractalNoiseCmd = static_cast<FractalNoiseCmd *>(cmd.get());
364
+ fractalNoiseCmd->pushShader(ctx);
365
+ } else if (nodeType == "skLinearGradient") {
366
+ auto *linearGradientCmd = static_cast<LinearGradientCmd *>(cmd.get());
367
+ linearGradientCmd->pushShader(ctx);
368
+ } else if (nodeType == "skRadialGradient") {
369
+ auto *radialGradientCmd = static_cast<RadialGradientCmd *>(cmd.get());
370
+ radialGradientCmd->pushShader(ctx);
371
+ } else if (nodeType == "skSweepGradient") {
372
+ auto *sweepGradientCmd = static_cast<SweepGradientCmd *>(cmd.get());
373
+ sweepGradientCmd->pushShader(ctx);
374
+ } else if (nodeType == "skTwoPointConicalGradient") {
375
+ auto *twoPointConicalGradientCmd =
376
+ static_cast<TwoPointConicalGradientCmd *>(cmd.get());
377
+ twoPointConicalGradientCmd->pushShader(ctx);
378
+ } else if (nodeType == "skBlendShader") {
379
+ auto *blendShaderCmd =
380
+ static_cast<BlendShaderCmd *>(cmd.get());
381
+ blendShaderCmd->pushShader(ctx);
382
+ } else {
383
+ throw std::runtime_error("Invalid shader type: " + nodeType);
384
+ }
385
+ break;
386
+ }
387
+
388
+ case CommandType::PushImageFilter: {
389
+ auto nodeType = cmd->nodeType;
390
+ if (nodeType == "skOffsetImageFilter") {
391
+ auto *offsetCmd = static_cast<OffsetImageFilterCmd *>(cmd.get());
392
+ offsetCmd->pushImageFilter(ctx);
393
+ } else if (nodeType == "skDisplacementMapImageFilter") {
394
+ auto *displacementCmd =
395
+ static_cast<DisplacementMapImageFilterCmd *>(cmd.get());
396
+ displacementCmd->pushImageFilter(ctx);
397
+ } else if (nodeType == "skBlurImageFilter") {
398
+ auto *blurCmd = static_cast<BlurImageFilterCmd *>(cmd.get());
399
+ blurCmd->pushImageFilter(ctx);
400
+ } else if (nodeType == "skDropShadowImageFilter") {
401
+ auto *dropShadowCmd =
402
+ static_cast<DropShadowImageFilterCmd *>(cmd.get());
403
+ dropShadowCmd->pushImageFilter(ctx);
404
+ } else if (nodeType == "skMorphologyImageFilter") {
405
+ auto *morphologyCmd =
406
+ static_cast<MorphologyImageFilterCmd *>(cmd.get());
407
+ morphologyCmd->pushImageFilter(ctx);
408
+ } else if (nodeType == "skBlendImageFilter") {
409
+ auto *blendCmd = static_cast<BlendImageFilterCmd *>(cmd.get());
410
+ blendCmd->pushImageFilter(ctx);
411
+ } else if (nodeType == "skRuntimeShaderImageFilter") {
412
+ auto *runtimeShaderCmd =
413
+ static_cast<RuntimeShaderImageFilterCmd *>(cmd.get());
414
+ runtimeShaderCmd->pushImageFilter(ctx);
415
+ } else {
416
+ throw std::runtime_error("Invalid image filter type: " + nodeType);
417
+ }
418
+ break;
419
+ }
420
+
421
+ case CommandType::PushPathEffect: {
422
+ auto nodeType = cmd->nodeType;
423
+ if (nodeType == "skDiscretePathEffect") {
424
+ auto *discreteCmd = static_cast<DiscretePathEffectCmd *>(cmd.get());
425
+ discreteCmd->pushPathEffect(ctx);
426
+ } else if (nodeType == "skDashPathEffect") {
427
+ auto *dashCmd = static_cast<DashPathEffectCmd *>(cmd.get());
428
+ dashCmd->pushPathEffect(ctx);
429
+ } else if (nodeType == "skPath1DPathEffect") {
430
+ auto *path1DCmd = static_cast<Path1DPathEffectCmd *>(cmd.get());
431
+ path1DCmd->pushPathEffect(ctx);
432
+ } else if (nodeType == "skPath2DPathEffect") {
433
+ auto *path2DCmd = static_cast<Path2DPathEffectCmd *>(cmd.get());
434
+ path2DCmd->pushPathEffect(ctx);
435
+ } else if (nodeType == "skCornerPathEffect") {
436
+ auto *cornerCmd = static_cast<CornerPathEffectCmd *>(cmd.get());
437
+ cornerCmd->pushPathEffect(ctx);
438
+ } else if (nodeType == "skSumPathEffect") {
439
+ auto *sumCmd = static_cast<SumPathEffectCmd *>(cmd.get());
440
+ sumCmd->pushPathEffect(ctx);
441
+ } else if (nodeType == "skLine2DPathEffect") {
442
+ auto *line2DCmd = static_cast<Line2DPathEffectCmd *>(cmd.get());
443
+ line2DCmd->pushPathEffect(ctx);
444
+ } else {
445
+ throw std::runtime_error("Invalid path effect type: " + nodeType);
446
+ }
447
+ break;
448
+ }
449
+
450
+ case CommandType::PushColorFilter: {
451
+ auto nodeType = cmd->nodeType;
452
+ if (nodeType == "skMatrixColorFilter") {
453
+ auto *matrixCmd = static_cast<MatrixColorFilterCmd *>(cmd.get());
454
+ matrixCmd->pushColorFilter(ctx);
455
+ } else if (nodeType == "skBlendColorFilter") {
456
+ auto *blendCmd = static_cast<BlendColorFilterCmd *>(cmd.get());
457
+ blendCmd->pushColorFilter(ctx);
458
+ } else if (nodeType == "skLinearToSRGBGammaColorFilter") {
459
+ auto *linearToSRGBCmd =
460
+ static_cast<LinearToSRGBGammaColorFilterCmd *>(cmd.get());
461
+ linearToSRGBCmd->pushColorFilter(ctx);
462
+ } else if (nodeType == "skSRGBToLinearGammaColorFilter") {
463
+ auto *srgbToLinearCmd =
464
+ static_cast<SRGBToLinearGammaColorFilterCmd *>(cmd.get());
465
+ srgbToLinearCmd->pushColorFilter(ctx);
466
+ } else if (nodeType == "skLumaColorFilter") {
467
+ auto *lumaCmd = static_cast<LumaColorFilterCmd *>(cmd.get());
468
+ lumaCmd->pushColorFilter(ctx);
469
+ } else if (nodeType == "skLerpColorFilter") {
470
+ auto *lerpCmd = static_cast<LerpColorFilterCmd *>(cmd.get());
471
+ lerpCmd->pushColorFilter(ctx);
472
+ } else {
473
+ throw std::runtime_error("Invalid color filter type: " + nodeType);
474
+ }
475
+ break;
476
+ }
477
+
478
+ case CommandType::PushBlurMaskFilter: {
479
+ auto *blurMaskFilterCmd = static_cast<BlurMaskFilterCmd *>(cmd.get());
480
+ blurMaskFilterCmd->pushMaskFilter(ctx);
481
+ break;
482
+ }
483
+
484
+ case CommandType::DrawPaint: {
485
+ ctx->canvas->drawPaint(ctx->getPaint());
486
+ break;
487
+ }
488
+
489
+ case CommandType::DrawText: {
490
+ auto *textCmd = static_cast<TextCmd *>(cmd.get());
491
+ textCmd->draw(ctx);
492
+ break;
493
+ }
494
+
495
+ case CommandType::RestorePaint: {
496
+ ctx->restorePaint();
497
+ break;
498
+ }
499
+
500
+ case CommandType::SaveCTM: {
501
+ auto *saveCTMCmd = static_cast<SaveCTMCmd *>(cmd.get());
502
+ saveCTMCmd->saveCTM(ctx);
503
+ break;
504
+ }
505
+
506
+ case CommandType::RestoreCTM: {
507
+ ctx->canvas->restore();
508
+ break;
509
+ }
510
+ default: {
511
+ // Handle all drawing commands
512
+ auto currentPaints = ctx->paintDeclarations;
513
+ currentPaints.push_back(ctx->getPaint()); // Add current paint
514
+ ctx->paintDeclarations.clear();
515
+
516
+ for (auto &paint : currentPaints) {
517
+ ctx->pushPaint(paint);
518
+
519
+ switch (cmd->type) {
520
+ case CommandType::DrawPaint: {
521
+ ctx->canvas->drawPaint(paint);
522
+ break;
523
+ }
524
+ case CommandType::DrawCircle: {
525
+ auto *circleCmd = static_cast<CircleCmd *>(cmd.get());
526
+ circleCmd->draw(ctx);
527
+ break;
528
+ }
529
+ case CommandType::DrawPath: {
530
+ auto *pathCmd = static_cast<PathCmd *>(cmd.get());
531
+ pathCmd->draw(ctx);
532
+ break;
533
+ }
534
+ case CommandType::DrawRect: {
535
+ auto *rectCmd = static_cast<RectCmd *>(cmd.get());
536
+ rectCmd->draw(ctx);
537
+ break;
538
+ }
539
+ case CommandType::DrawLine: {
540
+ auto *lineCmd = static_cast<LineCmd *>(cmd.get());
541
+ lineCmd->draw(ctx);
542
+ break;
543
+ }
544
+ case CommandType::DrawTextPath: {
545
+ auto *textPathCmd = static_cast<TextPathCmd *>(cmd.get());
546
+ textPathCmd->draw(ctx);
547
+ break;
548
+ }
549
+ case CommandType::DrawText: {
550
+ auto *textCmd = static_cast<TextCmd *>(cmd.get());
551
+ textCmd->draw(ctx);
552
+ break;
553
+ }
554
+ case CommandType::DrawBox: {
555
+ auto *boxCmd = static_cast<BoxCmd *>(cmd.get());
556
+ boxCmd->draw(ctx);
557
+ break;
558
+ }
559
+ case CommandType::DrawImage: {
560
+ auto *imageCmd = static_cast<ImageCmd *>(cmd.get());
561
+ imageCmd->draw(ctx);
562
+ break;
563
+ }
564
+ case CommandType::DrawPoints: {
565
+ auto *pointsCmd = static_cast<PointsCmd *>(cmd.get());
566
+ pointsCmd->draw(ctx);
567
+ break;
568
+ }
569
+ case CommandType::DrawRRect: {
570
+ auto *rRectCmd = static_cast<RRectCmd *>(cmd.get());
571
+ rRectCmd->draw(ctx);
572
+ break;
573
+ }
574
+ case CommandType::DrawOval: {
575
+ auto *ovalCmd = static_cast<OvalCmd *>(cmd.get());
576
+ ovalCmd->draw(ctx);
577
+ break;
578
+ }
579
+ case CommandType::DrawPatch: {
580
+ auto *patchCmd = static_cast<PatchCmd *>(cmd.get());
581
+ patchCmd->draw(ctx);
582
+ break;
583
+ }
584
+ case CommandType::DrawVertices: {
585
+ auto *verticesCmd = static_cast<VerticesCmd *>(cmd.get());
586
+ verticesCmd->draw(ctx);
587
+ break;
588
+ }
589
+ case CommandType::DrawDiffRect: {
590
+ auto *diffRectCmd = static_cast<DiffRectCmd *>(cmd.get());
591
+ diffRectCmd->draw(ctx);
592
+ break;
593
+ }
594
+ case CommandType::DrawTextBlob: {
595
+ auto *textBlobCmd = static_cast<TextBlobCmd *>(cmd.get());
596
+ textBlobCmd->draw(ctx);
597
+ break;
598
+ }
599
+ case CommandType::DrawGlyphs: {
600
+ auto *glyphsCmd = static_cast<GlyphsCmd *>(cmd.get());
601
+ glyphsCmd->draw(ctx);
602
+ break;
603
+ }
604
+ case CommandType::DrawPicture: {
605
+ auto *pictureCmd = static_cast<PictureCmd *>(cmd.get());
606
+ pictureCmd->draw(ctx);
607
+ break;
608
+ }
609
+ case CommandType::DrawImageSVG: {
610
+ auto *imageSVGCmd = static_cast<ImageSVGCmd *>(cmd.get());
611
+ imageSVGCmd->draw(ctx);
612
+ break;
613
+ }
614
+ case CommandType::DrawParagraph: {
615
+ auto *paragraphCmd = static_cast<ParagraphCmd *>(cmd.get());
616
+ paragraphCmd->draw(ctx);
617
+ break;
618
+ }
619
+ case CommandType::DrawAtlas: {
620
+ auto *atlasCmd = static_cast<AtlasCmd *>(cmd.get());
621
+ atlasCmd->draw(ctx);
622
+ break;
623
+ }
624
+ }
625
+
626
+ ctx->restorePaint();
627
+ }
628
+ break;
629
+ }
630
+ }
631
+ }
632
+ }
633
+ };
634
+
635
+ } // namespace RNSkia