react-native-windows 0.74.1 → 0.74.3
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/Libraries/Components/Touchable/TouchableBounce.js +1 -0
- package/Libraries/Components/Touchable/TouchableOpacity.js +1 -0
- package/Libraries/Components/Touchable/TouchableOpacity.windows.js +1 -0
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +26 -13
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -2
- package/Microsoft.ReactNative/Fabric/Composition/ImageResponseImage.h +17 -0
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +230 -0
- package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h +36 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +3 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +2 -0
- package/Microsoft.ReactNative/Fabric/ImageManager.cpp +3 -2
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +102 -35
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +6 -1
- package/Microsoft.ReactNative/IReactPackageBuilderFabric.idl +5 -0
- package/Microsoft.ReactNative/ReactHost/React.h +7 -0
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +7 -0
- package/Microsoft.ReactNative/ReactNativeHost.cpp +8 -0
- package/Microsoft.ReactNative/ReactPackageBuilder.cpp +8 -0
- package/Microsoft.ReactNative/ReactPackageBuilder.h +6 -0
- package/Microsoft.ReactNative/UriImageManager.idl +75 -0
- package/Microsoft.ReactNative.Cxx/AutoDraw.h +1 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Shared.vcxitems +6 -0
- package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +33 -21
- package/codegen/rnwcoreJSI-generated.cpp +18 -6
- package/codegen/rnwcoreJSI.h +27 -9
- package/package.json +13 -13
- package/src/private/featureflags/NativeReactNativeFeatureFlags.js +4 -2
- package/src/private/featureflags/ReactNativeFeatureFlags.js +16 -6
|
@@ -1966,6 +1966,12 @@ winrt::Microsoft::UI::Composition::ICompositionSurface MicrosoftCompositionConte
|
|
|
1966
1966
|
surface.try_as(s);
|
|
1967
1967
|
return s ? s->Inner() : nullptr;
|
|
1968
1968
|
}
|
|
1969
|
+
|
|
1970
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IBrush MicrosoftCompositionContextHelper::WrapBrush(
|
|
1971
|
+
const winrt::Microsoft::UI::Composition::CompositionBrush &brush) noexcept {
|
|
1972
|
+
return winrt::make<::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompBrush>(brush);
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1969
1975
|
#endif
|
|
1970
1976
|
|
|
1971
1977
|
} // namespace winrt::Microsoft::ReactNative::Composition::Experimental::implementation
|
|
@@ -45,6 +45,8 @@ struct MicrosoftCompositionContextHelper : MicrosoftCompositionContextHelperT<Mi
|
|
|
45
45
|
static winrt::Microsoft::UI::Composition::DropShadow InnerDropShadow(IDropShadow shadow) noexcept;
|
|
46
46
|
static winrt::Microsoft::UI::Composition::CompositionBrush InnerBrush(IBrush brush) noexcept;
|
|
47
47
|
static winrt::Microsoft::UI::Composition::ICompositionSurface InnerSurface(IDrawingSurfaceBrush surface) noexcept;
|
|
48
|
+
|
|
49
|
+
static IBrush WrapBrush(const winrt::Microsoft::UI::Composition::CompositionBrush &brush) noexcept;
|
|
48
50
|
};
|
|
49
51
|
#endif
|
|
50
52
|
|
|
@@ -39,9 +39,9 @@ void ImageComponentView::WindowsImageResponseObserver::didReceiveProgress(float
|
|
|
39
39
|
|
|
40
40
|
void ImageComponentView::WindowsImageResponseObserver::didReceiveImage(
|
|
41
41
|
facebook::react::ImageResponse const &imageResponse) const {
|
|
42
|
-
auto
|
|
42
|
+
auto imageResponseImage = std::static_pointer_cast<ImageResponseImage>(imageResponse.getImage());
|
|
43
43
|
m_image->m_reactContext.UIDispatcher().Post(
|
|
44
|
-
[
|
|
44
|
+
[imageResponseImage, image = m_image]() { image->didReceiveImage(imageResponseImage); });
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
void ImageComponentView::WindowsImageResponseObserver::didReceiveFailure() const {
|
|
@@ -83,7 +83,7 @@ void ImageComponentView::ImageLoadStart() noexcept {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
void ImageComponentView::didReceiveImage(const
|
|
86
|
+
void ImageComponentView::didReceiveImage(const std::shared_ptr<ImageResponseImage> &imageResponseImage) noexcept {
|
|
87
87
|
// TODO check for recycled?
|
|
88
88
|
|
|
89
89
|
auto imageEventEmitter = std::static_pointer_cast<facebook::react::ImageEventEmitter const>(m_eventEmitter);
|
|
@@ -99,7 +99,7 @@ void ImageComponentView::didReceiveImage(const winrt::com_ptr<IWICBitmap> &wicbm
|
|
|
99
99
|
assert(uiDispatcher.HasThreadAccess());
|
|
100
100
|
#endif
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
m_imageResponseImage = imageResponseImage;
|
|
103
103
|
ensureDrawingSurface();
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -198,7 +198,8 @@ void ImageComponentView::updateLayoutMetrics(
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
void ImageComponentView::OnRenderingDeviceLost() noexcept {
|
|
201
|
-
|
|
201
|
+
m_drawingSurface = nullptr;
|
|
202
|
+
ensureDrawingSurface();
|
|
202
203
|
}
|
|
203
204
|
|
|
204
205
|
bool ImageComponentView::themeEffectsImage() const noexcept {
|
|
@@ -207,7 +208,8 @@ bool ImageComponentView::themeEffectsImage() const noexcept {
|
|
|
207
208
|
|
|
208
209
|
void ImageComponentView::onThemeChanged() noexcept {
|
|
209
210
|
if (themeEffectsImage()) {
|
|
210
|
-
|
|
211
|
+
m_drawingSurface = nullptr;
|
|
212
|
+
ensureDrawingSurface();
|
|
211
213
|
}
|
|
212
214
|
Super::onThemeChanged();
|
|
213
215
|
}
|
|
@@ -215,10 +217,17 @@ void ImageComponentView::onThemeChanged() noexcept {
|
|
|
215
217
|
void ImageComponentView::ensureDrawingSurface() noexcept {
|
|
216
218
|
assert(m_reactContext.UIDispatcher().HasThreadAccess());
|
|
217
219
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
+
if (!m_imageResponseImage) {
|
|
221
|
+
m_visual.Brush(nullptr);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
UINT width = 0, height = 0;
|
|
226
|
+
if (m_imageResponseImage->m_wicbmp) {
|
|
227
|
+
winrt::check_hresult(m_imageResponseImage->m_wicbmp->GetSize(&width, &height));
|
|
228
|
+
}
|
|
220
229
|
|
|
221
|
-
if (!m_drawingSurface && m_wicbmp) {
|
|
230
|
+
if (!m_drawingSurface && m_imageResponseImage->m_wicbmp) {
|
|
222
231
|
winrt::Windows::Foundation::Size drawingSurfaceSize{static_cast<float>(width), static_cast<float>(height)};
|
|
223
232
|
|
|
224
233
|
const auto imageProps = std::static_pointer_cast<const facebook::react::ImageProps>(m_props);
|
|
@@ -273,6 +282,8 @@ void ImageComponentView::ensureDrawingSurface() noexcept {
|
|
|
273
282
|
}
|
|
274
283
|
|
|
275
284
|
m_visual.Brush(m_drawingSurface);
|
|
285
|
+
} else if (m_imageResponseImage->m_brushFactory) {
|
|
286
|
+
m_visual.Brush(m_imageResponseImage->m_brushFactory(m_reactContext.Handle(), m_compContext));
|
|
276
287
|
}
|
|
277
288
|
}
|
|
278
289
|
|
|
@@ -286,7 +297,7 @@ void ImageComponentView::DrawImage() noexcept {
|
|
|
286
297
|
return;
|
|
287
298
|
}
|
|
288
299
|
|
|
289
|
-
if (!m_wicbmp) {
|
|
300
|
+
if (!m_imageResponseImage->m_wicbmp) {
|
|
290
301
|
return;
|
|
291
302
|
}
|
|
292
303
|
|
|
@@ -295,7 +306,8 @@ void ImageComponentView::DrawImage() noexcept {
|
|
|
295
306
|
::Microsoft::ReactNative::Composition::AutoDrawDrawingSurface autoDraw(m_drawingSurface, 1.0f, &offset);
|
|
296
307
|
if (auto d2dDeviceContext = autoDraw.GetRenderTarget()) {
|
|
297
308
|
winrt::com_ptr<ID2D1Bitmap1> bitmap;
|
|
298
|
-
winrt::check_hresult(
|
|
309
|
+
winrt::check_hresult(
|
|
310
|
+
d2dDeviceContext->CreateBitmapFromWicBitmap(m_imageResponseImage->m_wicbmp.get(), nullptr, bitmap.put()));
|
|
299
311
|
|
|
300
312
|
d2dDeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f));
|
|
301
313
|
if (m_props->backgroundColor) {
|
|
@@ -311,7 +323,8 @@ void ImageComponentView::DrawImage() noexcept {
|
|
|
311
323
|
if (useEffects) {
|
|
312
324
|
winrt::com_ptr<ID2D1Effect> bitmapEffects;
|
|
313
325
|
winrt::check_hresult(d2dDeviceContext->CreateEffect(CLSID_D2D1BitmapSource, bitmapEffects.put()));
|
|
314
|
-
winrt::check_hresult(
|
|
326
|
+
winrt::check_hresult(
|
|
327
|
+
bitmapEffects->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, m_imageResponseImage->m_wicbmp.get()));
|
|
315
328
|
|
|
316
329
|
if (imageProps->blurRadius > 0) {
|
|
317
330
|
winrt::com_ptr<ID2D1Effect> gaussianBlurEffect;
|
|
@@ -360,7 +373,7 @@ void ImageComponentView::DrawImage() noexcept {
|
|
|
360
373
|
}
|
|
361
374
|
} else {
|
|
362
375
|
UINT width, height;
|
|
363
|
-
winrt::check_hresult(m_wicbmp->GetSize(&width, &height));
|
|
376
|
+
winrt::check_hresult(m_imageResponseImage->m_wicbmp->GetSize(&width, &height));
|
|
364
377
|
|
|
365
378
|
D2D1_RECT_F rect = D2D1::RectF(
|
|
366
379
|
static_cast<float>(offset.x),
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include <winrt/Windows.UI.Composition.h>
|
|
15
15
|
#include "CompositionHelpers.h"
|
|
16
16
|
#include "CompositionViewComponentView.h"
|
|
17
|
+
#include "ImageResponseImage.h"
|
|
17
18
|
|
|
18
19
|
#pragma warning(push)
|
|
19
20
|
#pragma warning(disable : 4244 4305)
|
|
@@ -83,7 +84,7 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
|
|
|
83
84
|
|
|
84
85
|
void ImageLoadStart() noexcept;
|
|
85
86
|
void ImageLoaded() noexcept;
|
|
86
|
-
void didReceiveImage(const
|
|
87
|
+
void didReceiveImage(const std::shared_ptr<ImageResponseImage> &wicbmp) noexcept;
|
|
87
88
|
void didReceiveFailureFromObserver() noexcept;
|
|
88
89
|
void setStateAndResubscribeImageResponseObserver(
|
|
89
90
|
facebook::react::ImageShadowNode::ConcreteState::Shared const &state) noexcept;
|
|
@@ -93,7 +94,7 @@ struct ImageComponentView : ImageComponentViewT<ImageComponentView, ComponentVie
|
|
|
93
94
|
|
|
94
95
|
winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_visual{nullptr};
|
|
95
96
|
winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush m_drawingSurface;
|
|
96
|
-
|
|
97
|
+
std::shared_ptr<ImageResponseImage> m_imageResponseImage;
|
|
97
98
|
std::shared_ptr<WindowsImageResponseObserver> m_imageResponseObserver;
|
|
98
99
|
facebook::react::ImageShadowNode::ConcreteState::Shared m_state;
|
|
99
100
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include <wincodec.h>
|
|
8
|
+
#include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
|
|
9
|
+
|
|
10
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
11
|
+
|
|
12
|
+
struct ImageResponseImage {
|
|
13
|
+
winrt::com_ptr<IWICBitmap> m_wicbmp;
|
|
14
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory m_brushFactory{nullptr};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "pch.h"
|
|
5
|
+
#include "UriImageManager.h"
|
|
6
|
+
|
|
7
|
+
#include "Composition.ImageSource.g.h"
|
|
8
|
+
#include <AutoDraw.h>
|
|
9
|
+
#include <ReactPropertyBag.h>
|
|
10
|
+
#include <d2d1_3.h>
|
|
11
|
+
#include <shcore.h>
|
|
12
|
+
#include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
|
|
13
|
+
#include <winrt/Windows.Security.Cryptography.h>
|
|
14
|
+
#include <winrt/Windows.Storage.Streams.h>
|
|
15
|
+
|
|
16
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
17
|
+
|
|
18
|
+
struct ImageSource : ImageSourceT<ImageSource> {
|
|
19
|
+
ImageSource(const facebook::react::ImageSource &source)
|
|
20
|
+
: m_size({source.size.width, source.size.height}),
|
|
21
|
+
m_scale(source.scale),
|
|
22
|
+
m_uri(::Microsoft::ReactNative::UriTryCreate(winrt::to_hstring(source.uri))) {}
|
|
23
|
+
|
|
24
|
+
winrt::Windows::Foundation::Uri Uri() noexcept {
|
|
25
|
+
return m_uri;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
winrt::Windows::Foundation::Size Size() noexcept {
|
|
29
|
+
return m_size;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
float Scale() noexcept {
|
|
33
|
+
return m_scale;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private:
|
|
37
|
+
const winrt::Windows::Foundation::Uri m_uri;
|
|
38
|
+
const winrt::Windows::Foundation::Size m_size;
|
|
39
|
+
const float m_scale;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
winrt::Microsoft::ReactNative::Composition::ImageSource MakeImageSource(
|
|
43
|
+
const facebook::react::ImageSource &source) noexcept {
|
|
44
|
+
return winrt::make<ImageSource>(source);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* This ImageHandler will handle uri types with svgxaml base64 encoded data
|
|
49
|
+
*
|
|
50
|
+
* <Image
|
|
51
|
+
* style={{width: 400, height: 200}}
|
|
52
|
+
* source={{uri:
|
|
53
|
+
* 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4gPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTEzLjEyNSAwSDBWMTMuMTI1SDEzLjEyNVYwWiIgZmlsbD0iI0YyNTAyMiI+PC9wYXRoPjxwYXRoIGQ9Ik0yOCAwSDE0Ljg3NVYxMy4xMjVIMjhWMFoiIGZpbGw9IiM3RkJBMDAiPjwvcGF0aD48cGF0aCBkPSJNMTMuMTI1IDE0Ljg3NUgwVjI4SDEzLjEyNVYxNC44NzVaIiBmaWxsPSIjMDBBNEVGIj48L3BhdGg+PHBhdGggZD0iTTI4IDE0Ljg3NUgxNC44NzVWMjhIMjhWMTQuODc1WiIgZmlsbD0iI0ZGQjkwMCI+PC9wYXRoPjwvc3ZnPiA='}}
|
|
54
|
+
* />
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
struct SvgDataImageHandler : winrt::implements<
|
|
58
|
+
SvgDataImageHandler,
|
|
59
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::IUriBrushProvider,
|
|
60
|
+
winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
|
|
61
|
+
bool CanLoadImageUri(winrt::Microsoft::ReactNative::IReactContext context, winrt::Windows::Foundation::Uri uri) {
|
|
62
|
+
return uri.SchemeName() == L"data" && std::wstring_view(uri.Path()).starts_with(L"image/svg+xml;base64,");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
winrt::Windows::Foundation::IAsyncOperation<winrt::Microsoft::ReactNative::Composition::Experimental::UriBrushFactory>
|
|
66
|
+
GetSourceAsync(
|
|
67
|
+
const winrt::Microsoft::ReactNative::IReactContext &context,
|
|
68
|
+
const winrt::Microsoft::ReactNative::Composition::ImageSource &imageSource) {
|
|
69
|
+
auto path = winrt::to_string(imageSource.Uri().Path());
|
|
70
|
+
auto size = imageSource.Size();
|
|
71
|
+
auto scale = imageSource.Scale();
|
|
72
|
+
|
|
73
|
+
size_t start = path.find(',');
|
|
74
|
+
if (start == std::string::npos || start + 1 > path.length())
|
|
75
|
+
co_return nullptr;
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
co_await winrt::resume_background();
|
|
79
|
+
|
|
80
|
+
std::string_view base64String(path.c_str() + start + 1, path.length() - start - 1);
|
|
81
|
+
auto buffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::DecodeFromBase64String(
|
|
82
|
+
winrt::to_hstring(base64String));
|
|
83
|
+
|
|
84
|
+
winrt::Windows::Storage::Streams::InMemoryRandomAccessStream memoryStream;
|
|
85
|
+
co_await memoryStream.WriteAsync(buffer);
|
|
86
|
+
memoryStream.Seek(0);
|
|
87
|
+
|
|
88
|
+
co_return
|
|
89
|
+
[memoryStream, size, scale](
|
|
90
|
+
const winrt::Microsoft::ReactNative::IReactContext &reactContext,
|
|
91
|
+
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compositionContext)
|
|
92
|
+
-> winrt::Microsoft::ReactNative::Composition::Experimental::IBrush {
|
|
93
|
+
auto drawingBrush = compositionContext.CreateDrawingSurfaceBrush(
|
|
94
|
+
size,
|
|
95
|
+
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
|
|
96
|
+
winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
|
|
97
|
+
POINT pt;
|
|
98
|
+
::Microsoft::ReactNative::Composition::AutoDrawDrawingSurface autoDraw(drawingBrush, 1.0, &pt);
|
|
99
|
+
auto renderTarget = autoDraw.GetRenderTarget();
|
|
100
|
+
|
|
101
|
+
winrt::com_ptr<ID2D1DeviceContext5> deviceContext5;
|
|
102
|
+
winrt::check_hresult(renderTarget->QueryInterface(IID_ID2D1DeviceContext5, deviceContext5.put_void()));
|
|
103
|
+
|
|
104
|
+
winrt::com_ptr<IStream> nativeStream;
|
|
105
|
+
|
|
106
|
+
winrt::check_hresult(CreateStreamOverRandomAccessStream(
|
|
107
|
+
memoryStream.as<::IUnknown>().get(), IID_PPV_ARGS(nativeStream.put())));
|
|
108
|
+
|
|
109
|
+
winrt::com_ptr<ID2D1SvgDocument> svgDocument;
|
|
110
|
+
if (FAILED(deviceContext5->CreateSvgDocument(
|
|
111
|
+
nativeStream.get(), {size.Width, size.Height}, svgDocument.put()))) {
|
|
112
|
+
return nullptr;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
D2D1::Matrix3x2F originalTransform;
|
|
116
|
+
D2D1::Matrix3x2F translationTransform =
|
|
117
|
+
D2D1::Matrix3x2F::Translation(static_cast<float>(pt.x), static_cast<float>(pt.y));
|
|
118
|
+
|
|
119
|
+
renderTarget->GetTransform(&originalTransform);
|
|
120
|
+
translationTransform = originalTransform * translationTransform;
|
|
121
|
+
|
|
122
|
+
renderTarget->SetTransform(translationTransform);
|
|
123
|
+
|
|
124
|
+
deviceContext5->DrawSvgDocument(svgDocument.get());
|
|
125
|
+
|
|
126
|
+
renderTarget->SetTransform(originalTransform);
|
|
127
|
+
|
|
128
|
+
return drawingBrush;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
} catch (winrt::hresult_error const &) {
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
co_return nullptr;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* This ImageHandler will handle uri types of base64 encoded data
|
|
140
|
+
*
|
|
141
|
+
* <Image
|
|
142
|
+
* style={{width: 400, height: 200}}
|
|
143
|
+
* source={{uri:
|
|
144
|
+
* 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg=='}}
|
|
145
|
+
* />
|
|
146
|
+
*
|
|
147
|
+
*/
|
|
148
|
+
struct DataImageHandler : winrt::implements<
|
|
149
|
+
DataImageHandler,
|
|
150
|
+
winrt::Microsoft::ReactNative::Composition::IUriImageStreamProvider,
|
|
151
|
+
winrt::Microsoft::ReactNative::Composition::IUriImageProvider> {
|
|
152
|
+
bool CanLoadImageUri(winrt::Microsoft::ReactNative::IReactContext context, winrt::Windows::Foundation::Uri uri) {
|
|
153
|
+
return uri.SchemeName() == L"data";
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream> GetSourceAsync(
|
|
157
|
+
const winrt::Microsoft::ReactNative::IReactContext &context,
|
|
158
|
+
const winrt::Microsoft::ReactNative::Composition::ImageSource &imageSource) {
|
|
159
|
+
auto path = winrt::to_string(imageSource.Uri().Path());
|
|
160
|
+
|
|
161
|
+
size_t start = path.find(',');
|
|
162
|
+
if (start == std::string::npos || start + 1 > path.length())
|
|
163
|
+
co_return nullptr;
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
co_await winrt::resume_background();
|
|
167
|
+
|
|
168
|
+
std::string_view base64String(path.c_str() + start + 1, path.length() - start - 1);
|
|
169
|
+
auto buffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::DecodeFromBase64String(
|
|
170
|
+
winrt::to_hstring(base64String));
|
|
171
|
+
|
|
172
|
+
winrt::Windows::Storage::Streams::InMemoryRandomAccessStream memoryStream;
|
|
173
|
+
co_await memoryStream.WriteAsync(buffer);
|
|
174
|
+
memoryStream.Seek(0);
|
|
175
|
+
|
|
176
|
+
co_return memoryStream;
|
|
177
|
+
} catch (winrt::hresult_error const &) {
|
|
178
|
+
// Base64 decode failed
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
co_return nullptr;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
static const ReactPropertyId<ReactNonAbiValue<std::shared_ptr<UriImageManager>>> &UriImageManagerPropertyId() noexcept {
|
|
186
|
+
static const ReactPropertyId<ReactNonAbiValue<std::shared_ptr<UriImageManager>>> prop{
|
|
187
|
+
L"ReactNative", L"UriImageManager"};
|
|
188
|
+
return prop;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
UriImageManager::UriImageManager() {
|
|
192
|
+
m_providers.push_back(winrt::make<SvgDataImageHandler>());
|
|
193
|
+
m_providers.push_back(winrt::make<DataImageHandler>());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
void UriImageManager::Install(
|
|
197
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties,
|
|
198
|
+
const std::shared_ptr<UriImageManager> &manager) noexcept {
|
|
199
|
+
properties.Set(UriImageManagerPropertyId(), manager);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
std::shared_ptr<UriImageManager> UriImageManager::Get(
|
|
203
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept {
|
|
204
|
+
return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(UriImageManagerPropertyId()).Value();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
void UriImageManager::AddUriImageProvider(const IUriImageProvider &provider) {
|
|
208
|
+
if (!provider)
|
|
209
|
+
winrt::throw_hresult(E_INVALIDARG);
|
|
210
|
+
m_providers.push_back(provider);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
IUriImageProvider UriImageManager::TryGetUriImageProvider(
|
|
214
|
+
const IReactContext &context,
|
|
215
|
+
winrt::Microsoft::ReactNative::Composition::ImageSource &source) noexcept {
|
|
216
|
+
auto uri = source.Uri();
|
|
217
|
+
if (!uri) {
|
|
218
|
+
return nullptr;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
for (auto &provider : m_providers) {
|
|
222
|
+
if (provider.CanLoadImageUri(context, source.Uri())) {
|
|
223
|
+
return provider;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return nullptr;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <ReactPropertyBag.h>
|
|
7
|
+
#include <Utils/ImageUtils.h>
|
|
8
|
+
#include <react/renderer/imagemanager/primitives.h>
|
|
9
|
+
#include <winrt/Microsoft.ReactNative.Composition.h>
|
|
10
|
+
|
|
11
|
+
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
12
|
+
|
|
13
|
+
struct UriImageManager {
|
|
14
|
+
UriImageManager();
|
|
15
|
+
|
|
16
|
+
void AddUriImageProvider(const IUriImageProvider &provider);
|
|
17
|
+
|
|
18
|
+
static void Install(
|
|
19
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties,
|
|
20
|
+
const std::shared_ptr<UriImageManager> &manager) noexcept;
|
|
21
|
+
|
|
22
|
+
static std::shared_ptr<UriImageManager> Get(
|
|
23
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept;
|
|
24
|
+
|
|
25
|
+
IUriImageProvider TryGetUriImageProvider(
|
|
26
|
+
const IReactContext &context,
|
|
27
|
+
winrt::Microsoft::ReactNative::Composition::ImageSource &source) noexcept;
|
|
28
|
+
|
|
29
|
+
private:
|
|
30
|
+
std::vector<IUriImageProvider> m_providers;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
winrt::Microsoft::ReactNative::Composition::ImageSource MakeImageSource(
|
|
34
|
+
const facebook::react::ImageSource &source) noexcept;
|
|
35
|
+
|
|
36
|
+
} // namespace winrt::Microsoft::ReactNative::Composition::implementation
|
|
@@ -330,6 +330,9 @@ void FabricUIManager::initiateTransaction(facebook::react::MountingCoordinator::
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
void FabricUIManager::schedulerDidFinishTransaction(
|
|
333
|
+
const facebook::react::MountingCoordinator::Shared &mountingCoordinator) {}
|
|
334
|
+
|
|
335
|
+
void FabricUIManager::schedulerShouldRenderTransactions(
|
|
333
336
|
const facebook::react::MountingCoordinator::Shared &mountingCoordinator) {
|
|
334
337
|
// Should cache this locally
|
|
335
338
|
|
|
@@ -78,6 +78,8 @@ struct FabricUIManager final : public std::enable_shared_from_this<FabricUIManag
|
|
|
78
78
|
std::unordered_map<facebook::react::SurfaceId, SurfaceInfo> m_surfaceRegistry;
|
|
79
79
|
|
|
80
80
|
// Inherited via SchedulerDelegate
|
|
81
|
+
virtual void schedulerShouldRenderTransactions(
|
|
82
|
+
const facebook::react::MountingCoordinator::Shared &mountingCoordinator) override;
|
|
81
83
|
virtual void schedulerDidFinishTransaction(
|
|
82
84
|
const facebook::react::MountingCoordinator::Shared &mountingCoordinator) override;
|
|
83
85
|
virtual void schedulerDidRequestPreliminaryViewAllocation(
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
namespace facebook {
|
|
10
10
|
namespace react {
|
|
11
11
|
|
|
12
|
-
ImageManager::ImageManager(ContextContainer::Shared const &) {
|
|
13
|
-
|
|
12
|
+
ImageManager::ImageManager(ContextContainer::Shared const &contextContainer) {
|
|
13
|
+
auto reactContext = *contextContainer->find<winrt::Microsoft::ReactNative::ReactContext>("MSRN.ReactContext");
|
|
14
|
+
self_ = new Microsoft::ReactNative::WindowsImageManager(reactContext);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
ImageManager::~ImageManager() {
|