@shopify/react-native-skia 0.1.185 → 0.1.186
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.
- package/android/build.gradle +2 -1
- package/android/cpp/jni/JniPlatformContext.cpp +92 -3
- package/android/cpp/jni/include/JniPlatformContext.h +4 -0
- package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +8 -0
- package/android/src/main/java/com/shopify/reactnative/skia/PlatformContext.java +17 -1
- package/android/src/main/java/com/shopify/reactnative/skia/ViewScreenshotService.java +180 -0
- package/cpp/api/JsiSkFont.h +1 -1
- package/cpp/api/JsiSkHostObjects.h +1 -1
- package/cpp/api/JsiSkImage.h +1 -1
- package/cpp/api/JsiSkImageFactory.h +29 -0
- package/cpp/api/JsiSkPaint.h +7 -7
- package/cpp/api/JsiSkPathFactory.h +1 -1
- package/cpp/api/JsiSkPicture.h +2 -2
- package/cpp/api/JsiSkRuntimeEffect.h +3 -3
- package/cpp/api/JsiSkSVG.h +12 -2
- package/cpp/api/JsiSkShader.h +1 -1
- package/cpp/api/JsiSkSurface.h +3 -3
- package/cpp/api/JsiSkSurfaceFactory.h +1 -1
- package/cpp/api/JsiSkTypeface.h +1 -1
- package/cpp/rnskia/RNSkAnimation.h +3 -3
- package/cpp/rnskia/RNSkDomView.h +9 -9
- package/cpp/rnskia/RNSkInfoParameter.h +2 -2
- package/cpp/rnskia/RNSkJsView.h +8 -8
- package/cpp/rnskia/RNSkJsiViewApi.h +5 -5
- package/cpp/rnskia/RNSkPictureView.h +8 -8
- package/cpp/rnskia/RNSkPlatformContext.h +32 -3
- package/cpp/rnskia/RNSkValueApi.h +5 -5
- package/cpp/rnskia/RNSkView.h +6 -6
- package/cpp/rnskia/dom/base/ConcatablePaint.h +6 -6
- package/cpp/rnskia/dom/base/Declaration.h +1 -1
- package/cpp/rnskia/dom/base/DeclarationContext.h +7 -7
- package/cpp/rnskia/dom/base/DrawingContext.h +3 -3
- package/cpp/rnskia/dom/base/NodePropsContainer.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiBlurMaskNode.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiColorFilterNodes.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiGlyphsNode.h +8 -7
- package/cpp/rnskia/dom/nodes/JsiImageFilterNodes.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiImageNode.h +5 -2
- package/cpp/rnskia/dom/nodes/JsiImageSvgNode.h +9 -9
- package/cpp/rnskia/dom/nodes/JsiPathEffectNodes.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiPathNode.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiPointsNode.h +1 -1
- package/cpp/rnskia/dom/nodes/JsiShaderNodes.h +7 -3
- package/cpp/rnskia/dom/nodes/JsiTextNode.h +5 -4
- package/cpp/rnskia/dom/nodes/JsiTextPathNode.h +3 -1
- package/cpp/rnskia/dom/props/BlendModeProp.h +1 -1
- package/cpp/rnskia/dom/props/CircleProp.h +1 -1
- package/cpp/rnskia/dom/props/ClipProp.h +1 -1
- package/cpp/rnskia/dom/props/FontProp.h +15 -10
- package/cpp/rnskia/dom/props/ImageProps.h +30 -16
- package/cpp/rnskia/dom/props/PaintProps.h +1 -1
- package/cpp/rnskia/dom/props/PathProp.h +1 -1
- package/cpp/rnskia/dom/props/PointProp.h +1 -1
- package/cpp/rnskia/dom/props/PointsProp.h +1 -1
- package/cpp/rnskia/dom/props/RRectProp.h +2 -2
- package/cpp/rnskia/dom/props/RadiusProp.h +1 -1
- package/cpp/rnskia/dom/props/RectProp.h +1 -1
- package/cpp/rnskia/dom/props/StrokeProps.h +1 -1
- package/cpp/rnskia/dom/props/SvgProp.h +18 -12
- package/cpp/rnskia/dom/props/TextBlobProp.h +60 -57
- package/cpp/rnskia/dom/props/TileModeProp.h +1 -1
- package/cpp/rnskia/dom/props/UniformsProp.h +1 -1
- package/cpp/rnskia/dom/props/VertexModeProp.h +1 -1
- package/cpp/rnskia/dom/props/VerticesProps.h +1 -1
- package/cpp/rnskia/values/RNSkClockValue.h +2 -2
- package/cpp/rnskia/values/RNSkComputedValue.h +1 -1
- package/cpp/rnskia/values/RNSkReadonlyValue.h +3 -3
- package/cpp/rnskia/values/RNSkValue.h +4 -4
- package/cpp/utils/RNSkMeasureTime.h +1 -1
- package/cpp/utils/RNSkTimingInfo.h +1 -1
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +16 -13
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +8 -0
- package/ios/RNSkia-iOS/SkiaManager.mm +20 -1
- package/ios/RNSkia-iOS/ViewScreenshotService.h +21 -0
- package/ios/RNSkia-iOS/ViewScreenshotService.mm +79 -0
- package/lib/commonjs/dom/nodes/drawings/ImageNode.js +22 -1
- package/lib/commonjs/dom/nodes/drawings/ImageNode.js.map +1 -1
- package/lib/commonjs/dom/nodes/drawings/ImageSVG.js +5 -0
- package/lib/commonjs/dom/nodes/drawings/ImageSVG.js.map +1 -1
- package/lib/commonjs/dom/nodes/drawings/Text.d.ts +2 -2
- package/lib/commonjs/dom/nodes/drawings/Text.js +13 -2
- package/lib/commonjs/dom/nodes/drawings/Text.js.map +1 -1
- package/lib/commonjs/dom/nodes/paint/Shaders.js +5 -0
- package/lib/commonjs/dom/nodes/paint/Shaders.js.map +1 -1
- package/lib/commonjs/dom/types/Drawings.d.ts +5 -5
- package/lib/commonjs/dom/types/Drawings.js.map +1 -1
- package/lib/commonjs/dom/types/Shaders.d.ts +1 -1
- package/lib/commonjs/dom/types/Shaders.js.map +1 -1
- package/lib/commonjs/mock/index.js +2 -1
- package/lib/commonjs/mock/index.js.map +1 -1
- package/lib/commonjs/skia/core/Image.d.ts +14 -2
- package/lib/commonjs/skia/core/Image.js +37 -1
- package/lib/commonjs/skia/core/Image.js.map +1 -1
- package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +7 -0
- package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/commonjs/skia/types/SVG/SVG.d.ts +4 -1
- package/lib/commonjs/skia/types/SVG/SVG.js.map +1 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +2 -1
- package/lib/commonjs/skia/web/JsiSkImageFactory.js +7 -0
- package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/module/dom/nodes/drawings/ImageNode.js +22 -1
- package/lib/module/dom/nodes/drawings/ImageNode.js.map +1 -1
- package/lib/module/dom/nodes/drawings/ImageSVG.js +5 -0
- package/lib/module/dom/nodes/drawings/ImageSVG.js.map +1 -1
- package/lib/module/dom/nodes/drawings/Text.d.ts +2 -2
- package/lib/module/dom/nodes/drawings/Text.js +13 -2
- package/lib/module/dom/nodes/drawings/Text.js.map +1 -1
- package/lib/module/dom/nodes/paint/Shaders.js +5 -0
- package/lib/module/dom/nodes/paint/Shaders.js.map +1 -1
- package/lib/module/dom/types/Drawings.d.ts +5 -5
- package/lib/module/dom/types/Drawings.js.map +1 -1
- package/lib/module/dom/types/Shaders.d.ts +1 -1
- package/lib/module/dom/types/Shaders.js.map +1 -1
- package/lib/module/mock/index.js +2 -1
- package/lib/module/mock/index.js.map +1 -1
- package/lib/module/skia/core/Image.d.ts +14 -2
- package/lib/module/skia/core/Image.js +32 -0
- package/lib/module/skia/core/Image.js.map +1 -1
- package/lib/module/skia/types/Image/ImageFactory.d.ts +7 -0
- package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
- package/lib/module/skia/types/SVG/SVG.d.ts +4 -1
- package/lib/module/skia/types/SVG/SVG.js.map +1 -1
- package/lib/module/skia/web/JsiSkImageFactory.d.ts +2 -1
- package/lib/module/skia/web/JsiSkImageFactory.js +7 -0
- package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
- package/lib/typescript/src/dom/nodes/drawings/Text.d.ts +2 -2
- package/lib/typescript/src/dom/types/Drawings.d.ts +5 -5
- package/lib/typescript/src/dom/types/Shaders.d.ts +1 -1
- package/lib/typescript/src/skia/core/Image.d.ts +14 -2
- package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +7 -0
- package/lib/typescript/src/skia/types/SVG/SVG.d.ts +4 -1
- package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +2 -1
- package/package.json +2 -2
- package/scripts/install-npm.js +3 -2
- package/src/dom/nodes/drawings/ImageNode.ts +9 -1
- package/src/dom/nodes/drawings/ImageSVG.ts +3 -0
- package/src/dom/nodes/drawings/Text.ts +13 -3
- package/src/dom/nodes/paint/Shaders.ts +4 -0
- package/src/dom/types/Drawings.ts +5 -5
- package/src/dom/types/Shaders.ts +1 -1
- package/src/mock/index.ts +1 -0
- package/src/skia/core/Image.ts +43 -1
- package/src/skia/types/Image/ImageFactory.ts +8 -0
- package/src/skia/types/SVG/SVG.ts +4 -1
- package/src/skia/web/JsiSkImageFactory.ts +8 -1
|
@@ -17,19 +17,25 @@ public:
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
void updateDerivedValue() override {
|
|
20
|
-
if (_imageSvgProp->
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
if (_imageSvgProp->isSet()) {
|
|
21
|
+
|
|
22
|
+
if (_imageSvgProp->value().getType() == PropType::HostObject) {
|
|
23
|
+
|
|
24
|
+
auto ptr = std::dynamic_pointer_cast<JsiSkSVG>(
|
|
25
|
+
_imageSvgProp->value().getAsHostObject());
|
|
26
|
+
if (ptr == nullptr) {
|
|
27
|
+
throw std::runtime_error(
|
|
28
|
+
"Expected SkSvgDom object for the svg property.");
|
|
29
|
+
}
|
|
30
|
+
setDerivedValue(ptr->getObject());
|
|
31
|
+
} else {
|
|
32
|
+
throw std::runtime_error(
|
|
33
|
+
"Expected SkSvgDom object or null/undefined for the svg property.");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
} else {
|
|
37
|
+
setDerivedValue(nullptr);
|
|
23
38
|
}
|
|
24
|
-
|
|
25
|
-
auto ptr = std::dynamic_pointer_cast<JsiSkSVG>(
|
|
26
|
-
_imageSvgProp->value().getAsHostObject());
|
|
27
|
-
if (ptr == nullptr) {
|
|
28
|
-
throw std::runtime_error(
|
|
29
|
-
"Expected SkSvgDom object for the svg property.");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
setDerivedValue(ptr->getObject());
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
private:
|
|
@@ -46,7 +46,6 @@ public:
|
|
|
46
46
|
_pathProp = defineProperty<PathProp>("path");
|
|
47
47
|
_offsetProp = defineProperty<NodeProp>("initialOffset");
|
|
48
48
|
|
|
49
|
-
_fontProp->require();
|
|
50
49
|
_textProp->require();
|
|
51
50
|
_pathProp->require();
|
|
52
51
|
_offsetProp->require();
|
|
@@ -58,66 +57,70 @@ public:
|
|
|
58
57
|
auto path = _pathProp->getDerivedValue();
|
|
59
58
|
auto offset = _offsetProp->value().getAsNumber();
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
60
|
+
if (font != nullptr) {
|
|
61
|
+
// Get glyphs
|
|
62
|
+
auto numGlyphIds =
|
|
63
|
+
font->countText(text.c_str(), text.length(), SkTextEncoding::kUTF8);
|
|
64
|
+
|
|
65
|
+
std::vector<SkGlyphID> glyphIds;
|
|
66
|
+
glyphIds.reserve(numGlyphIds);
|
|
67
|
+
auto ids = font->textToGlyphs(
|
|
68
|
+
text.c_str(), text.length(), SkTextEncoding::kUTF8,
|
|
69
|
+
static_cast<SkGlyphID *>(glyphIds.data()), numGlyphIds);
|
|
70
|
+
|
|
71
|
+
// Get glyph widths
|
|
72
|
+
int glyphsSize = static_cast<int>(ids);
|
|
73
|
+
std::vector<SkScalar> widthPtrs;
|
|
74
|
+
widthPtrs.resize(glyphsSize);
|
|
75
|
+
font->getWidthsBounds(glyphIds.data(), numGlyphIds,
|
|
76
|
+
static_cast<SkScalar *>(widthPtrs.data()), nullptr,
|
|
77
|
+
nullptr); // TODO: Should we use paint somehow here?
|
|
78
|
+
|
|
79
|
+
std::vector<SkRSXform> rsx;
|
|
80
|
+
SkContourMeasureIter meas(*path, false, 1);
|
|
81
|
+
|
|
82
|
+
auto cont = meas.next();
|
|
83
|
+
auto dist = offset;
|
|
84
|
+
|
|
85
|
+
for (size_t i = 0; i < text.length() && cont != nullptr; ++i) {
|
|
86
|
+
auto width = widthPtrs[i];
|
|
87
|
+
dist += width / 2;
|
|
88
|
+
if (dist > cont->length()) {
|
|
89
|
+
// jump to next contour
|
|
90
|
+
cont = meas.next();
|
|
91
|
+
if (cont == nullptr) {
|
|
92
|
+
// We have come to the end of the path - terminate the string
|
|
93
|
+
// right here.
|
|
94
|
+
text = text.substr(0, i);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
dist = width / 2;
|
|
96
98
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
auto tx = tan.x();
|
|
110
|
-
auto ty = tan.y();
|
|
99
|
+
// Gives us the (x, y) coordinates as well as the cos/sin of the tangent
|
|
100
|
+
// line at that position.
|
|
101
|
+
SkPoint pos;
|
|
102
|
+
SkVector tan;
|
|
103
|
+
if (!cont->getPosTan(dist, &pos, &tan)) {
|
|
104
|
+
throw std::runtime_error(
|
|
105
|
+
"Could not calculate distance when resolving text path");
|
|
106
|
+
}
|
|
107
|
+
auto px = pos.x();
|
|
108
|
+
auto py = pos.y();
|
|
109
|
+
auto tx = tan.x();
|
|
110
|
+
auto ty = tan.y();
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
auto adjustedX = px - (width / 2) * tx;
|
|
113
|
+
auto adjustedY = py - (width / 2) * ty;
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
rsx.push_back(SkRSXform::Make(tx, ty, adjustedX, adjustedY));
|
|
116
|
+
dist += width / 2;
|
|
117
|
+
}
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
setDerivedValue(SkTextBlob::MakeFromRSXform(text.c_str(), text.length(),
|
|
120
|
+
rsx.data(), *font));
|
|
121
|
+
} else {
|
|
122
|
+
setDerivedValue(nullptr);
|
|
123
|
+
}
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
private:
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
#include <jsi/jsi.h>
|
|
12
12
|
|
|
13
|
-
#include
|
|
14
|
-
#include
|
|
15
|
-
#include
|
|
13
|
+
#include "JsiSkHostObjects.h"
|
|
14
|
+
#include "JsiValueWrapper.h"
|
|
15
|
+
#include "RNSkPlatformContext.h"
|
|
16
16
|
|
|
17
17
|
namespace RNSkia {
|
|
18
18
|
namespace jsi = facebook::jsi;
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
#include <functional>
|
|
4
4
|
#include <memory>
|
|
5
5
|
|
|
6
|
-
#include
|
|
7
|
-
#include
|
|
8
|
-
#include
|
|
9
|
-
#include
|
|
6
|
+
#include "JsiHostObject.h"
|
|
7
|
+
#include "RNSkAnimation.h"
|
|
8
|
+
#include "RNSkPlatformContext.h"
|
|
9
|
+
#include "RNSkReadonlyValue.h"
|
|
10
10
|
#include <jsi/jsi.h>
|
|
11
11
|
|
|
12
12
|
namespace RNSkia {
|
|
@@ -6,16 +6,8 @@
|
|
|
6
6
|
#include <memory>
|
|
7
7
|
#include <string>
|
|
8
8
|
|
|
9
|
-
#include
|
|
10
|
-
#include
|
|
11
|
-
|
|
12
|
-
#pragma clang diagnostic push
|
|
13
|
-
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
14
|
-
|
|
15
|
-
#include "SkStream.h"
|
|
16
|
-
#include "SkSurface.h"
|
|
17
|
-
|
|
18
|
-
#pragma clang diagnostic pop
|
|
9
|
+
#include "DisplayLink.h"
|
|
10
|
+
#include "RNSkPlatformContext.h"
|
|
19
11
|
|
|
20
12
|
#include <jsi/jsi.h>
|
|
21
13
|
|
|
@@ -35,10 +27,15 @@ static void handleNotification(CFNotificationCenterRef center, void *observer,
|
|
|
35
27
|
|
|
36
28
|
class RNSkiOSPlatformContext : public RNSkPlatformContext {
|
|
37
29
|
public:
|
|
38
|
-
RNSkiOSPlatformContext(
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
RNSkiOSPlatformContext(
|
|
31
|
+
jsi::Runtime *runtime, std::shared_ptr<react::CallInvoker> callInvoker,
|
|
32
|
+
std::function<void(std::function<void()>)> dispatchMainThread,
|
|
33
|
+
std::function<sk_sp<SkImage>(size_t viewTag)> takeViewScreenshot)
|
|
34
|
+
: _dispatchMainThread(dispatchMainThread),
|
|
35
|
+
_takeViewScreenshot(takeViewScreenshot),
|
|
36
|
+
RNSkPlatformContext(runtime, callInvoker,
|
|
41
37
|
[[UIScreen mainScreen] scale]) {
|
|
38
|
+
|
|
42
39
|
// We need to make sure we invalidate when modules are freed
|
|
43
40
|
CFNotificationCenterAddObserver(
|
|
44
41
|
CFNotificationCenterGetLocalCenter(), this, &handleNotification,
|
|
@@ -55,6 +52,10 @@ public:
|
|
|
55
52
|
void startDrawLoop() override;
|
|
56
53
|
void stopDrawLoop() override;
|
|
57
54
|
|
|
55
|
+
void runOnMainThread(std::function<void()>) override;
|
|
56
|
+
|
|
57
|
+
sk_sp<SkImage> takeScreenshotFromViewTag(size_t tag) override;
|
|
58
|
+
|
|
58
59
|
virtual void performStreamOperation(
|
|
59
60
|
const std::string &sourceUri,
|
|
60
61
|
const std::function<void(std::unique_ptr<SkStreamAsset>)> &op) override;
|
|
@@ -69,6 +70,8 @@ public:
|
|
|
69
70
|
|
|
70
71
|
private:
|
|
71
72
|
DisplayLink *_displayLink;
|
|
73
|
+
std::function<void(std::function<void()>)> _dispatchMainThread;
|
|
74
|
+
std::function<sk_sp<SkImage>(size_t viewTag)> _takeViewScreenshot;
|
|
72
75
|
};
|
|
73
76
|
|
|
74
77
|
static void handleNotification(CFNotificationCenterRef center, void *observer,
|
|
@@ -62,6 +62,14 @@ sk_sp<SkSurface> RNSkiOSPlatformContext::makeOffscreenSurface(int width,
|
|
|
62
62
|
return MakeOffscreenMetalSurface(width, height);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
void RNSkiOSPlatformContext::runOnMainThread(std::function<void()> func) {
|
|
66
|
+
_dispatchMainThread(func);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
sk_sp<SkImage> RNSkiOSPlatformContext::takeScreenshotFromViewTag(size_t tag) {
|
|
70
|
+
return _takeViewScreenshot(tag);
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
void RNSkiOSPlatformContext::startDrawLoop() {
|
|
66
74
|
if (_displayLink == nullptr) {
|
|
67
75
|
_displayLink = [[DisplayLink alloc] init];
|
|
@@ -4,14 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
#import <React/RCTBridge+Private.h>
|
|
6
6
|
#import <React/RCTBridge.h>
|
|
7
|
+
#import <React/RCTUIManager.h>
|
|
7
8
|
|
|
8
9
|
#import <ReactCommon/RCTTurboModule.h>
|
|
9
10
|
|
|
10
11
|
#import "RNSkiOSPlatformContext.h"
|
|
12
|
+
#import "ViewScreenshotService.h"
|
|
11
13
|
|
|
12
14
|
@implementation SkiaManager {
|
|
13
15
|
std::shared_ptr<RNSkia::RNSkManager> _skManager;
|
|
14
16
|
std::shared_ptr<RNSkia::RNSkiOSPlatformContext> _platformContext;
|
|
17
|
+
ViewScreenshotService *_screenshot;
|
|
15
18
|
__weak RCTBridge *weakBridge;
|
|
16
19
|
}
|
|
17
20
|
|
|
@@ -37,9 +40,25 @@
|
|
|
37
40
|
facebook::jsi::Runtime *jsRuntime =
|
|
38
41
|
(facebook::jsi::Runtime *)cxxBridge.runtime;
|
|
39
42
|
|
|
43
|
+
// Create screenshot manager
|
|
44
|
+
_screenshot =
|
|
45
|
+
[[ViewScreenshotService alloc] initWithUiManager:bridge.uiManager];
|
|
46
|
+
|
|
47
|
+
auto takeScreenshot = [self](size_t viewTag) {
|
|
48
|
+
return [_screenshot
|
|
49
|
+
screenshotOfViewWithTag:[NSNumber numberWithLong:viewTag]];
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
auto dispatchOnMainThread = [self](std::function<void()> fp) {
|
|
53
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
54
|
+
fp();
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
40
58
|
// Create platform context
|
|
41
59
|
_platformContext = std::make_shared<RNSkia::RNSkiOSPlatformContext>(
|
|
42
|
-
jsRuntime, callInvoker)
|
|
60
|
+
jsRuntime, callInvoker, std::move(dispatchOnMainThread),
|
|
61
|
+
std::move(takeScreenshot));
|
|
43
62
|
|
|
44
63
|
// Create the RNSkiaManager (cross platform)
|
|
45
64
|
_skManager = std::make_shared<RNSkia::RNSkManager>(jsRuntime, callInvoker,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <CoreFoundation/CoreFoundation.h>
|
|
4
|
+
#import <UIKit/UIKit.h>
|
|
5
|
+
|
|
6
|
+
#import <React/RCTUIManager.h>
|
|
7
|
+
|
|
8
|
+
#pragma clang diagnostic push
|
|
9
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
10
|
+
|
|
11
|
+
#include "SkImage.h"
|
|
12
|
+
|
|
13
|
+
#pragma clang diagnostic pop
|
|
14
|
+
|
|
15
|
+
@interface ViewScreenshotService : NSObject {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
- (instancetype)initWithUiManager:(RCTUIManager *)uiManager;
|
|
19
|
+
- (sk_sp<SkImage>)screenshotOfViewWithTag:(NSNumber *)viewTag;
|
|
20
|
+
|
|
21
|
+
@end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#import "ViewScreenshotService.h"
|
|
2
|
+
#import <QuartzCore/QuartzCore.h>
|
|
3
|
+
|
|
4
|
+
#pragma clang diagnostic push
|
|
5
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
6
|
+
|
|
7
|
+
#include "SkData.h"
|
|
8
|
+
|
|
9
|
+
#pragma clang diagnostic pop
|
|
10
|
+
|
|
11
|
+
@implementation ViewScreenshotService {
|
|
12
|
+
RCTUIManager *_uiManager;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
- (instancetype)initWithUiManager:(RCTUIManager *)uiManager {
|
|
16
|
+
if (self = [super init]) {
|
|
17
|
+
_uiManager = uiManager;
|
|
18
|
+
}
|
|
19
|
+
return self;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
- (sk_sp<SkImage>)screenshotOfViewWithTag:(NSNumber *)viewTag {
|
|
23
|
+
// Find view corresponding to the tag
|
|
24
|
+
auto view = [_uiManager viewForReactTag:viewTag];
|
|
25
|
+
if (view == NULL) {
|
|
26
|
+
RCTFatal(RCTErrorWithMessage(@"Could not find view with tag"));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Get size
|
|
30
|
+
CGSize size = view.frame.size;
|
|
31
|
+
|
|
32
|
+
// Setup context
|
|
33
|
+
UIGraphicsImageRendererFormat *format =
|
|
34
|
+
[UIGraphicsImageRendererFormat defaultFormat];
|
|
35
|
+
format.opaque = NO;
|
|
36
|
+
UIGraphicsImageRenderer *renderer =
|
|
37
|
+
[[UIGraphicsImageRenderer alloc] initWithSize:size format:format];
|
|
38
|
+
|
|
39
|
+
// Render to context - this is now the only part of this function that shows
|
|
40
|
+
// up in the profiler!
|
|
41
|
+
UIImage *image = [renderer
|
|
42
|
+
imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull context) {
|
|
43
|
+
[view drawViewHierarchyInRect:(CGRect){CGPointZero, size}
|
|
44
|
+
afterScreenUpdates:YES];
|
|
45
|
+
}];
|
|
46
|
+
|
|
47
|
+
// Convert from UIImage -> CGImage -> SkImage
|
|
48
|
+
CGImageRef cgImage = image.CGImage;
|
|
49
|
+
|
|
50
|
+
// Get some info about the image
|
|
51
|
+
auto width = CGImageGetWidth(cgImage);
|
|
52
|
+
auto height = CGImageGetHeight(cgImage);
|
|
53
|
+
auto bytesPerRow = CGImageGetBytesPerRow(cgImage);
|
|
54
|
+
|
|
55
|
+
// Convert from UIImage -> SkImage, start by getting the pixels directly from
|
|
56
|
+
// the CGImage:
|
|
57
|
+
auto dataRef = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
|
|
58
|
+
auto length = CFDataGetLength(dataRef);
|
|
59
|
+
void *data = CFDataGetMutableBytePtr((CFMutableDataRef)dataRef);
|
|
60
|
+
|
|
61
|
+
// Now we'll capture the data in an SkData object and control releasing it:
|
|
62
|
+
auto skData = SkData::MakeWithProc(
|
|
63
|
+
data, length,
|
|
64
|
+
[](const void *ptr, void *context) {
|
|
65
|
+
CFDataRef dataRef = (CFDataRef)context;
|
|
66
|
+
CFRelease(dataRef);
|
|
67
|
+
},
|
|
68
|
+
(void *)dataRef);
|
|
69
|
+
|
|
70
|
+
// Make SkImageInfo
|
|
71
|
+
SkImageInfo info =
|
|
72
|
+
SkImageInfo::Make(static_cast<int>(width), static_cast<int>(height),
|
|
73
|
+
kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
|
74
|
+
|
|
75
|
+
// ... and then create the SkImage itself!
|
|
76
|
+
return SkImage::MakeRasterData(info, skData, bytesPerRow);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@end
|
|
@@ -20,6 +20,24 @@ class ImageNode extends _DrawingNode.JsiDrawingNode {
|
|
|
20
20
|
const {
|
|
21
21
|
image
|
|
22
22
|
} = this.props;
|
|
23
|
+
|
|
24
|
+
if (!image) {
|
|
25
|
+
return {
|
|
26
|
+
src: {
|
|
27
|
+
x: 0,
|
|
28
|
+
y: 0,
|
|
29
|
+
width: 0,
|
|
30
|
+
height: 0
|
|
31
|
+
},
|
|
32
|
+
dst: {
|
|
33
|
+
x: 0,
|
|
34
|
+
y: 0,
|
|
35
|
+
width: 0,
|
|
36
|
+
height: 0
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
const fit = this.props.fit ?? "contain";
|
|
24
42
|
const rect = (0, _datatypes.processRect)(this.Skia, this.props);
|
|
25
43
|
const {
|
|
@@ -54,7 +72,10 @@ class ImageNode extends _DrawingNode.JsiDrawingNode {
|
|
|
54
72
|
src,
|
|
55
73
|
dst
|
|
56
74
|
} = this.derived;
|
|
57
|
-
|
|
75
|
+
|
|
76
|
+
if (image) {
|
|
77
|
+
canvas.drawImageRect(image, src, dst, paint);
|
|
78
|
+
}
|
|
58
79
|
}
|
|
59
80
|
|
|
60
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ImageNode","JsiDrawingNode","constructor","ctx","props","NodeType","Image","deriveProps","image","
|
|
1
|
+
{"version":3,"names":["ImageNode","JsiDrawingNode","constructor","ctx","props","NodeType","Image","deriveProps","image","src","x","y","width","height","dst","fit","rect","processRect","Skia","fitRects","draw","canvas","paint","derived","Error","drawImageRect"],"sources":["ImageNode.ts"],"sourcesContent":["import type { SkRect } from \"../../../skia/types\";\nimport type { DrawingContext, ImageProps } from \"../../types\";\nimport { NodeType } from \"../../types\";\nimport { fitRects, processRect } from \"../datatypes\";\nimport { JsiDrawingNode } from \"../DrawingNode\";\nimport type { NodeContext } from \"../Node\";\n\nexport class ImageNode extends JsiDrawingNode<\n ImageProps,\n { src: SkRect; dst: SkRect }\n> {\n constructor(ctx: NodeContext, props: ImageProps) {\n super(ctx, NodeType.Image, props);\n }\n\n deriveProps() {\n const { image } = this.props;\n if (!image) {\n return {\n src: { x: 0, y: 0, width: 0, height: 0 },\n dst: { x: 0, y: 0, width: 0, height: 0 },\n };\n }\n const fit = this.props.fit ?? \"contain\";\n const rect = processRect(this.Skia, this.props);\n const { src, dst } = fitRects(\n fit,\n {\n x: 0,\n y: 0,\n width: image.width(),\n height: image.height(),\n },\n rect\n );\n return { src, dst };\n }\n\n draw({ canvas, paint }: DrawingContext) {\n const { image } = this.props;\n if (!this.derived) {\n throw new Error(\"ImageNode: src and dst are undefined\");\n }\n const { src, dst } = this.derived;\n if (image) {\n canvas.drawImageRect(image, src, dst, paint);\n }\n }\n}\n"],"mappings":";;;;;;;AAEA;;AACA;;AACA;;AAGO,MAAMA,SAAN,SAAwBC,2BAAxB,CAGL;EACAC,WAAW,CAACC,GAAD,EAAmBC,KAAnB,EAAsC;IAC/C,MAAMD,GAAN,EAAWE,eAAA,CAASC,KAApB,EAA2BF,KAA3B;EACD;;EAEDG,WAAW,GAAG;IACZ,MAAM;MAAEC;IAAF,IAAY,KAAKJ,KAAvB;;IACA,IAAI,CAACI,KAAL,EAAY;MACV,OAAO;QACLC,GAAG,EAAE;UAAEC,CAAC,EAAE,CAAL;UAAQC,CAAC,EAAE,CAAX;UAAcC,KAAK,EAAE,CAArB;UAAwBC,MAAM,EAAE;QAAhC,CADA;QAELC,GAAG,EAAE;UAAEJ,CAAC,EAAE,CAAL;UAAQC,CAAC,EAAE,CAAX;UAAcC,KAAK,EAAE,CAArB;UAAwBC,MAAM,EAAE;QAAhC;MAFA,CAAP;IAID;;IACD,MAAME,GAAG,GAAG,KAAKX,KAAL,CAAWW,GAAX,IAAkB,SAA9B;IACA,MAAMC,IAAI,GAAG,IAAAC,sBAAA,EAAY,KAAKC,IAAjB,EAAuB,KAAKd,KAA5B,CAAb;IACA,MAAM;MAAEK,GAAF;MAAOK;IAAP,IAAe,IAAAK,mBAAA,EACnBJ,GADmB,EAEnB;MACEL,CAAC,EAAE,CADL;MAEEC,CAAC,EAAE,CAFL;MAGEC,KAAK,EAAEJ,KAAK,CAACI,KAAN,EAHT;MAIEC,MAAM,EAAEL,KAAK,CAACK,MAAN;IAJV,CAFmB,EAQnBG,IARmB,CAArB;IAUA,OAAO;MAAEP,GAAF;MAAOK;IAAP,CAAP;EACD;;EAEDM,IAAI,OAAoC;IAAA,IAAnC;MAAEC,MAAF;MAAUC;IAAV,CAAmC;IACtC,MAAM;MAAEd;IAAF,IAAY,KAAKJ,KAAvB;;IACA,IAAI,CAAC,KAAKmB,OAAV,EAAmB;MACjB,MAAM,IAAIC,KAAJ,CAAU,sCAAV,CAAN;IACD;;IACD,MAAM;MAAEf,GAAF;MAAOK;IAAP,IAAe,KAAKS,OAA1B;;IACA,IAAIf,KAAJ,EAAW;MACTa,MAAM,CAACI,aAAP,CAAqBjB,KAArB,EAA4BC,GAA5B,EAAiCK,GAAjC,EAAsCQ,KAAtC;IACD;EACF;;AArCD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ImageSVGNode","JsiDrawingNode","constructor","ctx","props","NodeType","ImageSVG","deriveProps","draw","canvas","svg","x","y","width","height","processRect","Skia","save","translate","drawSvg","restore"],"sources":["ImageSVG.ts"],"sourcesContent":["import type { DrawingContext, ImageSVGProps } from \"../../types\";\nimport { NodeType } from \"../../types\";\nimport { processRect } from \"../datatypes\";\nimport { JsiDrawingNode } from \"../DrawingNode\";\nimport type { NodeContext } from \"../Node\";\n\nexport class ImageSVGNode extends JsiDrawingNode<ImageSVGProps, null> {\n constructor(ctx: NodeContext, props: ImageSVGProps) {\n super(ctx, NodeType.ImageSVG, props);\n }\n\n deriveProps() {\n return null;\n }\n\n draw({ canvas }: DrawingContext) {\n const { svg } = this.props;\n const { x, y, width, height } = processRect(this.Skia, this.props);\n canvas.save();\n canvas.translate(x, y);\n canvas.drawSvg(svg, width, height);\n canvas.restore();\n }\n}\n"],"mappings":";;;;;;;AACA;;AACA;;AACA;;AAGO,MAAMA,YAAN,SAA2BC,2BAA3B,CAA+D;EACpEC,WAAW,CAACC,GAAD,EAAmBC,KAAnB,EAAyC;IAClD,MAAMD,GAAN,EAAWE,eAAA,CAASC,QAApB,EAA8BF,KAA9B;EACD;;EAEDG,WAAW,GAAG;IACZ,OAAO,IAAP;EACD;;EAEDC,IAAI,OAA6B;IAAA,IAA5B;MAAEC;IAAF,CAA4B;IAC/B,MAAM;MAAEC;IAAF,IAAU,KAAKN,KAArB
|
|
1
|
+
{"version":3,"names":["ImageSVGNode","JsiDrawingNode","constructor","ctx","props","NodeType","ImageSVG","deriveProps","draw","canvas","svg","x","y","width","height","processRect","Skia","save","translate","drawSvg","restore"],"sources":["ImageSVG.ts"],"sourcesContent":["import type { DrawingContext, ImageSVGProps } from \"../../types\";\nimport { NodeType } from \"../../types\";\nimport { processRect } from \"../datatypes\";\nimport { JsiDrawingNode } from \"../DrawingNode\";\nimport type { NodeContext } from \"../Node\";\n\nexport class ImageSVGNode extends JsiDrawingNode<ImageSVGProps, null> {\n constructor(ctx: NodeContext, props: ImageSVGProps) {\n super(ctx, NodeType.ImageSVG, props);\n }\n\n deriveProps() {\n return null;\n }\n\n draw({ canvas }: DrawingContext) {\n const { svg } = this.props;\n if (!svg) {\n return;\n }\n const { x, y, width, height } = processRect(this.Skia, this.props);\n canvas.save();\n canvas.translate(x, y);\n canvas.drawSvg(svg, width, height);\n canvas.restore();\n }\n}\n"],"mappings":";;;;;;;AACA;;AACA;;AACA;;AAGO,MAAMA,YAAN,SAA2BC,2BAA3B,CAA+D;EACpEC,WAAW,CAACC,GAAD,EAAmBC,KAAnB,EAAyC;IAClD,MAAMD,GAAN,EAAWE,eAAA,CAASC,QAApB,EAA8BF,KAA9B;EACD;;EAEDG,WAAW,GAAG;IACZ,OAAO,IAAP;EACD;;EAEDC,IAAI,OAA6B;IAAA,IAA5B;MAAEC;IAAF,CAA4B;IAC/B,MAAM;MAAEC;IAAF,IAAU,KAAKN,KAArB;;IACA,IAAI,CAACM,GAAL,EAAU;MACR;IACD;;IACD,MAAM;MAAEC,CAAF;MAAKC,CAAL;MAAQC,KAAR;MAAeC;IAAf,IAA0B,IAAAC,sBAAA,EAAY,KAAKC,IAAjB,EAAuB,KAAKZ,KAA5B,CAAhC;IACAK,MAAM,CAACQ,IAAP;IACAR,MAAM,CAACS,SAAP,CAAiBP,CAAjB,EAAoBC,CAApB;IACAH,MAAM,CAACU,OAAP,CAAeT,GAAf,EAAoBG,KAApB,EAA2BC,MAA3B;IACAL,MAAM,CAACW,OAAP;EACD;;AAnBmE"}
|
|
@@ -8,9 +8,9 @@ export declare class TextNode extends JsiDrawingNode<TextProps, null> {
|
|
|
8
8
|
protected deriveProps(): null;
|
|
9
9
|
draw({ canvas, paint }: DrawingContext): void;
|
|
10
10
|
}
|
|
11
|
-
export declare class TextPathNode extends JsiDrawingNode<TextPathProps, SkTextBlob> {
|
|
11
|
+
export declare class TextPathNode extends JsiDrawingNode<TextPathProps, SkTextBlob | null> {
|
|
12
12
|
constructor(ctx: NodeContext, props: TextPathProps);
|
|
13
|
-
deriveProps(): SkTextBlob;
|
|
13
|
+
deriveProps(): SkTextBlob | null;
|
|
14
14
|
draw({ canvas, paint }: DrawingContext): void;
|
|
15
15
|
}
|
|
16
16
|
export declare class TextBlobNode extends JsiDrawingNode<TextBlobProps, null> {
|
|
@@ -31,7 +31,10 @@ class TextNode extends _DrawingNode.JsiDrawingNode {
|
|
|
31
31
|
y,
|
|
32
32
|
font
|
|
33
33
|
} = this.props;
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
if (font) {
|
|
36
|
+
canvas.drawText(text, x, y, paint, font);
|
|
37
|
+
}
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
}
|
|
@@ -49,6 +52,11 @@ class TextPathNode extends _DrawingNode.JsiDrawingNode {
|
|
|
49
52
|
font,
|
|
50
53
|
initialOffset
|
|
51
54
|
} = this.props;
|
|
55
|
+
|
|
56
|
+
if (!font) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
let {
|
|
53
61
|
text
|
|
54
62
|
} = this.props;
|
|
@@ -171,7 +179,10 @@ class GlyphsNode extends _DrawingNode.JsiDrawingNode {
|
|
|
171
179
|
y,
|
|
172
180
|
font
|
|
173
181
|
} = this.props;
|
|
174
|
-
|
|
182
|
+
|
|
183
|
+
if (font) {
|
|
184
|
+
canvas.drawGlyphs(glyphs, positions, x, y, font, paint);
|
|
185
|
+
}
|
|
175
186
|
}
|
|
176
187
|
|
|
177
188
|
}
|