Skip to content

Commit 8011465

Browse files
authored
fix(windows): svgs being rendered blurry when at high dpi (#2640)
# Summary The windows svg rendering pass was always rendering the svg to a bitmap the size of the svg at 100% display scale factor, which would then be stretched at higher scale factors. This meant that the svg would be blurry when running in scale factor systems. With this change the svg will be rendered taking into account the scale factor. I also removed an invalid color="none" property set, which would cause errors when running against a debug D2D instance. - That property had no effect, as it was an invalid property value. -- Instead we just leave the property unset when there is no color specified. ## Test Plan Before: ![Screenshot 2025-02-27 110318](https://github.com/user-attachments/assets/aae0cb81-96a3-415e-a908-aa4e46c82a37) After: ![Screenshot 2025-02-27 151859](https://github.com/user-attachments/assets/1ec86957-4a98-41f3-9ba3-4b400c7849f8) ## Checklist <!-- Check completed item, when applicable, via: [X] --> - [x] I have tested this on a device and a simulator - [ ] I added documentation in `README.md` - [ ] I updated the typed files (typescript) - [ ] I added a test for the API in the `__tests__` folder
1 parent 817af7f commit 8011465

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

windows/RNSVG/Fabric/SvgView.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,7 @@ void SvgView::Draw(
268268
if (m_props->color) {
269269
spRoot->SetAttributeValue(
270270
SvgStrings::colorAttributeName, D2DHelpers::AsD2DColor(m_props->color.AsWindowsColor(Theme())));
271-
} else
272-
spRoot->SetAttributeValue(
273-
SvgStrings::colorAttributeName,
274-
D2D1_SVG_ATTRIBUTE_STRING_TYPE::D2D1_SVG_ATTRIBUTE_STRING_TYPE_SVG,
275-
SvgStrings::noneAttributeValue);
271+
}
276272

277273
if (m_props->align != std::nullopt || m_props->meetOrSlice != std::nullopt) {
278274
D2D1_SVG_PRESERVE_ASPECT_RATIO preserveAspectRatio;
@@ -304,7 +300,7 @@ winrt::Microsoft::ReactNative::Composition::Theme SvgView::Theme() const noexcep
304300

305301
void SvgView::Invalidate() {
306302
if (auto view = m_wkView.get()) {
307-
auto size = winrt::Windows::Foundation::Size{m_layoutMetrics.Frame.Width, m_layoutMetrics.Frame.Height};
303+
auto size = winrt::Windows::Foundation::Size{ m_layoutMetrics.Frame.Width, m_layoutMetrics.Frame.Height };
308304

309305
if (!m_isMounted) {
310306
return;
@@ -315,7 +311,7 @@ void SvgView::Invalidate() {
315311
}
316312

317313
auto drawingSurface = m_compContext.CreateDrawingSurfaceBrush(
318-
size,
314+
{ m_layoutMetrics.Frame.Width * m_layoutMetrics.PointScaleFactor, m_layoutMetrics.Frame.Height * m_layoutMetrics.PointScaleFactor },
319315
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
320316
winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
321317

@@ -324,15 +320,24 @@ void SvgView::Invalidate() {
324320
::Microsoft::ReactNative::Composition::AutoDrawDrawingSurface autoDraw(drawingSurface, 1.0, &offset);
325321
if (auto deviceContext = autoDraw.GetRenderTarget()) {
326322
auto transform =
327-
winrt::Windows::Foundation::Numerics::make_float3x2_translation({static_cast<float>(offset.x), static_cast<float>(offset.y)});
323+
winrt::Windows::Foundation::Numerics::make_float3x2_translation({static_cast<float>(offset.x / m_layoutMetrics.PointScaleFactor), static_cast<float>(offset.y / m_layoutMetrics.PointScaleFactor)});
328324
deviceContext->SetTransform(D2DHelpers::AsD2DTransform(transform));
329325

330326
deviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f));
331327

332328
com_ptr<ID2D1DeviceContext> spDeviceContext;
333329
spDeviceContext.copy_from(deviceContext);
334330

331+
const auto dpi = m_layoutMetrics.PointScaleFactor * 96.0f;
332+
float oldDpiX, oldDpiY;
333+
deviceContext->GetDpi(&oldDpiX, &oldDpiY);
334+
deviceContext->SetDpi(dpi, dpi);
335+
335336
Draw(view, *spDeviceContext, size);
337+
338+
// restore dpi to old state
339+
deviceContext->SetDpi(oldDpiX, oldDpiY);
340+
336341
}
337342
}
338343

0 commit comments

Comments
 (0)