@shopify/react-native-skia 0.1.165 → 0.1.167

Sign up to get free protection for your applications and to get access to all the features.
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
  }