@shopify/react-native-skia 0.1.165 → 0.1.167

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 (83) hide show
  1. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +11 -5
  2. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseViewManager.java +34 -0
  3. package/android/src/main/java/com/shopify/reactnative/skia/SkiaDomViewManager.java +2 -47
  4. package/android/src/main/java/com/shopify/reactnative/skia/SkiaDrawViewManager.java +2 -44
  5. package/android/src/main/java/com/shopify/reactnative/skia/SkiaPictureViewManager.java +2 -47
  6. package/cpp/api/JsiSkPath.h +20 -3
  7. package/cpp/rnskia/dom/base/DerivedNodeProp.h +4 -4
  8. package/cpp/rnskia/dom/nodes/JsiBoxNode.h +8 -16
  9. package/cpp/rnskia/dom/nodes/JsiPathNode.h +12 -5
  10. package/cpp/rnskia/dom/nodes/JsiShaderNodes.h +44 -13
  11. package/cpp/rnskia/dom/props/ClipProp.h +6 -6
  12. package/cpp/rnskia/dom/props/ImageProps.h +13 -8
  13. package/cpp/rnskia/dom/props/PaintProps.h +0 -16
  14. package/cpp/rnskia/dom/props/PointProp.h +4 -13
  15. package/cpp/rnskia/dom/props/PointsProp.h +1 -7
  16. package/cpp/rnskia/dom/props/RRectProp.h +53 -0
  17. package/cpp/rnskia/dom/props/RadiusProp.h +7 -9
  18. package/cpp/rnskia/dom/props/TransformProp.h +2 -2
  19. package/cpp/rnskia/dom/props/VerticesProps.h +2 -2
  20. package/lib/commonjs/dom/nodes/datatypes/Transform.js +0 -3
  21. package/lib/commonjs/dom/nodes/datatypes/Transform.js.map +1 -1
  22. package/lib/commonjs/dom/nodes/drawings/Box.js +1 -1
  23. package/lib/commonjs/dom/nodes/drawings/Box.js.map +1 -1
  24. package/lib/commonjs/dom/nodes/paint/ImageFilters.js +1 -1
  25. package/lib/commonjs/dom/nodes/paint/ImageFilters.js.map +1 -1
  26. package/lib/commonjs/dom/nodes/paint/Shaders.js +5 -2
  27. package/lib/commonjs/dom/nodes/paint/Shaders.js.map +1 -1
  28. package/lib/commonjs/renderer/Canvas.js +8 -39
  29. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  30. package/lib/commonjs/renderer/DrawingContext.js.map +1 -1
  31. package/lib/commonjs/renderer/Reconciler.js +64 -0
  32. package/lib/commonjs/renderer/Reconciler.js.map +1 -0
  33. package/lib/commonjs/skia/types/Path/Path.js.map +1 -1
  34. package/lib/commonjs/skia/types/Shader/Shader.js +26 -27
  35. package/lib/commonjs/skia/types/Shader/Shader.js.map +1 -1
  36. package/lib/commonjs/skia/web/JsiSkPath.js +7 -0
  37. package/lib/commonjs/skia/web/JsiSkPath.js.map +1 -1
  38. package/lib/commonjs/skia/web/JsiSkRRect.js +14 -1
  39. package/lib/commonjs/skia/web/JsiSkRRect.js.map +1 -1
  40. package/lib/commonjs/skia/web/JsiSkia.js +1 -1
  41. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  42. package/lib/module/dom/nodes/datatypes/Transform.js +0 -3
  43. package/lib/module/dom/nodes/datatypes/Transform.js.map +1 -1
  44. package/lib/module/dom/nodes/drawings/Box.js +1 -1
  45. package/lib/module/dom/nodes/drawings/Box.js.map +1 -1
  46. package/lib/module/dom/nodes/paint/ImageFilters.js +1 -1
  47. package/lib/module/dom/nodes/paint/ImageFilters.js.map +1 -1
  48. package/lib/module/dom/nodes/paint/Shaders.js +5 -4
  49. package/lib/module/dom/nodes/paint/Shaders.js.map +1 -1
  50. package/lib/module/renderer/Canvas.js +7 -33
  51. package/lib/module/renderer/Canvas.js.map +1 -1
  52. package/lib/module/renderer/DrawingContext.js.map +1 -1
  53. package/lib/module/renderer/Reconciler.js +48 -0
  54. package/lib/module/renderer/Reconciler.js.map +1 -0
  55. package/lib/module/skia/types/Path/Path.js.map +1 -1
  56. package/lib/module/skia/types/Shader/Shader.js +26 -27
  57. package/lib/module/skia/types/Shader/Shader.js.map +1 -1
  58. package/lib/module/skia/web/JsiSkPath.js +7 -0
  59. package/lib/module/skia/web/JsiSkPath.js.map +1 -1
  60. package/lib/module/skia/web/JsiSkRRect.js +14 -1
  61. package/lib/module/skia/web/JsiSkRRect.js.map +1 -1
  62. package/lib/module/skia/web/JsiSkia.js +1 -1
  63. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  64. package/lib/typescript/src/renderer/Canvas.d.ts +4 -7
  65. package/lib/typescript/src/renderer/DrawingContext.d.ts +2 -5
  66. package/lib/typescript/src/renderer/Reconciler.d.ts +13 -0
  67. package/lib/typescript/src/skia/types/Path/Path.d.ts +13 -0
  68. package/lib/typescript/src/skia/types/Shader/Shader.d.ts +1 -2
  69. package/lib/typescript/src/skia/web/JsiSkPath.d.ts +1 -0
  70. package/lib/typescript/src/skia/web/JsiSkRRect.d.ts +2 -2
  71. package/package.json +1 -1
  72. package/src/dom/nodes/datatypes/Transform.ts +0 -2
  73. package/src/dom/nodes/drawings/Box.ts +1 -1
  74. package/src/dom/nodes/paint/ImageFilters.ts +1 -1
  75. package/src/dom/nodes/paint/Shaders.ts +5 -5
  76. package/src/renderer/Canvas.tsx +12 -61
  77. package/src/renderer/DrawingContext.ts +2 -6
  78. package/src/renderer/Reconciler.tsx +66 -0
  79. package/src/skia/types/Path/Path.ts +14 -0
  80. package/src/skia/types/Shader/Shader.ts +30 -38
  81. package/src/skia/web/JsiSkPath.ts +10 -0
  82. package/src/skia/web/JsiSkRRect.ts +13 -2
  83. package/src/skia/web/JsiSkia.ts +1 -4
@@ -7,21 +7,27 @@ import android.view.Surface;
7
7
  import android.view.TextureView;
8
8
 
9
9
  import com.facebook.jni.annotations.DoNotStrip;
10
+ import com.facebook.react.uimanager.PointerEvents;
11
+ import com.facebook.react.views.view.ReactViewGroup;
10
12
 
11
- public abstract class SkiaBaseView extends TextureView implements TextureView.SurfaceTextureListener {
13
+ public abstract class SkiaBaseView extends ReactViewGroup implements TextureView.SurfaceTextureListener {
12
14
 
13
15
  @DoNotStrip
14
16
  private Surface mSurface;
17
+ private TextureView mTexture;
15
18
 
16
19
  public SkiaBaseView(Context context) {
17
20
  super(context);
18
- setSurfaceTextureListener(this);
19
- setOpaque(false);
21
+ mTexture = new TextureView(context);
22
+ mTexture.setSurfaceTextureListener(this);
23
+ mTexture.setOpaque(false);
24
+ addView(mTexture);
20
25
  }
21
26
 
22
27
  @Override
23
- public void setBackgroundColor(int color) {
24
- // Texture view does not support setting the background color.
28
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
29
+ super.onLayout(changed, left, top, right, bottom);
30
+ mTexture.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight());
25
31
  }
26
32
 
27
33
  @Override
@@ -0,0 +1,34 @@
1
+ package com.shopify.reactnative.skia;
2
+
3
+ import com.facebook.react.uimanager.annotations.ReactProp;
4
+ import com.facebook.react.views.view.ReactViewGroup;
5
+ import com.facebook.react.views.view.ReactViewManager;
6
+
7
+ import androidx.annotation.NonNull;
8
+ import androidx.annotation.Nullable;
9
+
10
+ public abstract class SkiaBaseViewManager extends ReactViewManager {
11
+
12
+ @Override
13
+ public void setNativeId(@NonNull ReactViewGroup view, @Nullable String nativeId) {
14
+ super.setNativeId(view, nativeId);
15
+ int nativeIdResolved = Integer.parseInt(nativeId);
16
+ ((SkiaBaseView)view).registerView(nativeIdResolved);
17
+ }
18
+
19
+ @ReactProp(name = "mode")
20
+ public void setMode(ReactViewGroup view, String mode) {
21
+ ((SkiaBaseView)view).setMode(mode);
22
+ }
23
+
24
+ @ReactProp(name = "debug")
25
+ public void setDebug(ReactViewGroup view, boolean show) {
26
+ ((SkiaBaseView)view).setDebugMode(show);
27
+ }
28
+
29
+ @Override
30
+ public void onDropViewInstance(@NonNull ReactViewGroup view) {
31
+ super.onDropViewInstance(view);
32
+ ((SkiaBaseView)view).unregisterView();
33
+ }
34
+ }
@@ -1,17 +1,9 @@
1
1
  package com.shopify.reactnative.skia;
2
2
 
3
- import com.facebook.react.bridge.ReactContext;
4
- import com.facebook.react.uimanager.BaseViewManager;
5
- import com.facebook.react.uimanager.LayoutShadowNode;
6
3
  import com.facebook.react.uimanager.ThemedReactContext;
7
- import com.facebook.react.uimanager.annotations.ReactProp;
8
-
9
4
  import androidx.annotation.NonNull;
10
- import androidx.annotation.Nullable;
11
-
12
- import java.util.HashMap;
13
5
 
14
- public class SkiaDomViewManager extends BaseViewManager<SkiaDomView, LayoutShadowNode> {
6
+ public class SkiaDomViewManager extends SkiaBaseViewManager {
15
7
 
16
8
  @NonNull
17
9
  @Override
@@ -19,46 +11,9 @@ public class SkiaDomViewManager extends BaseViewManager<SkiaDomView, LayoutShado
19
11
  return "SkiaDomView";
20
12
  }
21
13
 
22
- @Override
23
- public LayoutShadowNode createShadowNodeInstance() {
24
- return new LayoutShadowNode();
25
- }
26
-
27
- @Override
28
- public Class<? extends LayoutShadowNode> getShadowNodeClass() {
29
- return LayoutShadowNode.class;
30
- }
31
-
32
- @Override
33
- public void updateExtraData(SkiaDomView root, Object extraData) {
34
- }
35
-
36
- @Override
37
- public void setNativeId(@NonNull SkiaDomView view, @Nullable String nativeId) {
38
- super.setNativeId(view, nativeId);
39
- int nativeIdResolved = Integer.parseInt(nativeId);
40
- view.registerView(nativeIdResolved);
41
- }
42
-
43
- @ReactProp(name = "mode")
44
- public void setMode(SkiaDomView view, String mode) {
45
- view.setMode(mode);
46
- }
47
-
48
- @ReactProp(name = "debug")
49
- public void setDebug(SkiaDomView view, boolean show) {
50
- view.setDebugMode(show);
51
- }
52
-
53
- @Override
54
- public void onDropViewInstance(@NonNull SkiaDomView view) {
55
- super.onDropViewInstance(view);
56
- view.unregisterView();
57
- }
58
-
59
14
  @NonNull
60
15
  @Override
61
- protected SkiaDomView createViewInstance(@NonNull ThemedReactContext reactContext) {
16
+ public SkiaDomView createViewInstance(@NonNull ThemedReactContext reactContext) {
62
17
  return new SkiaDomView(reactContext);
63
18
  }
64
19
  }
@@ -1,14 +1,9 @@
1
1
  package com.shopify.reactnative.skia;
2
2
 
3
- import com.facebook.react.uimanager.BaseViewManager;
4
- import com.facebook.react.uimanager.LayoutShadowNode;
5
3
  import com.facebook.react.uimanager.ThemedReactContext;
6
- import com.facebook.react.uimanager.annotations.ReactProp;
7
-
8
4
  import androidx.annotation.NonNull;
9
- import androidx.annotation.Nullable;
10
5
 
11
- public class SkiaDrawViewManager extends BaseViewManager<SkiaDrawView, LayoutShadowNode> {
6
+ public class SkiaDrawViewManager extends SkiaBaseViewManager {
12
7
 
13
8
  @NonNull
14
9
  @Override
@@ -16,46 +11,9 @@ public class SkiaDrawViewManager extends BaseViewManager<SkiaDrawView, LayoutSha
16
11
  return "SkiaDrawView";
17
12
  }
18
13
 
19
- @Override
20
- public LayoutShadowNode createShadowNodeInstance() {
21
- return new LayoutShadowNode();
22
- }
23
-
24
- @Override
25
- public Class<? extends LayoutShadowNode> getShadowNodeClass() {
26
- return LayoutShadowNode.class;
27
- }
28
-
29
- @Override
30
- public void updateExtraData(SkiaDrawView root, Object extraData) {
31
- }
32
-
33
- @Override
34
- public void setNativeId(@NonNull SkiaDrawView view, @Nullable String nativeId) {
35
- super.setNativeId(view, nativeId);
36
- int nativeIdResolved = Integer.parseInt(nativeId);
37
- view.registerView(nativeIdResolved);
38
- }
39
-
40
- @ReactProp(name = "mode")
41
- public void setMode(SkiaDrawView view, String mode) {
42
- view.setMode(mode);
43
- }
44
-
45
- @ReactProp(name = "debug")
46
- public void setDebug(SkiaDrawView view, boolean show) {
47
- view.setDebugMode(show);
48
- }
49
-
50
- @Override
51
- public void onDropViewInstance(@NonNull SkiaDrawView view) {
52
- super.onDropViewInstance(view);
53
- view.unregisterView();
54
- }
55
-
56
14
  @NonNull
57
15
  @Override
58
- protected SkiaDrawView createViewInstance(@NonNull ThemedReactContext reactContext) {
16
+ public SkiaDrawView createViewInstance(@NonNull ThemedReactContext reactContext) {
59
17
  return new SkiaDrawView(reactContext);
60
18
  }
61
19
  }
@@ -1,17 +1,9 @@
1
1
  package com.shopify.reactnative.skia;
2
2
 
3
- import com.facebook.react.bridge.ReactContext;
4
- import com.facebook.react.uimanager.BaseViewManager;
5
- import com.facebook.react.uimanager.LayoutShadowNode;
6
3
  import com.facebook.react.uimanager.ThemedReactContext;
7
- import com.facebook.react.uimanager.annotations.ReactProp;
8
-
9
4
  import androidx.annotation.NonNull;
10
- import androidx.annotation.Nullable;
11
-
12
- import java.util.HashMap;
13
5
 
14
- public class SkiaPictureViewManager extends BaseViewManager<SkiaPictureView, LayoutShadowNode> {
6
+ public class SkiaPictureViewManager extends SkiaBaseViewManager {
15
7
 
16
8
  @NonNull
17
9
  @Override
@@ -19,46 +11,9 @@ public class SkiaPictureViewManager extends BaseViewManager<SkiaPictureView, Lay
19
11
  return "SkiaPictureView";
20
12
  }
21
13
 
22
- @Override
23
- public LayoutShadowNode createShadowNodeInstance() {
24
- return new LayoutShadowNode();
25
- }
26
-
27
- @Override
28
- public Class<? extends LayoutShadowNode> getShadowNodeClass() {
29
- return LayoutShadowNode.class;
30
- }
31
-
32
- @Override
33
- public void updateExtraData(SkiaPictureView root, Object extraData) {
34
- }
35
-
36
- @Override
37
- public void setNativeId(@NonNull SkiaPictureView view, @Nullable String nativeId) {
38
- super.setNativeId(view, nativeId);
39
- int nativeIdResolved = Integer.parseInt(nativeId);
40
- view.registerView(nativeIdResolved);
41
- }
42
-
43
- @ReactProp(name = "mode")
44
- public void setMode(SkiaPictureView view, String mode) {
45
- view.setMode(mode);
46
- }
47
-
48
- @ReactProp(name = "debug")
49
- public void setDebug(SkiaPictureView view, boolean show) {
50
- view.setDebugMode(show);
51
- }
52
-
53
- @Override
54
- public void onDropViewInstance(@NonNull SkiaPictureView view) {
55
- super.onDropViewInstance(view);
56
- view.unregisterView();
57
- }
58
-
59
14
  @NonNull
60
15
  @Override
61
- protected SkiaPictureView createViewInstance(@NonNull ThemedReactContext reactContext) {
16
+ public SkiaPictureView createViewInstance(@NonNull ThemedReactContext reactContext) {
62
17
  return new SkiaPictureView(reactContext);
63
18
  }
64
19
  }
@@ -41,6 +41,23 @@ public:
41
41
  return jsi::String::createFromUtf8(runtime, "Path");
42
42
  }
43
43
 
44
+ JSI_HOST_FUNCTION(addPath) {
45
+ auto src = JsiSkPath::fromValue(runtime, arguments[0]);
46
+ auto matrix =
47
+ count > 1 && !arguments[1].isUndefined() && !arguments[1].isNull()
48
+ ? JsiSkMatrix::fromValue(runtime, arguments[1])
49
+ : nullptr;
50
+ auto mode = count > 2 && arguments[2].asBool()
51
+ ? SkPath::kExtend_AddPathMode
52
+ : SkPath::kAppend_AddPathMode;
53
+ if (matrix == nullptr) {
54
+ getObject()->addPath(*src, mode);
55
+ } else {
56
+ getObject()->addPath(*src, *matrix, mode);
57
+ }
58
+ return thisValue.getObject(runtime);
59
+ }
60
+
44
61
  JSI_HOST_FUNCTION(addArc) {
45
62
  auto rect = JsiSkRect::fromValue(runtime, arguments[0]);
46
63
  auto start = arguments[1].asNumber();
@@ -512,9 +529,9 @@ public:
512
529
  JSI_EXPORT_PROPERTY_GETTERS(JSI_EXPORT_PROP_GET(JsiSkPath, __typename__))
513
530
 
514
531
  JSI_EXPORT_FUNCTIONS(
515
- JSI_EXPORT_FUNC(JsiSkPath, addArc), JSI_EXPORT_FUNC(JsiSkPath, addOval),
516
- JSI_EXPORT_FUNC(JsiSkPath, addPoly), JSI_EXPORT_FUNC(JsiSkPath, addRect),
517
- JSI_EXPORT_FUNC(JsiSkPath, addRRect),
532
+ JSI_EXPORT_FUNC(JsiSkPath, addPath), JSI_EXPORT_FUNC(JsiSkPath, addArc),
533
+ JSI_EXPORT_FUNC(JsiSkPath, addOval), JSI_EXPORT_FUNC(JsiSkPath, addPoly),
534
+ JSI_EXPORT_FUNC(JsiSkPath, addRect), JSI_EXPORT_FUNC(JsiSkPath, addRRect),
518
535
  JSI_EXPORT_FUNC(JsiSkPath, arcToOval),
519
536
  JSI_EXPORT_FUNC(JsiSkPath, arcToRotated),
520
537
  JSI_EXPORT_FUNC(JsiSkPath, rArcTo),
@@ -116,7 +116,7 @@ public:
116
116
  /**
117
117
  Returns the derived value
118
118
  */
119
- std::shared_ptr<T> getDerivedValue() { return _derivedValue; }
119
+ std::shared_ptr<const T> getDerivedValue() { return _derivedValue; }
120
120
 
121
121
  /**
122
122
  Returns true if is optional and one of the child props has a value, or all
@@ -128,7 +128,7 @@ protected:
128
128
  /**
129
129
  Set derived value from sub classes
130
130
  */
131
- void setDerivedValue(std::shared_ptr<T> value) {
131
+ void setDerivedValue(std::shared_ptr<const T> value) {
132
132
  setIsChanged(_derivedValue != value);
133
133
  _derivedValue = value;
134
134
  }
@@ -138,11 +138,11 @@ protected:
138
138
  */
139
139
  void setDerivedValue(const T &&value) {
140
140
  setIsChanged(true);
141
- _derivedValue = std::make_shared<T>(std::move(value));
141
+ _derivedValue = std::make_shared<const T>(std::move(value));
142
142
  }
143
143
 
144
144
  private:
145
- std::shared_ptr<T> _derivedValue;
145
+ std::shared_ptr<const T> _derivedValue;
146
146
  };
147
147
 
148
148
  /**
@@ -15,15 +15,8 @@ public:
15
15
 
16
16
  protected:
17
17
  void renderNode(DrawingContext *context) override {
18
- // Verify
19
- if (!_rrectProp->isSet() && !_rectProp->isSet()) {
20
- throw std::runtime_error("The box property must be set on the Box node.");
21
- }
22
-
23
18
  // Get rect - we'll try to end up with an rrect:
24
- auto box = _rrectProp->isSet()
25
- ? *_rrectProp->getDerivedValue()
26
- : SkRRect::MakeRectXY(*_rectProp->getDerivedValue(), 0, 0);
19
+ auto box = *_boxProp->getDerivedValue();
27
20
 
28
21
  // Get shadows
29
22
  std::vector<std::shared_ptr<JsiBoxShadowNode>> shadows;
@@ -76,13 +69,13 @@ protected:
76
69
 
77
70
  void defineProperties(NodePropsContainer *container) override {
78
71
  JsiDomRenderNode::defineProperties(container);
79
- _rrectProp = container->defineProperty<RRectProp>("box");
80
- _rectProp = container->defineProperty<RectProp>("box");
72
+ _boxProp = container->defineProperty<BoxProps>("box");
73
+ _boxProp->require();
81
74
  }
82
75
 
83
76
  private:
84
- SkRRect inflate(const SkRRect &box, SkScalar dx, SkScalar dy, size_t tx = 0,
85
- size_t ty = 0) {
77
+ SkRRect inflate(const SkRRect &box, SkScalar dx, SkScalar dy, SkScalar tx = 0,
78
+ SkScalar ty = 0) {
86
79
  return SkRRect::MakeRectXY(
87
80
  SkRect::MakeXYWH(box.rect().x() - dx + tx, box.rect().y() - dy + ty,
88
81
  box.rect().width() + 2 * dx,
@@ -90,13 +83,12 @@ private:
90
83
  box.getSimpleRadii().x() + dx, box.getSimpleRadii().y() + dy);
91
84
  }
92
85
 
93
- SkRRect deflate(const SkRRect &box, SkScalar dx, SkScalar dy, size_t tx = 0,
94
- size_t ty = 0) {
86
+ SkRRect deflate(const SkRRect &box, SkScalar dx, SkScalar dy, SkScalar tx = 0,
87
+ SkScalar ty = 0) {
95
88
  return inflate(box, -dx, -dy, tx, ty);
96
89
  }
97
90
 
98
- RRectProp *_rrectProp;
99
- RectProp *_rectProp;
91
+ BoxProps *_boxProp;
100
92
  };
101
93
 
102
94
  } // namespace RNSkia
@@ -59,20 +59,22 @@ protected:
59
59
  ", end: " + std::to_string(_endProp->value().getAsNumber()));
60
60
  }
61
61
  filteredPath.swap(filteredPath);
62
- _path = std::make_shared<SkPath>(filteredPath);
62
+ _path = std::make_shared<const SkPath>(filteredPath);
63
63
  } else if (hasStartOffset || hasEndOffset) {
64
64
  throw std::runtime_error(
65
65
  "Failed trimming path with parameters start: " +
66
66
  std::to_string(_startProp->value().getAsNumber()) +
67
67
  ", end: " + std::to_string(_endProp->value().getAsNumber()));
68
68
  } else {
69
- _path = std::make_shared<SkPath>(filteredPath);
69
+ _path = std::make_shared<const SkPath>(filteredPath);
70
70
  }
71
71
 
72
72
  // Set fill style
73
73
  if (_fillTypeProp->isSet()) {
74
74
  auto fillType = _fillTypeProp->value().getAsString();
75
- _path->setFillType(getFillTypeFromStringValue(fillType));
75
+ auto p = std::make_shared<SkPath>(*_path.get());
76
+ p->setFillType(getFillTypeFromStringValue(fillType));
77
+ _path = std::const_pointer_cast<const SkPath>(p);
76
78
  }
77
79
 
78
80
  // do we have a special paint here?
@@ -105,9 +107,14 @@ protected:
105
107
  precision = opts.getValue(PropNamePrecision).getAsNumber();
106
108
  }
107
109
 
108
- if (!strokePaint.getFillPath(*_path.get(), _path.get(), nullptr,
110
+ // _path is const so we can't mutate it directly, let's replace the
111
+ // path like this:
112
+ auto p = std::make_shared<SkPath>(*_path.get());
113
+ if (!strokePaint.getFillPath(*_path.get(), p.get(), nullptr,
109
114
  precision)) {
110
115
  _path = nullptr;
116
+ } else {
117
+ _path = std::const_pointer_cast<const SkPath>(p);
111
118
  }
112
119
  }
113
120
 
@@ -157,7 +164,7 @@ private:
157
164
  NodeProp *_fillTypeProp;
158
165
  NodeProp *_strokeOptsProp;
159
166
 
160
- std::shared_ptr<SkPath> _path;
167
+ std::shared_ptr<const SkPath> _path;
161
168
  };
162
169
 
163
170
  class StrokeOptsProps : public BaseDerivedProp {
@@ -67,9 +67,22 @@ protected:
67
67
  }
68
68
  auto uniforms =
69
69
  _uniformsProp->isSet() ? _uniformsProp->getDerivedValue() : nullptr;
70
- auto localMatrix =
70
+
71
+ SkMatrix lm;
72
+ auto tm =
71
73
  _transformProp->isSet() ? _transformProp->getDerivedValue() : nullptr;
72
74
 
75
+ if (tm != nullptr) {
76
+ if (_originProp->isSet()) {
77
+ auto tr = _originProp->getDerivedValue();
78
+ lm.preTranslate(tr->x(), tr->y());
79
+ lm.preConcat(*tm);
80
+ lm.preTranslate(-tr->x(), -tr->y());
81
+ } else {
82
+ lm.preConcat(*tm);
83
+ }
84
+ }
85
+
73
86
  // get all children that are shader nodes
74
87
  std::vector<sk_sp<SkShader>> children;
75
88
  children.reserve(getChildren().size());
@@ -82,8 +95,7 @@ protected:
82
95
 
83
96
  // Update shader
84
97
  setShader(context, source->getObject()->makeShader(
85
- uniforms, children.data(), children.size(),
86
- localMatrix.get()));
98
+ uniforms, children.data(), children.size(), &lm));
87
99
  }
88
100
  }
89
101
 
@@ -93,6 +105,7 @@ protected:
93
105
  _uniformsProp =
94
106
  container->defineProperty<UniformsProp>("uniforms", _sourceProp);
95
107
  _transformProp = container->defineProperty<TransformProp>("transform");
108
+ _originProp = container->defineProperty<PointProp>("origin");
96
109
 
97
110
  _sourceProp->require();
98
111
  }
@@ -101,6 +114,7 @@ private:
101
114
  NodeProp *_sourceProp;
102
115
  UniformsProp *_uniformsProp;
103
116
  TransformProp *_transformProp;
117
+ PointProp *_originProp;
104
118
  };
105
119
 
106
120
  class JsiImageShaderNode : public JsiBaseShaderNode,
@@ -114,15 +128,28 @@ protected:
114
128
  if (isChanged(context)) {
115
129
  auto image = _imageProps->getImage();
116
130
  auto rect = _imageProps->getRect();
117
- auto lm = _transformProp->isSet()
118
- ? _transformProp->getDerivedValue().get()
119
- : nullptr;
131
+ auto lm =
132
+ _transformProp->isSet() ? _transformProp->getDerivedValue() : nullptr;
120
133
 
121
134
  if (rect != nullptr && lm != nullptr) {
122
135
  auto rc = _imageProps->getDerivedValue();
123
136
  auto m3 = _imageProps->rect2rect(rc->src, rc->dst);
124
- lm->preTranslate(m3.x(), m3.y());
125
- lm->preScale(m3.width(), m3.height());
137
+ if (_transformProp->isChanged()) {
138
+ // To modify the matrix we need to copy it since we're not allowed to
139
+ // modify values contained in properties - this would have caused the
140
+ // matrix to be translated and scaled more and more for each render
141
+ // even thought the matrix prop did not change.
142
+ _matrix.reset();
143
+ _matrix.preConcat(m3);
144
+ if (_originProp->isSet()) {
145
+ auto tr = _originProp->getDerivedValue();
146
+ _matrix.preTranslate(tr->x(), tr->y());
147
+ _matrix.preConcat(*lm);
148
+ _matrix.preTranslate(-tr->x(), -tr->y());
149
+ } else {
150
+ _matrix.preConcat(*lm);
151
+ }
152
+ }
126
153
  }
127
154
 
128
155
  setShader(
@@ -133,7 +160,7 @@ protected:
133
160
  _filterModeProp->value().getAsString()),
134
161
  getMipmapModeFromString(
135
162
  _mipmapModeProp->value().getAsString())),
136
- lm));
163
+ &_matrix));
137
164
  }
138
165
  }
139
166
 
@@ -146,6 +173,7 @@ protected:
146
173
 
147
174
  _imageProps = container->defineProperty<ImageProps>();
148
175
  _transformProp = container->defineProperty<TransformProp>("transform");
176
+ _originProp = container->defineProperty<PointProp>("origin");
149
177
 
150
178
  _txProp->require();
151
179
  _tyProp->require();
@@ -185,12 +213,15 @@ private:
185
213
  "\" is not a valid Mipmap Mode.");
186
214
  }
187
215
 
216
+ SkMatrix _matrix;
217
+
188
218
  TileModeProp *_txProp;
189
219
  TileModeProp *_tyProp;
190
220
  NodeProp *_filterModeProp;
191
221
  NodeProp *_mipmapModeProp;
192
222
  ImageProps *_imageProps;
193
223
  TransformProp *_transformProp;
224
+ PointProp *_originProp;
194
225
  };
195
226
 
196
227
  class JsiColorShaderNode : public JsiBaseShaderNode,
@@ -328,12 +359,12 @@ protected:
328
359
  }
329
360
  }
330
361
 
331
- SkColor *_colors;
332
- SkTileMode _mode;
362
+ const SkColor *_colors;
333
363
  double _flags;
334
- SkScalar *_positions;
335
- SkMatrix *_matrix;
336
364
  int _colorCount;
365
+ SkTileMode _mode;
366
+ const SkScalar *_positions;
367
+ const SkMatrix *_matrix;
337
368
 
338
369
  private:
339
370
  TransformsProps *_transformsProps;
@@ -45,18 +45,18 @@ public:
45
45
  return _pathProp->isSet() || _rectProp->isSet() || _rrectProp->isSet();
46
46
  }
47
47
 
48
- SkPath *getPath() { return _path.get(); }
49
- SkRect *getRect() { return _rect.get(); }
50
- SkRRect *getRRect() { return _rrect.get(); }
48
+ const SkPath *getPath() { return _path.get(); }
49
+ const SkRect *getRect() { return _rect.get(); }
50
+ const SkRRect *getRRect() { return _rrect.get(); }
51
51
 
52
52
  private:
53
53
  PathProp *_pathProp;
54
54
  RectProp *_rectProp;
55
55
  RRectProp *_rrectProp;
56
56
 
57
- std::shared_ptr<SkPath> _path;
58
- std::shared_ptr<SkRect> _rect;
59
- std::shared_ptr<SkRRect> _rrect;
57
+ std::shared_ptr<const SkPath> _path;
58
+ std::shared_ptr<const SkRect> _rect;
59
+ std::shared_ptr<const SkRRect> _rrect;
60
60
  };
61
61
 
62
62
  } // namespace RNSkia
@@ -74,14 +74,19 @@ public:
74
74
  }
75
75
 
76
76
  sk_sp<SkImage> getImage() { return _imageProp->getDerivedValue(); }
77
- std::shared_ptr<SkRect> getRect() { return _rectProp->getDerivedValue(); }
78
-
79
- SkRect rect2rect(SkRect src, SkRect dst) {
80
- auto scaleX = dst.width() / src.width();
81
- auto scaleY = dst.height() / src.height();
82
- auto translateX = dst.x() - src.x() * scaleX;
83
- auto translateY = dst.y() - src.y() * scaleY;
84
- return SkRect::MakeXYWH(translateX, translateY, scaleX, scaleY);
77
+ std::shared_ptr<const SkRect> getRect() {
78
+ return _rectProp->getDerivedValue();
79
+ }
80
+
81
+ SkMatrix rect2rect(SkRect src, SkRect dst) {
82
+ auto sx = dst.width() / src.width();
83
+ auto sy = dst.height() / src.height();
84
+ auto tx = dst.x() - src.x() * sx;
85
+ auto ty = dst.y() - src.y() * sy;
86
+ SkMatrix m3;
87
+ m3.preTranslate(tx, ty);
88
+ m3.preScale(sx, sy);
89
+ return m3;
85
90
  }
86
91
 
87
92
  private:
@@ -19,8 +19,6 @@
19
19
 
20
20
  namespace RNSkia {
21
21
 
22
- static PropId PropNameCurrent = JsiPropId::get("current");
23
-
24
22
  class PaintProp : public DerivedProp<SkPaint> {
25
23
  public:
26
24
  explicit PaintProp(PropId name) : DerivedProp<SkPaint>() {
@@ -40,20 +38,6 @@ public:
40
38
  throw std::runtime_error("Expected SkPaint object, got unknown "
41
39
  "object when reading paint property.");
42
40
  }
43
- } else if (_paintProp->value().getType() == PropType::Object) {
44
- // We have a JS object - is it a ref?
45
- auto ref = _paintProp->value().getValue(PropNameCurrent);
46
- if (ref.getType() == PropType::HostObject) {
47
- auto ptr = ref.getAs<JsiSkPaint>();
48
- if (ptr != nullptr) {
49
- // Update the local paint for the current context
50
- setDerivedValue(ptr->getObject());
51
- } else {
52
- throw std::runtime_error(
53
- "Expected reference to a SkPaint object, got unknown object "
54
- "when reading paint property.");
55
- }
56
- }
57
41
  } else {
58
42
  setDerivedValue(nullptr);
59
43
  }