Rebased ref, commits from common ancestor:
commit d3c22b713a37126b9a736520da35c7bb2616ea30
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Apr 25 12:47:57 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Mon Apr 25 12:48:19 2022 +0200

    Add branch info to README.md
    
    Change-Id: I94e48d767e2717bef55195e81ff6938fd2b746be

diff --git a/README.md b/README.md
index 96fde564a842..bbe872b7eedb 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,17 @@
+# Branch info
+
+This basically tries to fix tdf#141578. So every frame gets some scaling 
factor.
+Same for all the stuff buffering some output. The main functionality is 
extending
+SalGeometryProvider and then inheriting it from various classes.
+
+Problems:
+  * Refresh layout when moving a window to a screen with different scaling
+  * In theory, the SalEvent::Resize is sufficient, but an extra 
SalEvent::ScaleChanged should be better
+  * VirtualDevices are independent. These need to be created with a reference 
window
+  * A lot of code uses "Application::GetDefaultDevice()"
+  * The font preview can just cache a single scale size.
+
+
 # LibreOffice
 [![Coverity Scan Build 
Status](https://scan.coverity.com/projects/211/badge.svg)](https://scan.coverity.com/projects/211)
 [![CII Best 
Practices](https://bestpractices.coreinfrastructure.org/projects/307/badge)](https://bestpractices.coreinfrastructure.org/projects/307)
 [![Translation 
status](https://weblate.documentfoundation.org/widgets/libo_ui-master/-/svg-badge.svg)](https://weblate.documentfoundation.org/engage/libo_ui-master/?utm_source=widget)
 
commit b8101f62822fca4cfd1e90e1f7d7df5cc781e14b
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Apr 25 12:15:17 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Mon Apr 25 12:48:19 2022 +0200

    more work

diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx
index 6ac1588597fb..570c3075869c 100644
--- a/vcl/inc/qt5/QtInstance.hxx
+++ b/vcl/inc/qt5/QtInstance.hxx
@@ -112,9 +112,10 @@ public:
 
     void RunInMainThread(std::function<void()> func);
 
-    virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window&) override;
-    virtual SalFrame* CreateChildFrame(SystemParentData* pParent,
-                                       SalFrameStyleFlags nStyle, 
vcl::Window&) override;
+    virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle,
+                                  vcl::Window&) override;
+    virtual SalFrame* CreateChildFrame(SystemParentData* pParent, 
SalFrameStyleFlags nStyle,
+                                       vcl::Window&) override;
     virtual void DestroyFrame(SalFrame* pFrame) override;
 
     virtual SalObject* CreateObject(SalFrame* pParent, SystemWindowData* 
pWindowData,
diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx
index 1234cbc0c9ec..1fb5d9de0489 100644
--- a/vcl/qt5/QtInstance.cxx
+++ b/vcl/qt5/QtInstance.cxx
@@ -297,7 +297,8 @@ void QtInstance::localeChanged()
 
 void QtInstance::deleteObjectLater(QObject* pObject) { pObject->deleteLater(); 
}
 
-SalFrame* QtInstance::CreateChildFrame(SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle, vcl::Window& rWin)
+SalFrame* QtInstance::CreateChildFrame(SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle,
+                                       vcl::Window& rWin)
 {
     SalFrame* pRet(nullptr);
     RunInMainThread([&, this]() { pRet = new QtFrame(nullptr, nStyle, rWin, 
useCairo()); });
@@ -310,8 +311,9 @@ SalFrame* QtInstance::CreateFrame(SalFrame* pParent, 
SalFrameStyleFlags nStyle,
     assert(!pParent || dynamic_cast<QtFrame*>(pParent));
 
     SalFrame* pRet(nullptr);
-    RunInMainThread(
-        [&, this]() { pRet = new QtFrame(static_cast<QtFrame*>(pParent), 
nStyle, rWin, useCairo()); });
+    RunInMainThread([&, this]() {
+        pRet = new QtFrame(static_cast<QtFrame*>(pParent), nStyle, rWin, 
useCairo());
+    });
     assert(pRet);
     return pRet;
 }
@@ -344,9 +346,10 @@ void QtInstance::DestroyObject(SalObject* pObject)
     }
 }
 
-std::unique_ptr<SalVirtualDevice>
-QtInstance::CreateVirtualDevice(SalGraphics& rGraphics, sal_Int32& nDX, 
sal_Int32& nDY,
-                                DeviceFormat /*eFormat*/, const 
SystemGraphicsData* pGd)
+std::unique_ptr<SalVirtualDevice> QtInstance::CreateVirtualDevice(SalGraphics& 
rGraphics,
+                                                                  sal_Int32& 
nDX, sal_Int32& nDY,
+                                                                  DeviceFormat 
/*eFormat*/,
+                                                                  const 
SystemGraphicsData* pGd)
 {
     if (m_bUseCairo)
     {
@@ -362,7 +365,8 @@ QtInstance::CreateVirtualDevice(SalGraphics& rGraphics, 
sal_Int32& nDX, sal_Int3
     }
     else
     {
-        std::unique_ptr<SalVirtualDevice> pVD(new QtVirtualDevice(nDX, nDY, 
rGraphics.GetDPIScalePercentage()));
+        std::unique_ptr<SalVirtualDevice> pVD(
+            new QtVirtualDevice(nDX, nDY, rGraphics.GetDPIScalePercentage()));
         return pVD;
     }
 }
diff --git a/vcl/qt5/QtSvpGraphics.cxx b/vcl/qt5/QtSvpGraphics.cxx
index 7b49ff3df806..e978e2a51a42 100644
--- a/vcl/qt5/QtSvpGraphics.cxx
+++ b/vcl/qt5/QtSvpGraphics.cxx
@@ -30,8 +30,8 @@ QtSvpGraphics::QtSvpGraphics(QtFrame* pFrame)
 {
     if (!QtData::noNativeControls())
         m_pWidgetDraw.reset(new QtGraphics_Controls(*this));
-    SAL_DEBUG(__func__ << " " << m_pFrame);
-#if 1
+//    SAL_DEBUG(__func__ << " " << m_pFrame);
+#if 0
     if (m_pFrame)
        SAL_DEBUG(__func__ << " " << m_pFrame->devicePixelRatioF());
 //        setDevicePixelRatioF(m_pFrame->devicePixelRatioF());
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index a8f2be7a15e6..faa39ed8242c 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -202,7 +202,6 @@ void QtWidget::mouseMoveEvent(QMouseEvent* pEvent)
     SalMouseEvent aEvent;
     FILL_SAME(m_rFrame, width());
 
-    SAL_DEBUG(this << " " << __func__ << " " << Point(aEvent.mnX, aEvent.mnY));
     aEvent.mnButton = 0;
 
     m_rFrame.CallCallback(SalEvent::MouseMove, &aEvent);
@@ -224,9 +223,6 @@ void QtWidget::handleMouseEnterLeaveEvents(const QtFrame& 
rFrame, QEvent* pQEven
     aEvent.mnCode = GetKeyModCode(QGuiApplication::keyboardModifiers())
                     | GetMouseModCode(QGuiApplication::mouseButtons());
 
-    SAL_DEBUG(pWidget << " " << __func__ << " " << Point(aEvent.mnX, 
aEvent.mnY) << " "
-                      << QGuiApplication::isLeftToRight());
-
     SalEvent nEventType;
     if (pQEvent->type() == QEvent::Enter)
         nEventType = SalEvent::MouseMove;
diff --git a/vcl/source/image/ImplImageTree.cxx 
b/vcl/source/image/ImplImageTree.cxx
index 85e4bf24b1a9..94ccb84d844f 100644
--- a/vcl/source/image/ImplImageTree.cxx
+++ b/vcl/source/image/ImplImageTree.cxx
@@ -75,8 +75,10 @@ sal_Int32 ImageRequestParameters::scalePercentage()
     sal_Int32 aScalePercentage = 100;
     if (!(meFlags & ImageLoadFlags::IgnoreScalingFactor))
     {
+#if 0
        if (mnScalePercentage <= 0)
             SAL_WARN("vcl", "icon requested without percentage!");
+#endif
         if (mnScalePercentage > 0)
             aScalePercentage = mnScalePercentage;
        else
commit d2f73194c5b1b3e04a9d2e2ec8d8b97f74293ba8
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Wed Apr 20 12:27:53 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Mon Apr 25 12:48:19 2022 +0200

    SalGeometryProvider base for scaling

diff --git a/include/vcl/GeometryProvider.hxx b/include/vcl/GeometryProvider.hxx
new file mode 100644
index 000000000000..bbd7d37e2c3d
--- /dev/null
+++ b/include/vcl/GeometryProvider.hxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/dllapi.h>
+#include <tools/gen.hxx>
+
+namespace vcl
+{
+enum class SGPmetric
+{
+    Width = 1,
+    Height,
+    DPIX,
+    DPIY,
+    ScalePercentage,
+    OffScreen,
+    BitCount,
+};
+
+class VCL_DLLPUBLIC SalGeometryProvider
+{
+public:
+    virtual ~SalGeometryProvider();
+
+    sal_Int32 GetWidth() const { return GetSgpMetric(SGPmetric::Width); }
+    sal_Int32 GetHeight() const { return GetSgpMetric(SGPmetric::Height); }
+    sal_Int32 GetDPIX() const { return GetSgpMetric(SGPmetric::DPIX); }
+    sal_Int32 GetDPIY() const { return GetSgpMetric(SGPmetric::DPIY); }
+    sal_Int32 GetDPIScalePercentage() const { return 
GetSgpMetric(SGPmetric::ScalePercentage); }
+    float GetDPIScaleFactor() const { return 
GetSgpMetric(SGPmetric::ScalePercentage) / 100.0f; }
+    bool IsOffScreen() const { return !!GetSgpMetric(SGPmetric::OffScreen); }
+    sal_Int32 GetBitCount() const { return GetSgpMetric(SGPmetric::BitCount); }
+    Size GetSizePixel() const
+    {
+        return Size(GetSgpMetric(SGPmetric::Width), 
GetSgpMetric(SGPmetric::Height));
+    }
+
+    virtual sal_Int32 GetSgpMetric(SGPmetric eMetric) const = 0;
+};
+
+struct VCL_DLLPUBLIC SalSgpMetrics
+{
+    sal_Int32 m_nWidth = 1;
+    sal_Int32 m_nHeight = 1;
+    sal_Int32 mnDPIX = 96;
+    sal_Int32 mnDPIY = 96;
+    sal_Int32 mnDPIScalePercentage = 100;
+    bool m_bOffScreen = false;
+    sal_Int32 mnBitCount = 32;
+};
+
+class VCL_DLLPUBLIC SalGeometryProviderImpl : public SalGeometryProvider, 
protected SalSgpMetrics
+{
+public:
+    SalGeometryProviderImpl() = default;
+
+    virtual sal_Int32 GetSgpMetric(SGPmetric eMetric) const override;
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 7dacb68d55ad..4c2277c1830c 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -32,6 +32,7 @@
 #include <vcl/devicecoordinate.hxx>
 #include <vcl/dllapi.h>
 #include <vcl/font.hxx>
+#include <vcl/GeometryProvider.hxx>
 #include <vcl/region.hxx>
 #include <vcl/rendercontext/AddFontSubstituteFlags.hxx>
 #include <vcl/rendercontext/AntialiasingFlags.hxx>
@@ -172,14 +173,16 @@ typedef struct _cairo_surface cairo_surface_t;
 * so we need to use virtual inheritance to keep the referencing counting
 * OK.
 */
-class SAL_WARN_UNUSED VCL_DLLPUBLIC OutputDevice : public virtual 
VclReferenceBase
+class SAL_WARN_UNUSED VCL_DLLPUBLIC OutputDevice
+    : public virtual VclReferenceBase
+    , public vcl::SalGeometryProviderImpl
 {
     friend class Printer;
     friend class VirtualDevice;
     friend class vcl::Window;
     friend class vcl::WindowOutputDevice;
     friend class WorkWindow;
-    friend void ImplHandleResize( vcl::Window* pWindow, tools::Long nNewWidth, 
tools::Long nNewHeight );
+    friend void ImplHandleResize(vcl::Window*, sal_Int32 nNewWidth, sal_Int32 
nNewHeight);
 
 private:
     OutputDevice(const OutputDevice&) = delete;
@@ -213,11 +216,6 @@ private:
     tools::Long                            mnOutOffX;
     /// Output offset for device output in pixel (pseudo window offset within 
window system's frames)
     tools::Long                            mnOutOffY;
-    tools::Long                            mnOutWidth;
-    tools::Long                            mnOutHeight;
-    sal_Int32                       mnDPIX;
-    sal_Int32                       mnDPIY;
-    sal_Int32                       mnDPIScalePercentage; ///< For HiDPI 
displays, we want to draw elements for a percentage larger
     /// font specific text alignment offsets in pixel units
     mutable tools::Long                    mnTextOffX;
     mutable tools::Long                    mnTextOffY;
@@ -316,12 +314,10 @@ public:
 
     virtual bool                IsScreenComp() const { return true; }
 
-    virtual sal_uInt16          GetBitCount() const;
-
-    Size                        GetOutputSizePixel() const
-                                    { return Size( mnOutWidth, mnOutHeight ); }
-    tools::Long                        GetOutputWidthPixel() const { return 
mnOutWidth; }
-    tools::Long                        GetOutputHeightPixel() const { return 
mnOutHeight; }
+    void SetGeometrySize(sal_Int32, sal_Int32);
+    Size GetOutputSizePixel() const { return GetSizePixel(); }
+    tools::Long GetOutputWidthPixel() const { return m_nWidth; }
+    tools::Long GetOutputHeightPixel() const { return m_nHeight; }
     tools::Long                        GetOutOffXPixel() const { return 
mnOutOffX; }
     tools::Long                        GetOutOffYPixel() const { return 
mnOutOffY; }
     void                        SetOutOffXPixel(tools::Long nOutOffX);
@@ -384,32 +380,9 @@ protected:
     ///@{
 
 public:
-
-    /** Get the output device's DPI x-axis value.
-
-     @returns x-axis DPI value
-     */
-    SAL_DLLPRIVATE sal_Int32    GetDPIX() const { return mnDPIX; }
-
-    /** Get the output device's DPI y-axis value.
-
-     @returns y-axis DPI value
-     */
-    SAL_DLLPRIVATE sal_Int32    GetDPIY() const { return mnDPIY; }
-
     SAL_DLLPRIVATE void         SetDPIX( sal_Int32 nDPIX ) { mnDPIX = nDPIX; }
     SAL_DLLPRIVATE void         SetDPIY( sal_Int32 nDPIY ) { mnDPIY = nDPIY; }
 
-    float GetDPIScaleFactor() const
-    {
-        return mnDPIScalePercentage / 100.0f;
-    }
-
-    sal_Int32 GetDPIScalePercentage() const
-    {
-        return mnDPIScalePercentage;
-    }
-
     OutDevType                  GetOutDevType() const { return meOutDevType; }
     virtual bool IsVirtual() const;
 
diff --git a/include/vcl/virdev.hxx b/include/vcl/virdev.hxx
index 459660eb71cd..966afadfe831 100644
--- a/include/vcl/virdev.hxx
+++ b/include/vcl/virdev.hxx
@@ -48,14 +48,13 @@ private:
     std::unique_ptr<SalVirtualDevice> mpVirDev;
     VclPtr<VirtualDevice>  mpPrev;
     VclPtr<VirtualDevice>  mpNext;
-    sal_uInt16          mnBitCount;
     bool                mbScreenComp;
     const DeviceFormat  meFormat;
     const DeviceFormat  meAlphaFormat;
     RefDevMode          meRefDevMode;
     bool                mbForceZeroExtleadBug;
 
-    SAL_DLLPRIVATE void ImplInitVirDev( const OutputDevice* pOutDev, 
tools::Long nDX, tools::Long nDY, const SystemGraphicsData *pData = nullptr );
+    SAL_DLLPRIVATE void ImplInitVirDev(const OutputDevice* pOutDev, sal_Int32 
nDX, sal_Int32 nDY, const SystemGraphicsData *pData = nullptr );
     SAL_DLLPRIVATE bool InnerImplSetOutputSizePixel( const Size& rNewSize, 
bool bErase,
                                                      sal_uInt8* pBuffer );
     SAL_DLLPRIVATE bool ImplSetOutputSizePixel( const Size& rNewSize, bool 
bErase,
@@ -168,8 +167,6 @@ public:
 
     void                SetReferenceDevice( sal_Int32 i_nDPIX, sal_Int32 
i_nDPIY );
 
-    virtual sal_uInt16  GetBitCount() const override;
-
     bool IsVirtual() const override;
 
     bool                IsScreenComp() const override { return mbScreenComp; }
diff --git a/include/vcl/windowstate.hxx b/include/vcl/windowstate.hxx
index dcf0f4e9a394..6a9de43d18c9 100644
--- a/include/vcl/windowstate.hxx
+++ b/include/vcl/windowstate.hxx
@@ -30,8 +30,8 @@ private:
     WindowStateMask mnValidMask;
     int mnX;
     int mnY;
-    unsigned int mnWidth;
-    unsigned int mnHeight;
+    sal_Int32 mnWidth;
+    sal_Int32 mnHeight;
     int mnMaximizedX;
     int mnMaximizedY;
     unsigned int mnMaximizedWidth;
@@ -60,10 +60,10 @@ public:
     int GetX() const { return mnX; }
     void SetY(int nY) { mnY = nY; }
     int GetY() const { return mnY; }
-    void SetWidth(unsigned int nWidth) { mnWidth = nWidth; }
-    unsigned int GetWidth() const { return mnWidth; }
-    void SetHeight(unsigned int nHeight) { mnHeight = nHeight; }
-    unsigned int GetHeight() const { return mnHeight; }
+    void SetWidth(sal_Int32 nWidth) { mnWidth = nWidth; }
+    sal_Int32 GetWidth() const { return mnWidth; }
+    void SetHeight(sal_Int32 nHeight) { mnHeight = nHeight; }
+    sal_Int32 GetHeight() const { return mnHeight; }
     void SetState(WindowStateState nState) { mnState = nState; }
     WindowStateState GetState() const { return mnState; }
     void SetMaximizedX(int nRX) { mnMaximizedX = nRX; }
diff --git a/svtools/source/control/ctrlbox.cxx 
b/svtools/source/control/ctrlbox.cxx
index d679b7c46160..f17c008fe01b 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -355,6 +355,8 @@ IMPL_LINK(FontNameBox, SettingsChangedHdl, VclSimpleEvent&, 
rEvent, void)
     DataChangedEvent* pData = 
static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(rEvent).GetData());
     if (pData->GetType() == DataChangedEventType::SETTINGS)
     {
+        for (auto &rDev : gFontPreviewVirDevs)
+            rDev.disposeAndClear();
         gFontPreviewVirDevs.clear();
         gRenderedFontNames.clear();
         calcCustomItemSize(*m_xComboBox);
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a141e22348dd..21a5a8fe672a 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -379,6 +379,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/helper/canvasbitmap \
     vcl/source/helper/canvastools \
     vcl/source/helper/commandinfoprovider \
+    vcl/source/helper/geometryprovider \
     vcl/source/helper/displayconnectiondispatch \
     vcl/source/helper/driverblocklist \
     vcl/source/helper/errcode \
diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx
index ca130fb1b19f..5d50531bbd76 100644
--- a/vcl/android/androidinst.cxx
+++ b/vcl/android/androidinst.cxx
@@ -143,12 +143,12 @@ public:
     }
 };
 
-SalFrame *AndroidSalInstance::CreateChildFrame( SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle )
+SalFrame *AndroidSalInstance::CreateChildFrame( SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle, vcl::Window& rWin )
 {
     return new AndroidSalFrame( this, NULL, nStyle );
 }
 
-SalFrame *AndroidSalInstance::CreateFrame( SalFrame* pParent, 
SalFrameStyleFlags nStyle )
+SalFrame *AndroidSalInstance::CreateFrame( SalFrame* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& )
 {
     return new AndroidSalFrame( this, pParent, nStyle );
 }
diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index ab8cdb0b30bc..28b4f9954d16 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -431,8 +431,8 @@ void CairoCommon::releaseCairoContext(cairo_t* cr, bool 
bXorModeAllowed,
     basegfx::B2IRange 
aIntExtents(basegfx::unotools::b2ISurroundingRangeFromB2DRange(rExtents));
     sal_Int32 nExtentsLeft(aIntExtents.getMinX()), 
nExtentsTop(aIntExtents.getMinY());
     sal_Int32 nExtentsRight(aIntExtents.getMaxX()), 
nExtentsBottom(aIntExtents.getMaxY());
-    sal_Int32 nWidth = m_aFrameSize.getX();
-    sal_Int32 nHeight = m_aFrameSize.getY();
+    sal_Int32 nWidth = cairo_image_surface_get_width(m_pSurface);
+    sal_Int32 nHeight = cairo_image_surface_get_height(m_pSurface);
     nExtentsLeft = std::max<sal_Int32>(nExtentsLeft, 0);
     nExtentsTop = std::max<sal_Int32>(nExtentsTop, 0);
     nExtentsRight = std::min<sal_Int32>(nExtentsRight, nWidth);
@@ -467,11 +467,13 @@ void CairoCommon::releaseCairoContext(cairo_t* cr, bool 
bXorModeAllowed,
         cairo_format_t nFormat = 
cairo_image_surface_get_format(target_surface);
         assert(nFormat == CAIRO_FORMAT_ARGB32
                && "need to implement CAIRO_FORMAT_A1 after all here");
-        sal_Int32 nStride = cairo_format_stride_for_width(nFormat, nWidth * 
m_fScale);
-        sal_Int32 nUnscaledExtentsLeft = nExtentsLeft * m_fScale;
-        sal_Int32 nUnscaledExtentsRight = nExtentsRight * m_fScale;
-        sal_Int32 nUnscaledExtentsTop = nExtentsTop * m_fScale;
-        sal_Int32 nUnscaledExtentsBottom = nExtentsBottom * m_fScale;
+        double fScale = 1.0;
+        dl_cairo_surface_get_device_scale(m_pSurface, &fScale, nullptr);
+        sal_Int32 nStride = cairo_format_stride_for_width(nFormat, nWidth * 
fScale);
+        sal_Int32 nUnscaledExtentsLeft = nExtentsLeft * fScale;
+        sal_Int32 nUnscaledExtentsRight = nExtentsRight * fScale;
+        sal_Int32 nUnscaledExtentsTop = nExtentsTop * fScale;
+        sal_Int32 nUnscaledExtentsBottom = nExtentsBottom * fScale;
 
         // Handle headless size forced to (1,1) by 
SvpSalFrame::GetSurfaceFrameSize().
         int target_surface_width = 
cairo_image_surface_get_width(target_surface);
@@ -557,15 +559,19 @@ void CairoCommon::releaseCairoContext(cairo_t* cr, bool 
bXorModeAllowed,
 
 cairo_t* CairoCommon::createTmpCompatibleCairoContext() const
 {
+    double fScale = 1.0;
+    dl_cairo_surface_get_device_scale(m_pSurface, &fScale, nullptr);
+    sal_Int32 nWidth = cairo_image_surface_get_width(m_pSurface);
+    sal_Int32 nHeight = cairo_image_surface_get_height(m_pSurface);
 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
     cairo_surface_t* target = cairo_surface_create_similar_image(
         m_pSurface,
 #else
     cairo_surface_t* target = cairo_image_surface_create(
 #endif
-        CAIRO_FORMAT_ARGB32, m_aFrameSize.getX() * m_fScale, 
m_aFrameSize.getY() * m_fScale);
+        CAIRO_FORMAT_ARGB32, nWidth * fScale, nHeight * fScale);
 
-    dl_cairo_surface_set_device_scale(target, m_fScale, m_fScale);
+    dl_cairo_surface_set_device_scale(target, fScale, fScale);
 
     return cairo_create(target);
 }
@@ -920,10 +926,12 @@ void CairoCommon::copyBitsCairo(const SalTwoRect& rTR, 
cairo_surface_t* pSourceS
     if (pSourceSurface == getSurface())
     {
         //self copy is a problem, so dup source in that case
+        double fScale = 1.0;
+        dl_cairo_surface_get_device_scale(m_pSurface, &fScale, nullptr);
         pCopy
             = cairo_surface_create_similar(pSourceSurface, 
cairo_surface_get_content(getSurface()),
-                                           aTR.mnSrcWidth * m_fScale, 
aTR.mnSrcHeight * m_fScale);
-        dl_cairo_surface_set_device_scale(pCopy, m_fScale, m_fScale);
+                                           aTR.mnSrcWidth * fScale, 
aTR.mnSrcHeight * fScale);
+        dl_cairo_surface_set_device_scale(pCopy, fScale, fScale);
         cairo_t* cr = cairo_create(pCopy);
         cairo_set_source_surface(cr, pSourceSurface, -aTR.mnSrcX, -aTR.mnSrcY);
         cairo_rectangle(cr, 0, 0, aTR.mnSrcWidth, aTR.mnSrcHeight);
@@ -1003,12 +1011,14 @@ void CairoCommon::invert(const basegfx::B2DPolygon& 
rPoly, SalInvert nFlags, boo
 
         if (nFlags & SalInvert::N50)
         {
+            double fScale = 1.0;
+            dl_cairo_surface_get_device_scale(m_pSurface, &fScale, nullptr);
             cairo_pattern_t* pattern = create_stipple();
             cairo_surface_t* surface = cairo_surface_create_similar(
-                m_pSurface, cairo_surface_get_content(m_pSurface), 
extents.getWidth() * m_fScale,
-                extents.getHeight() * m_fScale);
+                m_pSurface, cairo_surface_get_content(m_pSurface), 
extents.getWidth() * fScale,
+                extents.getHeight() * fScale);
 
-            dl_cairo_surface_set_device_scale(surface, m_fScale, m_fScale);
+            dl_cairo_surface_set_device_scale(surface, fScale, fScale);
             cairo_t* stipple_cr = cairo_create(surface);
             cairo_set_source_rgb(stipple_cr, 1.0, 1.0, 1.0);
             cairo_mask(stipple_cr, pattern);
diff --git a/vcl/headless/SvpGraphicsBackend.cxx 
b/vcl/headless/SvpGraphicsBackend.cxx
index 223b333e9bef..37ffc7b981a6 100644
--- a/vcl/headless/SvpGraphicsBackend.cxx
+++ b/vcl/headless/SvpGraphicsBackend.cxx
@@ -51,7 +51,8 @@ sal_uInt16 SvpGraphicsBackend::GetBitCount() const
 
 tools::Long SvpGraphicsBackend::GetGraphicsWidth() const
 {
-    return m_rCairoCommon.m_pSurface ? m_rCairoCommon.m_aFrameSize.getX() : 0;
+    assert(m_rCairoCommon.m_pSurface);
+    return cairo_image_surface_get_width(m_rCairoCommon.m_pSurface);
 }
 
 void SvpGraphicsBackend::SetLineColor() { m_rCairoCommon.m_aLineColor = 
SALCOLOR_NONE; }
diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx
index c6c8a08e29c0..01729a876080 100644
--- a/vcl/headless/svpframe.cxx
+++ b/vcl/headless/svpframe.cxx
@@ -21,6 +21,7 @@
 #include <o3tl/safeint.hxx>
 #include <vcl/syswin.hxx>
 #include <sal/log.hxx>
+#include <window.h>
 
 #include <headless/svpframe.hxx>
 #include <headless/svpinst.hxx>
@@ -42,7 +43,8 @@ SvpSalFrame* SvpSalFrame::s_pFocusFrame = nullptr;
 
 SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance,
                           SalFrame* pParent,
-                          SalFrameStyleFlags nSalFrameStyle ) :
+                          SalFrameStyleFlags nSalFrameStyle, vcl::Window& rWin)
+    : SalFrame(rWin),
     m_pInstance( pInstance ),
     m_pParent( static_cast<SvpSalFrame*>(pParent) ),
     m_nStyle( nSalFrameStyle ),
@@ -158,7 +160,7 @@ SalGraphics* SvpSalFrame::AcquireGraphics()
 {
     SvpSalGraphics* pGraphics = new SvpSalGraphics();
 #ifndef IOS
-    pGraphics->setSurface(m_pSurface, GetSurfaceFrameSize());
+    pGraphics->setSurface(m_pSurface);
 #endif
     m_aGraphics.push_back( pGraphics );
     return pGraphics;
@@ -254,17 +256,17 @@ void SvpSalFrame::SetPosSize( tools::Long nX, tools::Long 
nY, tools::Long nWidth
     if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 )
     {
         maGeometry.nWidth = nWidth;
-        if( m_nMaxWidth > 0 && maGeometry.nWidth > 
o3tl::make_unsigned(m_nMaxWidth) )
+        if (m_nMaxWidth > 0 && maGeometry.nWidth > m_nMaxWidth)
             maGeometry.nWidth = m_nMaxWidth;
-        if( m_nMinWidth > 0 && maGeometry.nWidth < 
o3tl::make_unsigned(m_nMinWidth) )
+        if (m_nMinWidth > 0 && maGeometry.nWidth < m_nMinWidth)
             maGeometry.nWidth = m_nMinWidth;
     }
     if( (nFlags & SAL_FRAME_POSSIZE_HEIGHT) != 0 )
     {
         maGeometry.nHeight = nHeight;
-        if( m_nMaxHeight > 0 && maGeometry.nHeight > 
o3tl::make_unsigned(m_nMaxHeight) )
+        if (m_nMaxHeight > 0 && maGeometry.nHeight > m_nMaxHeight)
             maGeometry.nHeight = m_nMaxHeight;
-        if( m_nMinHeight > 0 && maGeometry.nHeight < 
o3tl::make_unsigned(m_nMinHeight) )
+        if (m_nMinHeight > 0 && maGeometry.nHeight < m_nMinHeight)
             maGeometry.nHeight = m_nMinHeight;
     }
 #ifndef IOS
@@ -281,16 +283,25 @@ void SvpSalFrame::SetPosSize( tools::Long nX, tools::Long 
nY, tools::Long nWidth
 
         // update device in existing graphics
         for (auto const& graphic : m_aGraphics)
-        {
-             graphic->setSurface(m_pSurface, aFrameSize);
-        }
+             graphic->setSurface(m_pSurface);
     }
     if( m_bVisible )
         m_pInstance->PostEvent( this, nullptr, SalEvent::Resize );
 #endif
 }
 
-void SvpSalFrame::GetClientSize( tools::Long& rWidth, tools::Long& rHeight )
+sal_Int32 SvpSalFrame::GetSgpMetric(vcl::SGPmetric eMetric) const
+{
+    switch (eMetric)
+    {
+        case vcl::SGPmetric::Width: return maGeometry.nWidth;
+        case vcl::SGPmetric::Height: return maGeometry.nHeight;
+        default:
+            return GetWindow()->GetOutDev()->GetSgpMetric(eMetric);
+    }
+}
+
+void SvpSalFrame::GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight)
 {
     rWidth = maGeometry.nWidth;
     rHeight = maGeometry.nHeight;
@@ -510,4 +521,9 @@ void SvpSalFrame::EndSetClipRegion()
 {
 }
 
+void SvpSalFrame::GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY)
+{
+    rDPIX = rDPIY = 96;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 881d42be256c..30244041690e 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -45,17 +45,32 @@ SvpSalGraphics::~SvpSalGraphics()
     ReleaseFonts();
 }
 
-void SvpSalGraphics::setSurface(cairo_surface_t* pSurface, const 
basegfx::B2IVector& rSize)
+void SvpSalGraphics::setSurface(cairo_surface_t* pSurface)
 {
     m_aCairoCommon.m_pSurface = pSurface;
-    m_aCairoCommon.m_aFrameSize = rSize;
-    dl_cairo_surface_get_device_scale(pSurface, &m_aCairoCommon.m_fScale, 
nullptr);
     GetImpl()->ResetClipRegion();
 }
 
-void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
+sal_Int32 SvpSalGraphics::GetSgpMetric(vcl::SGPmetric eMetric) const
 {
-    rDPIX = rDPIY = 96;
+    switch (eMetric)
+    {
+        case vcl::SGPmetric::Width: return 
cairo_image_surface_get_width(m_aCairoCommon.m_pSurface);
+        case vcl::SGPmetric::Height: return 
cairo_image_surface_get_height(m_aCairoCommon.m_pSurface);
+        case vcl::SGPmetric::DPIX:
+        case vcl::SGPmetric::DPIY:
+            return 96 * GetDPIScaleFactor();
+        case vcl::SGPmetric::ScalePercentage:
+        {
+            double fScale;
+            dl_cairo_surface_get_device_scale(m_aCairoCommon.m_pSurface, 
&fScale, nullptr);
+            return round(fScale * 100);
+        }
+        case vcl::SGPmetric::OffScreen: return true;
+        case vcl::SGPmetric::BitCount: return 32;
+        default:
+            return -1;
+    }
 }
 
 #if ENABLE_CAIRO_CANVAS
diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx
index bf53dc24faf3..aa4ae1214d77 100644
--- a/vcl/headless/svpinst.cxx
+++ b/vcl/headless/svpinst.cxx
@@ -216,14 +216,14 @@ bool SvpSalInstance::CheckTimeout( bool bExecuteTimers )
     return bRet;
 }
 
-SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle )
+SalFrame* SvpSalInstance::CreateChildFrame(SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle, vcl::Window& rWin)
 {
-    return new SvpSalFrame( this, nullptr, nStyle );
+    return new SvpSalFrame(this, nullptr, nStyle, rWin);
 }
 
-SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle )
+SalFrame* SvpSalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& rWin)
 {
-    return new SvpSalFrame( this, pParent, nStyle );
+    return new SvpSalFrame(this, pParent, nStyle, rWin);
 }
 
 void SvpSalInstance::DestroyFrame( SalFrame* pFrame )
@@ -244,7 +244,7 @@ void SvpSalInstance::DestroyObject( SalObject* pObject )
 #ifndef IOS
 
 std::unique_ptr<SalVirtualDevice> 
SvpSalInstance::CreateVirtualDevice(SalGraphics& rGraphics,
-                                                       tools::Long &nDX, 
tools::Long &nDY,
+                                                       sal_Int32 &nDX, 
sal_Int32 &nDY,
                                                        DeviceFormat 
/*eFormat*/,
                                                        const 
SystemGraphicsData* pGd)
 {
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
index 76cb53fc1745..2cb14e9d7ee2 100644
--- a/vcl/headless/svpvd.cxx
+++ b/vcl/headless/svpvd.cxx
@@ -48,7 +48,7 @@ SvpSalVirtualDevice::~SvpSalVirtualDevice()
 
 SvpSalGraphics* SvpSalVirtualDevice::AddGraphics(SvpSalGraphics* pGraphics)
 {
-    pGraphics->setSurface(m_pSurface, m_aFrameSize);
+    pGraphics->setSurface(m_pSurface);
     m_aGraphics.push_back(pGraphics);
     return pGraphics;
 }
@@ -64,29 +64,45 @@ void SvpSalVirtualDevice::ReleaseGraphics( SalGraphics* 
pGraphics )
     delete pGraphics;
 }
 
-bool SvpSalVirtualDevice::SetSize( tools::Long nNewDX, tools::Long nNewDY )
+void SvpSalVirtualDevice::SetScalePercentage(sal_Int32 nScale)
 {
-    return SetSizeUsingBuffer(nNewDX, nNewDY, nullptr);
+    CreateSurface(0, 0, nullptr, nScale);
 }
 
-void SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long 
nNewDY, sal_uInt8 *const pBuffer)
+void SvpSalVirtualDevice::CreateSurface(sal_Int32 nNewDX, sal_Int32 nNewDY, 
sal_uInt8 *const pBuffer, sal_Int32 nScalePercentage)
 {
-    if (m_pSurface)
-    {
-        cairo_surface_destroy(m_pSurface);
-    }
-
     double fXScale, fYScale;
-    if (comphelper::LibreOfficeKit::isActive())
-    {
-        // Force scaling of the painting
-        fXScale = fYScale = comphelper::LibreOfficeKit::getDPIScale();
-    }
+    if (nScalePercentage > 0)
+        fXScale = fYScale = nScalePercentage / 100.0;
     else
+        fXScale = fYScale = GetDPIScaleFactor();
+
+    if (nNewDX <= 0 || nNewDY <= 0)
     {
-        dl_cairo_surface_get_device_scale(m_pRefSurface, &fXScale, &fYScale);
+        if (nScalePercentage > 0 && m_pSurface)
+        {
+            dl_cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
+            return;
+        }
+
+        if (pBuffer && !m_pSurface)
+        {
+            SAL_WARN("vcl", "Trying to set buffer without sizes or surface!");
+            return;
+        }
+
+        if (m_pSurface)
+        {
+            nNewDX = cairo_image_surface_get_width(m_pSurface);
+            nNewDY = cairo_image_surface_get_height(m_pSurface);
+        }
+        else
+            nNewDX = nNewDY = 1;
     }
 
+    if (m_pSurface)
+        cairo_surface_destroy(m_pSurface);
+
     if (pBuffer)
     {
         nNewDX *= fXScale;
@@ -117,39 +133,49 @@ void SvpSalVirtualDevice::CreateSurface(tools::Long 
nNewDX, tools::Long nNewDY,
     SAL_WARN_IF(cairo_surface_status(m_pSurface) != CAIRO_STATUS_SUCCESS, 
"vcl", "surface of size " << nNewDX << " by " << nNewDY << " creation failed 
with status of: " << cairo_status_to_string(cairo_surface_status(m_pSurface)));
 }
 
-bool SvpSalVirtualDevice::SetSizeUsingBuffer( tools::Long nNewDX, tools::Long 
nNewDY,
-        sal_uInt8 *const pBuffer)
+bool SvpSalVirtualDevice::SetSizeUsingBuffer(sal_Int32 nNewDX, sal_Int32 
nNewDY, sal_uInt8 *const pBuffer, sal_Int32 nScale)
 {
-    if (nNewDX == 0)
-        nNewDX = 1;
-    if (nNewDY == 0)
-        nNewDY = 1;
-
-    if (!m_pSurface || m_aFrameSize.getX() != nNewDX ||
-                       m_aFrameSize.getY() != nNewDY)
+    FixSetSizeParams(nNewDX, nNewDY, nScale);
+    if (!m_pSurface || cairo_image_surface_get_width(m_pSurface) != nNewDX ||
+                       cairo_image_surface_get_height(m_pSurface) != nNewDY)
     {
-        m_aFrameSize = basegfx::B2IVector(nNewDX, nNewDY);
-
         if (m_bOwnsSurface)
-            CreateSurface(nNewDX, nNewDY, pBuffer);
+            CreateSurface(nNewDX, nNewDY, pBuffer, nScale);
 
         assert(m_pSurface);
 
         // update device in existing graphics
         for (auto const& graphic : m_aGraphics)
-            graphic->setSurface(m_pSurface, m_aFrameSize);
+            graphic->setSurface(m_pSurface);
     }
     return true;
 }
 
-tools::Long SvpSalVirtualDevice::GetWidth() const
+sal_Int32 SvpSalVirtualDevice::GetSgpMetric(vcl::SGPmetric eMetric) const
 {
-    return m_pSurface ? m_aFrameSize.getX() : 0;
-}
-
-tools::Long SvpSalVirtualDevice::GetHeight() const
-{
-    return m_pSurface ? m_aFrameSize.getY() : 0;
+    switch (eMetric)
+    {
+        case vcl::SGPmetric::Width: return m_pSurface ? 
cairo_image_surface_get_width(m_pSurface) : 1;
+        case vcl::SGPmetric::Height: return m_pSurface ? 
cairo_image_surface_get_height(m_pSurface) : 1;
+        case vcl::SGPmetric::DPIX:
+        case vcl::SGPmetric::DPIY:
+            return 96 * GetSgpMetric(vcl::SGPmetric::ScalePercentage);
+        case vcl::SGPmetric::ScalePercentage:
+        {
+            double fXScale, fYScale;
+            if (m_pSurface)
+                dl_cairo_surface_get_device_scale(m_pSurface, &fXScale, 
&fYScale);
+            else if (comphelper::LibreOfficeKit::isActive())
+                fXScale = comphelper::LibreOfficeKit::getDPIScale();
+            else
+                fXScale = 1.0;
+            return round(fXScale * 100);
+        }
+        case vcl::SGPmetric::OffScreen: return true;
+        case vcl::SGPmetric::BitCount: return 32;
+        default:
+            return -1;
+    }
 }
 
 #endif
diff --git a/vcl/inc/android/androidinst.hxx b/vcl/inc/android/androidinst.hxx
index 771eb4b1ed81..889a49264dca 100644
--- a/vcl/inc/android/androidinst.hxx
+++ b/vcl/inc/android/androidinst.hxx
@@ -37,8 +37,8 @@ public:
 
     // frame management
     void GetWorkArea(tools::Rectangle& rRect);
-    SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle);
-    SalFrame* CreateChildFrame(SystemParentData* pParent, SalFrameStyleFlags 
nStyle);
+    SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle, 
vcl::Window&);
+    SalFrame* CreateChildFrame(SystemParentData* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& rWin);
 
     // mainloop pieces
     virtual bool AnyInput(VclInputFlags nType);
diff --git a/vcl/inc/headless/CairoCommon.hxx b/vcl/inc/headless/CairoCommon.hxx
index e8b1a4927e21..56271a450224 100644
--- a/vcl/inc/headless/CairoCommon.hxx
+++ b/vcl/inc/headless/CairoCommon.hxx
@@ -147,19 +147,16 @@ struct VCL_DLLPUBLIC DamageHandler
 struct VCL_DLLPUBLIC CairoCommon
 {
     cairo_surface_t* m_pSurface;
-    basegfx::B2IVector m_aFrameSize;
     vcl::Region m_aClipRegion;
     Color m_aLineColor;
     Color m_aFillColor;
     PaintMode m_ePaintMode;
-    double m_fScale;
 
     CairoCommon()
         : m_pSurface(nullptr)
         , m_aLineColor(Color(0x00, 0x00, 0x00))
         , m_aFillColor(Color(0xFF, 0xFF, 0XFF))
         , m_ePaintMode(PaintMode::Over)
-        , m_fScale(1.0)
     {
     }
 
diff --git a/vcl/inc/headless/svpframe.hxx b/vcl/inc/headless/svpframe.hxx
index 84dca0c84cdc..a6125543f6f2 100644
--- a/vcl/inc/headless/svpframe.hxx
+++ b/vcl/inc/headless/svpframe.hxx
@@ -57,9 +57,7 @@ class SvpSalFrame : public SalFrame
     OUString m_sTitle;
 
 public:
-    SvpSalFrame( SvpSalInstance* pInstance,
-                 SalFrame* pParent,
-                 SalFrameStyleFlags nSalFrameStyle );
+    SvpSalFrame(SvpSalInstance*, SalFrame* pParent, SalFrameStyleFlags, 
vcl::Window&);
     virtual ~SvpSalFrame() override;
 
     void GetFocus();
@@ -87,7 +85,8 @@ public:
     virtual void                SetMinClientSize( tools::Long nWidth, 
tools::Long nHeight ) override;
     virtual void                SetMaxClientSize( tools::Long nWidth, 
tools::Long nHeight ) override;
     virtual void                SetPosSize( tools::Long nX, tools::Long nY, 
tools::Long nWidth, tools::Long nHeight, sal_uInt16 nFlags ) override;
-    virtual void                GetClientSize( tools::Long& rWidth, 
tools::Long& rHeight ) override;
+    virtual void GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+    virtual void GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight) override;
     virtual void                GetWorkArea( tools::Rectangle& rRect ) 
override;
     virtual SalFrame*           GetParent() const override;
     virtual void                SetWindowState( const SalFrameState* pState ) 
override;
@@ -123,6 +122,8 @@ public:
     virtual void                SetScreenNumber( unsigned int ) override {}
     virtual void                SetApplicationID(const OUString &) override {}
 
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
+
 private:
     basegfx::B2IVector GetSurfaceFrameSize() const;
 };
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index a63e7f289abf..fbfc452eb862 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -47,7 +47,7 @@ class VCL_DLLPUBLIC SvpSalGraphics : public 
SalGraphicsAutoDelegateToImpl
     CairoCommon m_aCairoCommon;
 
 public:
-    void setSurface(cairo_surface_t* pSurface, const basegfx::B2IVector& 
rSize);
+    void setSurface(cairo_surface_t* pSurface);
     cairo_surface_t* getSurface() const { return m_aCairoCommon.m_pSurface; }
     static cairo_user_data_key_t* getDamageKey()
     {
@@ -67,7 +67,7 @@ public:
     virtual SalGraphicsImpl* GetImpl() const override { return 
m_pBackend.get(); }
     std::unique_ptr<SvpGraphicsBackend> const& getSvpBackend() { return 
m_pBackend; }
 
-    virtual void            GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY 
) override;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
 
     virtual void            SetTextColor( Color nColor ) override;
     virtual void            SetFont(LogicalFontInstance*, int nFallbackLevel) 
override;
diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx
index 874ce672d97a..073dab1017da 100644
--- a/vcl/inc/headless/svpinst.hxx
+++ b/vcl/inc/headless/svpinst.hxx
@@ -120,8 +120,8 @@ public:
     bool                    CheckTimeout( bool bExecuteTimers = true );
 
     // Frame
-    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle ) override;
-    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle ) override;
+    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& rWin ) override;
+    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& ) override;
     virtual void            DestroyFrame( SalFrame* pFrame ) override;
 
     // Object (System Child Window)
@@ -134,7 +134,7 @@ public:
     // pData allows for using a system dependent graphics or device context
     virtual std::unique_ptr<SalVirtualDevice>
                             CreateVirtualDevice( SalGraphics& rGraphics,
-                                                     tools::Long &nDX, 
tools::Long &nDY,
+                                                     sal_Int32 &nDX, sal_Int32 
&nDY,
                                                      DeviceFormat eFormat, 
const SystemGraphicsData *pData = nullptr ) override;
 
     // Printer
diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx
index ca9e38cee31a..c4b9e47b814c 100644
--- a/vcl/inc/headless/svpvd.hxx
+++ b/vcl/inc/headless/svpvd.hxx
@@ -37,7 +37,7 @@ class VCL_DLLPUBLIC SvpSalVirtualDevice : public 
SalVirtualDevice
     basegfx::B2IVector                  m_aFrameSize;
     std::vector< SvpSalGraphics* >      m_aGraphics;
 
-    void CreateSurface(tools::Long nNewDX, tools::Long nNewDY, sal_uInt8 
*const pBuffer);
+    void CreateSurface(sal_Int32 nNewDX, sal_Int32 nNewDY, sal_uInt8 *const 
pBuffer, sal_Int32 nScale);
 
 protected:
     SvpSalGraphics* AddGraphics(SvpSalGraphics* aGraphics);
@@ -50,16 +50,14 @@ public:
     virtual SalGraphics*    AcquireGraphics() override;
     virtual void            ReleaseGraphics( SalGraphics* pGraphics ) override;
 
-    virtual bool        SetSize( tools::Long nNewDX, tools::Long nNewDY ) 
override;
-    virtual bool        SetSizeUsingBuffer( tools::Long nNewDX, tools::Long 
nNewDY,
-                                            sal_uInt8 * pBuffer
+    virtual bool        SetSizeUsingBuffer( sal_Int32 nNewDX, sal_Int32 nNewDY,
+                                            sal_uInt8 * pBuffer, sal_Int32 
nScale = 100
                                           ) override;
+    virtual void SetScalePercentage(sal_Int32) override;
 
     cairo_surface_t* GetSurface() const { return m_pSurface; }
 
-    // SalGeometryProvider
-    virtual tools::Long GetWidth() const override;
-    virtual tools::Long GetHeight() const override;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const;
 };
 
 #endif // INCLUDED_VCL_INC_HEADLESS_SVPVD_HXX
diff --git a/vcl/inc/image.h b/vcl/inc/image.h
index 633c38c4a34e..373bb656ce89 100644
--- a/vcl/inc/image.h
+++ b/vcl/inc/image.h
@@ -17,26 +17,25 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#ifndef INCLUDED_VCL_INC_IMAGE_H
-#define INCLUDED_VCL_INC_IMAGE_H
+#pragma once
 
 #include <vcl/bitmapex.hxx>
+#include <vcl/GeometryProvider.hxx>
 
-class ImplImage
+class ImplImage final : public vcl::SalGeometryProvider
 {
 private:
     BitmapChecksum maBitmapChecksum;
-    /// if non-empty: cached original size of maStockName else Size of maBitmap
-    Size maSizePixel;
     /// If set - defines the bitmap via images.zip*
-    OUString maStockName;
-
+    const OUString maStockName;
+    sal_Int32 m_nScalePercentage;
 
     /// Original bitmap - or cache of a potentially scaled bitmap
-    BitmapEx maBitmapEx;
-    BitmapEx maDisabledBitmapEx;
+    mutable BitmapEx maBitmapEx;
+    mutable BitmapEx maDisabledBitmapEx;
 
-    bool loadStockAtScale(double fScale, BitmapEx &rBitmapEx);
+    bool loadStockAtScale(BitmapEx* pBitmapEx) const;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
 
 public:
     ImplImage(const BitmapEx& rBitmapEx);
@@ -52,20 +51,12 @@ public:
         return maStockName;
     }
 
+    void setScalePercentage(sal_Int32);
+
     /// get size in co-ordinates not scaled for HiDPI
-    Size getSizePixel();
-    /// Legacy - the original bitmap
     BitmapEx const & getBitmapEx(bool bDisabled = false);
-    /// Taking account of HiDPI scaling
-    BitmapEx const & getBitmapExForHiDPI(bool bDisabled = false);
 
     bool isEqual(const ImplImage &ref) const;
-    bool isSizeEmpty() const
-    {
-        return maSizePixel == Size();
-    }
 };
 
-#endif // INCLUDED_VCL_INC_IMAGE_H
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/ios/iosinst.hxx b/vcl/inc/ios/iosinst.hxx
index f1269cabe75e..b341dd596e59 100644
--- a/vcl/inc/ios/iosinst.hxx
+++ b/vcl/inc/ios/iosinst.hxx
@@ -43,8 +43,8 @@ public:
     CreateClipboard(const css::uno::Sequence<css::uno::Any>& i_rArguments) 
override;
 
     void GetWorkArea(tools::Rectangle& rRect);
-    SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle) 
override;
-    SalFrame* CreateChildFrame(SystemParentData* pParent, SalFrameStyleFlags 
nStyle) override;
+    SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle, 
vcl::Window&) override;
+    SalFrame* CreateChildFrame(SystemParentData* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& rWin) override;
 };
 
 #endif // INCLUDED_VCL_INC_IOS_IOSINST_HXX
diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h
index 6d707807d38e..007545875369 100644
--- a/vcl/inc/osx/salinst.h
+++ b/vcl/inc/osx/salinst.h
@@ -93,8 +93,8 @@ public:
     virtual void AfterAppInit() override;
     virtual bool SVMainHook(int *) override;
 
-    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle ) override;
-    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle ) override;
+    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& rWin ) override;
+    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& ) override;
     virtual void            DestroyFrame( SalFrame* pFrame ) override;
     virtual SalObject*      CreateObject( SalFrame* pParent, SystemWindowData* 
pWindowData,
                                           bool bShow ) override;
diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 2d7c5718d6cf..c0a145ab89d1 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -129,7 +129,6 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
 
     bool isWindow() const;
     QWindow* windowHandle() const;
-    QScreen* screen() const;
     bool isMinimized() const;
     bool isMaximized() const;
     void SetWindowStateImpl(Qt::WindowStates eState);
@@ -141,17 +140,20 @@ private Q_SLOTS:
     void screenChanged(QScreen*);
 
 public:
-    QtFrame(QtFrame* pParent, SalFrameStyleFlags nSalFrameStyle, bool 
bUseCairo);
+    QtFrame(QtFrame* pParent, SalFrameStyleFlags nSalFrameStyle, vcl::Window&, 
bool bUseCairo);
     virtual ~QtFrame() override;
 
     QWidget* GetQWidget() const { return m_pQWidget; }
     QtMainWindow* GetTopLevelWindow() const { return m_pTopLevel; }
     QWidget* asChild() const;
     qreal devicePixelRatioF() const;
+    QScreen* screen() const;
 
     void Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 
nExtentsWidth,
                 sal_Int32 nExtentsHeight) const;
 
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
+
     virtual SalGraphics* AcquireGraphics() override;
     virtual void ReleaseGraphics(SalGraphics* pGraphics) override;
 
@@ -177,7 +179,8 @@ public:
     virtual void SetMaxClientSize(tools::Long nWidth, tools::Long nHeight) 
override;
     virtual void SetPosSize(tools::Long nX, tools::Long nY, tools::Long 
nWidth, tools::Long nHeight,
                             sal_uInt16 nFlags) override;
-    virtual void GetClientSize(tools::Long& rWidth, tools::Long& rHeight) 
override;
+    virtual void GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+    virtual void GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight) override;
     virtual void GetWorkArea(tools::Rectangle& rRect) override;
     virtual SalFrame* GetParent() const override;
     virtual void SetModal(bool bModal) override;
diff --git a/vcl/inc/qt5/QtGraphics.hxx b/vcl/inc/qt5/QtGraphics.hxx
index fed7c2cb88f0..8f85002ee6e4 100644
--- a/vcl/inc/qt5/QtGraphics.hxx
+++ b/vcl/inc/qt5/QtGraphics.hxx
@@ -29,8 +29,6 @@
 #include <QtGui/QPainterPath>
 #include <QtGui/QRegion>
 
-#include "QtGraphicsBase.hxx"
-
 namespace vcl::font
 {
 class PhysicalFontCollection;
@@ -42,7 +40,7 @@ class QtFontFace;
 class QtFrame;
 class QtPainter;
 
-class QtGraphicsBackend final : public SalGraphicsImpl, public QtGraphicsBase
+class QtGraphicsBackend final : public SalGraphicsImpl
 {
     friend class QtPainter;
 
@@ -164,7 +162,7 @@ private:
     void drawScaledImage(const SalTwoRect& rPosAry, const QImage& rImage);
 };
 
-class QtGraphics final : public SalGraphicsAutoDelegateToImpl, public 
QtGraphicsBase
+class QtGraphics final : public SalGraphicsAutoDelegateToImpl
 {
     friend class QtBitmap;
 
@@ -218,7 +216,7 @@ public:
 
     // GDI
 
-    virtual void GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
 
     // Text rendering + font support
 
diff --git a/vcl/inc/qt5/QtGraphicsBase.hxx b/vcl/inc/qt5/QtGraphicsBase.hxx
index 73c39fb5ba80..0c0a0f93b0fa 100644
--- a/vcl/inc/qt5/QtGraphicsBase.hxx
+++ b/vcl/inc/qt5/QtGraphicsBase.hxx
@@ -9,21 +9,10 @@
 
 #pragma once
 
-#include <QtWidgets/QApplication>
+#include <vcl/GenometryProvider.hxx>
 
-class QtGraphicsBase
-{
-    qreal m_fDPR;
+class QImage;
 
-public:
-    QtGraphicsBase()
-        : m_fDPR(qApp ? qApp->devicePixelRatio() : 1.0)
-    {
-    }
-
-    void setDevicePixelRatioF(qreal fDPR) { m_fDPR = fDPR; }
-
-    qreal devicePixelRatioF() const { return m_fDPR; }
-};
+static sal_Int32 GetSgpMetric(QImage &rImage, vcl::SGPmetric eMetric) const;
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/QtGraphics_Controls.hxx 
b/vcl/inc/qt5/QtGraphics_Controls.hxx
index 17039f9d6038..dd89713f3334 100644
--- a/vcl/inc/qt5/QtGraphics_Controls.hxx
+++ b/vcl/inc/qt5/QtGraphics_Controls.hxx
@@ -31,16 +31,16 @@
 #include <QtWidgets/QStyle>
 #include <QtWidgets/QStyleOption>
 
-class QtGraphicsBase;
+class SalGraphics;
 
 class QtGraphics_Controls final : public vcl::WidgetDrawInterface
 {
     std::unique_ptr<QImage> m_image;
     QRect m_lastPopupRect;
-    QtGraphicsBase const& m_rGraphics;
+    SalGraphics const& m_rGraphics;
 
 public:
-    QtGraphics_Controls(const QtGraphicsBase& rGraphics);
+    QtGraphics_Controls(const SalGraphics& rGraphics);
 
     QImage* getImage() { return m_image.get(); }
 
diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx
index df6c4ec5af86..6ac1588597fb 100644
--- a/vcl/inc/qt5/QtInstance.hxx
+++ b/vcl/inc/qt5/QtInstance.hxx
@@ -112,9 +112,9 @@ public:
 
     void RunInMainThread(std::function<void()> func);
 
-    virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags 
nStyle) override;
+    virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window&) override;
     virtual SalFrame* CreateChildFrame(SystemParentData* pParent,
-                                       SalFrameStyleFlags nStyle) override;
+                                       SalFrameStyleFlags nStyle, 
vcl::Window&) override;
     virtual void DestroyFrame(SalFrame* pFrame) override;
 
     virtual SalObject* CreateObject(SalFrame* pParent, SystemWindowData* 
pWindowData,
@@ -122,7 +122,7 @@ public:
     virtual void DestroyObject(SalObject* pObject) override;
 
     virtual std::unique_ptr<SalVirtualDevice>
-    CreateVirtualDevice(SalGraphics& rGraphics, tools::Long& nDX, tools::Long& 
nDY,
+    CreateVirtualDevice(SalGraphics& rGraphics, sal_Int32& nDX, sal_Int32& nDY,
                         DeviceFormat eFormat, const SystemGraphicsData* pData 
= nullptr) override;
 
     virtual SalInfoPrinter* CreateInfoPrinter(SalPrinterQueueInfo* pQueueInfo,
diff --git a/vcl/inc/qt5/QtPainter.hxx b/vcl/inc/qt5/QtPainter.hxx
index 9702a19bdbe4..6d012e996402 100644
--- a/vcl/inc/qt5/QtPainter.hxx
+++ b/vcl/inc/qt5/QtPainter.hxx
@@ -43,19 +43,19 @@ public:
     void update(int nx, int ny, int nw, int nh)
     {
         if (m_rGraphics.m_pFrame)
-            m_aRegion += scaledQRect({ nx, ny, nw, nh }, 1 / 
m_rGraphics.devicePixelRatioF());
+            m_aRegion += scaledQRect({ nx, ny, nw, nh }, 1 / 
m_rGraphics.m_pFrame->devicePixelRatioF());
     }
 
     void update(const QRect& rRect)
     {
         if (m_rGraphics.m_pFrame)
-            m_aRegion += scaledQRect(rRect, 1 / 
m_rGraphics.devicePixelRatioF());
+            m_aRegion += scaledQRect(rRect, 1 / 
m_rGraphics.m_pFrame->devicePixelRatioF());
     }
 
     void update(const QRectF& rRectF)
     {
         if (m_rGraphics.m_pFrame)
-            update(scaledQRect(rRectF.toAlignedRect(), 1 / 
m_rGraphics.devicePixelRatioF()));
+            update(scaledQRect(rRectF.toAlignedRect(), 1 / 
m_rGraphics.m_pFrame->devicePixelRatioF()));
     }
 
     void update()
diff --git a/vcl/inc/qt5/QtSvpGraphics.hxx b/vcl/inc/qt5/QtSvpGraphics.hxx
index da3786eee165..35150cd43903 100644
--- a/vcl/inc/qt5/QtSvpGraphics.hxx
+++ b/vcl/inc/qt5/QtSvpGraphics.hxx
@@ -22,13 +22,12 @@
 #include <vclpluginapi.h>
 #include <headless/svpgdi.hxx>
 
-#include "QtGraphicsBase.hxx"
-
 class QtFrame;
 
-class VCLPLUG_QT_PUBLIC QtSvpGraphics final : public SvpSalGraphics, public 
QtGraphicsBase
+class VCLPLUG_QT_PUBLIC QtSvpGraphics final : public SvpSalGraphics
 {
     QtFrame* const m_pFrame;
+    sal_Int32 m_nScalePercentage;
 
     void handleDamage(const tools::Rectangle&) override;
 
@@ -46,7 +45,7 @@ public:
                                           int height) const override;
 #endif // ENABLE_CAIRO_CANVAS
 
-    virtual void GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
 
     virtual OUString getRenderBackendName() const override { return "qt5svp"; }
 };
diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx
index ecaa7075a426..1260d3c193d4 100644
--- a/vcl/inc/qt5/QtTools.hxx
+++ b/vcl/inc/qt5/QtTools.hxx
@@ -30,6 +30,7 @@
 #include <tools/color.hxx>
 #include <tools/gen.hxx>
 #include <vcl/bitmap/BitmapTypes.hxx>
+#include <vcl/GeometryProvider.hxx>
 
 #include <com/sun/star/uno/Sequence.hxx>
 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
@@ -151,6 +152,8 @@ sal_uInt16 GetMouseModCode(Qt::MouseButtons eButtons);
 
 QImage toQImage(const Image& rImage);
 
+sal_Int32 GetSgpMetricFromQImage(vcl::SGPmetric eMetric, QImage& rImage);
+
 template <typename charT, typename traits>
 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, 
traits>& stream,
                                                      const QString& rString)
diff --git a/vcl/inc/qt5/QtVirtualDevice.hxx b/vcl/inc/qt5/QtVirtualDevice.hxx
index 2481f63d0657..dc5846a57307 100644
--- a/vcl/inc/qt5/QtVirtualDevice.hxx
+++ b/vcl/inc/qt5/QtVirtualDevice.hxx
@@ -34,23 +34,20 @@ class QtVirtualDevice final : public SalVirtualDevice
 {
     std::vector<QtGraphics*> m_aGraphics;
     std::unique_ptr<QImage> m_pImage;
-    QSize m_aFrameSize;
-    double m_fScale;
 
 public:
-    QtVirtualDevice(double fScale);
+    QtVirtualDevice(sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nScale);
 
     // SalVirtualDevice
     virtual SalGraphics* AcquireGraphics() override;
     virtual void ReleaseGraphics(SalGraphics* pGraphics) override;
 
-    virtual bool SetSize(tools::Long nNewDX, tools::Long nNewDY) override;
-    virtual bool SetSizeUsingBuffer(tools::Long nNewDX, tools::Long nNewDY,
-                                    sal_uInt8* pBuffer) override;
+    virtual bool SetSizeUsingBuffer(sal_Int32 nNewDX, sal_Int32 nNewDY,
+                                    sal_uInt8* pBuffer, sal_Int32 nScale = 
100) override;
 
     // SalGeometryProvider
-    virtual tools::Long GetWidth() const override;
-    virtual tools::Long GetHeight() const override;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
+    virtual void SetScalePercentage(sal_Int32) override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index 8f7f6cc319e1..0207da7c7432 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -87,6 +87,7 @@ class QtWidget : public QWidget
     void inputMethodEvent(QInputMethodEvent*) override;
     QVariant inputMethodQuery(Qt::InputMethodQuery) const override;
     static void closePopup();
+    void handleScaleOrResize(QResizeEvent* pEvent, bool bScaleChanged);
 
 public:
     QtWidget(QtFrame& rFrame, Qt::WindowFlags f = Qt::WindowFlags());
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index ac8840b437c7..f6b2a69c57d1 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -113,7 +113,7 @@ struct ImplSVEvent;
 /// A SalFrame is a system window (e.g. an X11 window).
 class VCL_PLUGIN_PUBLIC SalFrame
     : public vcl::DeletionNotifier
-    , public SalGeometryProvider
+    , public vcl::SalGeometryProvider
 {
 private:
     // the VCL window corresponding to this frame
@@ -123,15 +123,13 @@ private:
 protected:
     mutable std::unique_ptr<weld::Window> m_xFrameWeld;
 public:
-                            SalFrame();
+                            SalFrame(vcl::Window&);
     virtual                 ~SalFrame() override;
 
     SalFrameGeometry        maGeometry = {}; ///< absolute, unmirrored values
 
-    // SalGeometryProvider
-    virtual tools::Long GetWidth() const override { return maGeometry.nWidth; }
-    virtual tools::Long GetHeight() const override { return 
maGeometry.nHeight; }
-    virtual bool IsOffScreen() const override { return false; }
+    void SetGeometrySize(sal_Int32, sal_Int32);
+    void SetGeometrySize(const Size& rSize) { 
SetGeometrySize(rSize.getWidth(), rSize.getHeight()); }
 
     // SalGraphics or NULL, but two Graphics for all SalFrames
     // must be returned
@@ -159,7 +157,8 @@ public:
     virtual void            SetMinClientSize( tools::Long nWidth, tools::Long 
nHeight ) = 0;
     virtual void            SetMaxClientSize( tools::Long nWidth, tools::Long 
nHeight ) = 0;
     virtual void            SetPosSize( tools::Long nX, tools::Long nY, 
tools::Long nWidth, tools::Long nHeight, sal_uInt16 nFlags ) = 0;
-    virtual void            GetClientSize( tools::Long& rWidth, tools::Long& 
rHeight ) = 0;
+    virtual void GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY) = 0;
+    virtual void GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight) = 0;
     virtual void            GetWorkArea( tools::Rectangle& rRect ) = 0;
     virtual SalFrame*       GetParent() const = 0;
     // Note: x will be mirrored at parent if UI mirroring is active
@@ -293,7 +292,7 @@ public:
 
     // Callbacks (independent part in vcl/source/window/winproc.cxx)
     // for default message handling return 0
-    void                    SetCallback( vcl::Window* pWindow, SALFRAMEPROC 
pProc );
+    void                    SetCallback(SALFRAMEPROC pProc );
 
     // returns the instance set
     vcl::Window*            GetWindow() const { return m_pWindow; }
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index eed8ab7160ac..1d532c917977 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -74,7 +74,9 @@ typedef std::map< sal_Ucs, sal_uInt32 >   Ucs2UIntMap;
 // note: all positions are in pixel and relative to
 // the top/left-position of the virtual output area
 
-class VCL_PLUGIN_PUBLIC SalGraphics : protected vcl::WidgetDrawInterface
+class VCL_PLUGIN_PUBLIC SalGraphics
+    : protected vcl::WidgetDrawInterface
+    , public vcl::SalGeometryProvider
 {
 public:
     SalGraphics();
@@ -108,12 +110,6 @@ public:
 
     // public SalGraphics methods, the interface to the independent vcl part
 
-    // get device resolution
-    virtual void                GetResolution( sal_Int32& rDPIX, sal_Int32& 
rDPIY ) = 0;
-
-    // get the depth of the device
-    virtual sal_uInt16          GetBitCount() const = 0;
-
     // get the width of the device
     virtual tools::Long                GetGraphicsWidth() const = 0;
 
@@ -700,11 +696,6 @@ void SalGraphics::handleDamage(const tools::Rectangle&) {}
 class VCL_DLLPUBLIC SalGraphicsAutoDelegateToImpl : public SalGraphics
 {
 public:
-    sal_uInt16 GetBitCount() const override
-    {
-        return GetImpl()->GetBitCount();
-    }
-
     tools::Long GetGraphicsWidth() const override
     {
         return GetImpl()->GetGraphicsWidth();
diff --git a/vcl/inc/salgeom.hxx b/vcl/inc/salgeom.hxx
index 0bc7335c2977..09dad8cc0480 100644
--- a/vcl/inc/salgeom.hxx
+++ b/vcl/inc/salgeom.hxx
@@ -17,19 +17,20 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#ifndef INCLUDED_VCL_INC_SALGEOM_HXX
-#define INCLUDED_VCL_INC_SALGEOM_HXX
+#pragma once
 
 #include <iostream>
 
 #include <vcl/dllapi.h>
+#include <tools/gen.hxx>
 #include <tools/long.hxx>
 
-struct SalFrameGeometry {
+struct SalFrameGeometry
+{
     // screen position of upper left corner of drawable area in pixel
-    tools::Long                nX, nY;
+    sal_Int32 nX, nY;
     // dimensions of the drawable area in pixel
-    tools::ULong        nWidth, nHeight;
+    sal_Int32 nWidth, nHeight;
     // thickness of the decoration in pixel
     tools::ULong        nLeftDecoration,
                         nTopDecoration,
@@ -48,26 +49,18 @@ struct SalFrameGeometry {
         nBottomDecoration( 0 ),
         nDisplayScreenNumber( 0 )
     {}
+
+    Size GetSize() const { return Size(nWidth, nHeight); }
+    Point GetPos() const { return Point(nX, nY); }
 };
 
 inline std::ostream &operator <<(std::ostream& s, const SalFrameGeometry& 
rGeom)
 {
+    s << rGeom.nDisplayScreenNumber << " ";
     s << rGeom.nWidth << "x" << rGeom.nHeight << "@(" << rGeom.nX << "," << 
rGeom.nY << "):{"
       << rGeom.nLeftDecoration << "," << rGeom.nTopDecoration << "," << 
rGeom.nRightDecoration << "," << rGeom.nBottomDecoration << "}";
 
     return s;
 }
 
-/// Interface used to share logic on sizing between
-/// SalVirtualDevices and SalFrames
-class VCL_PLUGIN_PUBLIC SalGeometryProvider {
-public:
-    virtual ~SalGeometryProvider() {}
-    virtual tools::Long GetWidth() const = 0;
-    virtual tools::Long GetHeight() const = 0;
-    virtual bool IsOffScreen() const = 0;
-};
-
-#endif // INCLUDED_VCL_INC_SALGEOM_HXX
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx
index 98e962d8c637..ac90a323ca1b 100644
--- a/vcl/inc/salinst.hxx
+++ b/vcl/inc/salinst.hxx
@@ -95,9 +95,8 @@ public:
     virtual bool            SVMainHook(int*) { return false; }
 
     // Frame
-    // DisplayName for Unix ???
-    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle ) = 0;
-    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle ) = 0;
+    virtual SalFrame* CreateChildFrame(SystemParentData* pParent, 
SalFrameStyleFlags, vcl::Window&) = 0;
+    virtual SalFrame* CreateFrame(SalFrame* pParent, SalFrameStyleFlags, 
vcl::Window&) = 0;
     virtual void            DestroyFrame( SalFrame* pFrame ) = 0;
 
     // Object (System Child Window)
@@ -112,7 +111,7 @@ public:
     // its size; otherwise these remain unchanged.
     virtual std::unique_ptr<SalVirtualDevice>
                             CreateVirtualDevice( SalGraphics& rGraphics,
-                                                 tools::Long &rDX, tools::Long 
&rDY,
+                                                 sal_Int32 &rDX, sal_Int32 
&rDY,
                                                  DeviceFormat eFormat, const 
SystemGraphicsData *pData = nullptr ) = 0;
 
     // Printer
diff --git a/vcl/inc/salprn.hxx b/vcl/inc/salprn.hxx
index d72853b597bf..509e21e6fe5a 100644
--- a/vcl/inc/salprn.hxx
+++ b/vcl/inc/salprn.hxx
@@ -73,7 +73,7 @@ public:
     virtual bool                    SetData( JobSetFlags nFlags, ImplJobSetup* 
pSetupData ) = 0;
 
     virtual void                    GetPageInfo( const ImplJobSetup* 
pSetupData,
-                                                 tools::Long& rOutWidth, 
tools::Long& rOutHeight,
+                                                 sal_Int32& rOutWidth, 
sal_Int32& rOutHeight,
                                                  Point& rPageOffset,
                                                  Size& rPaperSize ) = 0;
     virtual sal_uInt32              GetCapabilities( const ImplJobSetup* 
pSetupData, PrinterCapType nType ) = 0;
diff --git a/vcl/inc/salvd.hxx b/vcl/inc/salvd.hxx
index d1035feaebdd..213cc81c3673 100644
--- a/vcl/inc/salvd.hxx
+++ b/vcl/inc/salvd.hxx
@@ -17,42 +17,47 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#ifndef INCLUDED_VCL_INC_SALVD_HXX
-#define INCLUDED_VCL_INC_SALVD_HXX
+#pragma once
 
-#include "salgeom.hxx"
+#include <vcl/GeometryProvider.hxx>
+#include <sal/log.hxx>
 
 class SalGraphics;
 
 /// A non-visible drawable/buffer (e.g. an X11 Pixmap).
 class VCL_PLUGIN_PUBLIC SalVirtualDevice
-        : public SalGeometryProvider
+    : public vcl::SalGeometryProvider
 {
 public:
     SalVirtualDevice() {}
     virtual ~SalVirtualDevice() override;
 
-    // SalGeometryProvider
-    virtual bool IsOffScreen() const override { return true; }
-
     // SalGraphics or NULL, but two Graphics for all SalVirtualDevices
     // must be returned
     virtual SalGraphics*    AcquireGraphics() = 0;
     virtual void            ReleaseGraphics( SalGraphics* pGraphics ) = 0;
 
     // Set new size, without saving the old contents
-    virtual bool            SetSize( tools::Long nNewDX, tools::Long nNewDY ) 
= 0;
+    bool SetSize(sal_Int32 nNewDX, sal_Int32 nNewDY, sal_Int32 nScale = 100)
+        { return SetSizeUsingBuffer(nNewDX, nNewDY, nullptr, nScale); }
+    static inline void FixSetSizeParams(sal_Int32& nDX, sal_Int32& nDY, 
sal_Int32& nScale);
 
     // Set new size using a buffer at the given address
-    virtual bool            SetSizeUsingBuffer( tools::Long nNewDX, 
tools::Long nNewDY,
-                                                sal_uInt8 * /* pBuffer */)
-        {
-            // Only the headless virtual device has an implementation that uses
-            // pBuffer (and bTopDown).
-            return SetSize( nNewDX, nNewDY );
-        }
+    virtual bool SetSizeUsingBuffer(sal_Int32 nNewDX, sal_Int32 nNewDY, 
sal_uInt8*, sal_Int32 nScale = 100) = 0;
+
+    virtual void SetScalePercentage(sal_Int32 nScale) = 0;
 };
 
-#endif // INCLUDED_VCL_INC_SALVD_HXX
+void SalVirtualDevice::FixSetSizeParams(sal_Int32& nDX, sal_Int32& nDY, 
sal_Int32& nScale)
+{
+    SAL_WARN_IF(!(nDX > 0 && nDY > 0 && nScale > 0), "vcl",
+                "Invalid virtual device request (" << nDX << " " << nDY << " " 
<< nScale << ")!");
+    if (nDX == 0)
+        nDX = 1;
+    if (nDY == 0)
+        nDY = 1;
+    if (nScale <= 0)
+        nScale = 100;
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 3f574237444b..fd15088c98e9 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -853,8 +853,7 @@ public:
 
     int get_menu_button_width() const override
     {
-        OutputDevice* pDefault = Application::GetDefaultDevice();
-        return 20 * (pDefault ? pDefault->GetDPIScaleFactor() : 1.0);
+        return 20 * m_xComboBox->GetDPIScaleFactor();
     }
 
     void CallHandleEventListener(VclWindowEvent& rEvent)
diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx
index c9f50cd63982..42a0ede1516a 100644
--- a/vcl/inc/salwtype.hxx
+++ b/vcl/inc/salwtype.hxx
@@ -88,6 +88,7 @@ enum class SalEvent {
     LongPress,
     ExternalGesture,
     Gesture,
+    ScaleChanged,
 };
 
 struct SalAbstractMouseEvent
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index b2814b2a6463..32e8223436e0 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -23,7 +23,7 @@
 #include <vcl/dllapi.h>
 
 #include <salgdiimpl.hxx>
-#include <salgeom.hxx>
+#include <vcl/GeometryProvider.hxx>
 
 #include <skia/utils.hxx>
 
@@ -37,7 +37,7 @@ class SkiaSalBitmap;
 class VCL_DLLPUBLIC SkiaSalGraphicsImpl : public SalGraphicsImpl
 {
 public:
-    SkiaSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider* pProvider);
+    SkiaSalGraphicsImpl(SalGraphics& pParent, vcl::SalGeometryProvider* 
pProvider);
     virtual ~SkiaSalGraphicsImpl() override;
 
     virtual void Init() override;
@@ -242,7 +242,7 @@ protected:
                               tools::Long nHeight, double nTransparency, bool 
blockAA = false);
     void privateCopyBits(const SalTwoRect& rPosAry, SkiaSalGraphicsImpl* src);
 
-    void setProvider(SalGeometryProvider* provider) { mProvider = provider; }
+    void setProvider(vcl::SalGeometryProvider* provider) { mProvider = 
provider; }
 
     bool isOffscreen() const;
     bool isGPU() const { return mIsGPU; }
@@ -341,7 +341,7 @@ protected:
 
     SalGraphics& mParent;
     /// Pointer to the SalFrame or SalVirtualDevice
-    SalGeometryProvider* mProvider;
+    vcl::SalGeometryProvider* mProvider;
     // The Skia surface that is target of all the rendering.
     sk_sp<SkSurface> mSurface;
     // Note that mSurface may be a proxy surface and not the one from the 
window context.
diff --git a/vcl/inc/skia/x11/salvd.hxx b/vcl/inc/skia/x11/salvd.hxx
index fec4b8080cc1..b2ce698de77b 100644
--- a/vcl/inc/skia/x11/salvd.hxx
+++ b/vcl/inc/skia/x11/salvd.hxx
@@ -22,14 +22,13 @@ class X11SkiaSalVirtualDevice final : public 
SalVirtualDevice
     int mnHeight;
 
 public:
-    X11SkiaSalVirtualDevice(const SalGraphics& rGraphics, tools::Long nDX, 
tools::Long nDY,
+    X11SkiaSalVirtualDevice(const SalGraphics& rGraphics, sal_Int32 nDX, 
sal_Int32 nDY,
                             const SystemGraphicsData* pData,
                             std::unique_ptr<X11SalGraphics> pNewGraphics);
     virtual ~X11SkiaSalVirtualDevice() override;
 
     // SalGeometryProvider
-    virtual tools::Long GetWidth() const override { return mnWidth; }
-    virtual tools::Long GetHeight() const override { return mnHeight; }
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
 
     SalDisplay* GetDisplay() const { return mpDisplay; }
     const SalX11Screen& GetXScreenNumber() const { return mnXScreen; }
@@ -38,7 +37,9 @@ public:
     virtual void ReleaseGraphics(SalGraphics* pGraphics) override;
 
     // Set new size, without saving the old contents
-    virtual bool SetSize(tools::Long nNewDX, tools::Long nNewDY) override;
+    virtual bool SetSizeUsingBuffer(sal_Int32 nNewDX, sal_Int32 nNewDY, 
sal_uInt8*, sal_Int32 = 100) override;
+
+    virtual void SetScalePercentage(sal_Int32) override;
 };
 
 #endif // INCLUDED_VCL_INC_SKIA_X11_SALVD_H
diff --git a/vcl/inc/unx/genprn.h b/vcl/inc/unx/genprn.h
index 0c92446d5286..7250bac909f3 100644
--- a/vcl/inc/unx/genprn.h
+++ b/vcl/inc/unx/genprn.h
@@ -43,7 +43,7 @@ public:
     virtual bool                    SetPrinterData( ImplJobSetup* pSetupData ) 
override;
     virtual bool                    SetData( JobSetFlags nFlags, ImplJobSetup* 
pSetupData ) override;
     virtual void                    GetPageInfo( const ImplJobSetup* 
pSetupData,
-                                                 tools::Long& rOutWidth, 
tools::Long& rOutHeight,
+                                                 sal_Int32& rOutWidth, 
sal_Int32& rOutHeight,
                                                  Point& rPageOffset,
                                                  Size& rPaperSize ) override;
     virtual sal_uInt32              GetCapabilities( const ImplJobSetup* 
pSetupData, PrinterCapType nType ) override;
diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h
index 75c1e4cd0852..0cfccc73f26b 100644
--- a/vcl/inc/unx/genpspgraphics.h
+++ b/vcl/inc/unx/genpspgraphics.h
@@ -78,8 +78,7 @@ public:
         return m_pBackend.get();
     }
 
-    virtual void            GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY 
) override;
-
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const;
     virtual void            SetTextColor( Color nColor ) override;
     virtual void            SetFont(LogicalFontInstance*, int nFallbackLevel) 
override;
     virtual void            GetFontMetric( ImplFontMetricDataRef&, int 
nFallbackLevel ) override;
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index ced3613ad0ca..2942a617d58c 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -422,8 +422,8 @@ public:
 #endif
     int                             m_nGrabLevel;
     bool                            m_bSalObjectSetPosSize;
-    GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle );
-    GtkSalFrame( SystemParentData* pSysData );
+    GtkSalFrame(SalFrame* pParent, SalFrameStyleFlags nStyle, vcl::Window&);
+    GtkSalFrame(SystemParentData* pSysData, vcl::Window&);
 
     guint                           m_nMenuExportId;
     guint                           m_nActionGroupExportId;
@@ -489,6 +489,8 @@ public:
 
     virtual ~GtkSalFrame() override;
 
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
+
     // SalGraphics or NULL, but two Graphics for all SalFrames
     // must be returned
     virtual SalGraphics*        AcquireGraphics() override;
@@ -514,7 +516,8 @@ public:
     virtual void                SetMinClientSize( tools::Long nWidth, 
tools::Long nHeight ) override;
     virtual void                SetMaxClientSize( tools::Long nWidth, 
tools::Long nHeight ) override;
     virtual void                SetPosSize( tools::Long nX, tools::Long nY, 
tools::Long nWidth, tools::Long nHeight, sal_uInt16 nFlags ) override;
-    virtual void                GetClientSize( tools::Long& rWidth, 
tools::Long& rHeight ) override;
+    void GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+    virtual void GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight) override;
     virtual void                GetWorkArea( tools::Rectangle& rRect ) 
override;
     virtual SalFrame*           GetParent() const override;
     virtual void                SetWindowState( const SalFrameState* pState ) 
override;
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index c0a032863ea4..2bc63166689a 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -126,8 +126,7 @@ public:
 
     void WidgetQueueDraw() const;
 
-    virtual void GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
-
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
     virtual OUString getRenderBackendName() const override { return "gtk3svp"; 
}
 
     GtkStyleContext* createStyleContext(GtkControlPart ePart);
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index eb3199b58eaf..a674fdbe7d68 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -254,8 +254,8 @@ public:
     void    EnsureInit();
     virtual void AfterAppInit() override;
 
-    virtual SalFrame*           CreateFrame( SalFrame* pParent, 
SalFrameStyleFlags nStyle ) override;
-    virtual SalFrame*           CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle ) override;
+    virtual SalFrame*           CreateFrame( SalFrame* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& ) override;
+    virtual SalFrame*           CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& rWin ) override;
     virtual SalObject*          CreateObject( SalFrame* pParent, 
SystemWindowData* pWindowData, bool bShow ) override;
     virtual SalSystem*          CreateSalSystem() override;
     virtual SalInfoPrinter*     CreateInfoPrinter(SalPrinterQueueInfo* 
pPrinterQueueInfo, ImplJobSetup* pJobSetup) override;
@@ -266,7 +266,7 @@ public:
     virtual void                AddToRecentDocumentList(const OUString& 
rFileUrl, const OUString& rMimeType, const OUString& rDocumentService) override;
     virtual std::unique_ptr<SalVirtualDevice>
                                 CreateVirtualDevice( SalGraphics&,
-                                                     tools::Long &nDX, 
tools::Long &nDY,
+                                                     sal_Int32 &nDX, sal_Int32 
&nDY,
                                                      DeviceFormat eFormat,
                                                      const SystemGraphicsData* 
= nullptr ) override;
     virtual std::shared_ptr<SalBitmap> CreateSalBitmap() override;
diff --git a/vcl/inc/unx/salframe.h b/vcl/inc/unx/salframe.h
index 1107ac9feb71..5de29c198750 100644
--- a/vcl/inc/unx/salframe.h
+++ b/vcl/inc/unx/salframe.h
@@ -160,8 +160,10 @@ class X11SalFrame final : public SalFrame
     void            askForXEmbedFocus( sal_Int32 i_nTimeCode );
 
     void            updateWMClass();
+    sal_Int32 GetDPI() const;
+
 public:
-    X11SalFrame( SalFrame* pParent, SalFrameStyleFlags nSalFrameStyle, 
SystemParentData const * pSystemParent = nullptr );
+    X11SalFrame(SalFrame* pParent, SalFrameStyleFlags, SystemParentData const 
* pSystemParent, vcl::Window&);
     virtual ~X11SalFrame() override;
 
     bool            Dispatch( XEvent *pEvent );
@@ -200,6 +202,7 @@ public:
     bool                    appendUnicodeSequence( sal_Unicode );
     bool                    endUnicodeSequence();
 
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
     virtual SalGraphics*        AcquireGraphics() override;
     virtual void                ReleaseGraphics( SalGraphics* pGraphics ) 
override;
 
@@ -219,7 +222,8 @@ public:
     virtual void                SetMinClientSize( tools::Long nWidth, 
tools::Long nHeight ) override;
     virtual void                SetMaxClientSize( tools::Long nWidth, 
tools::Long nHeight ) override;
     virtual void                SetPosSize( tools::Long nX, tools::Long nY, 
tools::Long nWidth, tools::Long nHeight, sal_uInt16 nFlags ) override;
-    virtual void                GetClientSize( tools::Long& rWidth, 
tools::Long& rHeight ) override;
+    virtual void GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+    virtual void GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight) override;
     virtual void                GetWorkArea( tools::Rectangle& rRect ) 
override;
     virtual SalFrame*           GetParent() const override;
     virtual void                SetWindowState( const SalFrameState* pState ) 
override;
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 045a3848e20f..182a7f1acc34 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -110,8 +110,8 @@ public:
 
     void                            Flush();
 
-    // override all pure virtual methods
-    virtual void                    GetResolution( sal_Int32& rDPIX, 
sal_Int32& rDPIY ) override;
+    sal_Int32 GetDPI() const;
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
 
     virtual void                    SetTextColor( Color nColor ) override;
     virtual void                    SetFont(LogicalFontInstance*, int 
nFallbackLevel) override;
diff --git a/vcl/inc/unx/salinst.h b/vcl/inc/unx/salinst.h
index 1f8ccd92b19c..ebb4ec0641dd 100644
--- a/vcl/inc/unx/salinst.h
+++ b/vcl/inc/unx/salinst.h
@@ -44,20 +44,20 @@ public:
     explicit X11SalInstance(std::unique_ptr<SalYieldMutex> pMutex);
     virtual ~X11SalInstance() override;
 
-    virtual SalFrame*           CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle ) override;
-    virtual SalFrame*           CreateFrame( SalFrame* pParent, 
SalFrameStyleFlags nStyle ) override;
+    virtual SalFrame*           CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& rWin ) override;
+    virtual SalFrame*           CreateFrame( SalFrame* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& ) override;
     virtual void                DestroyFrame( SalFrame* pFrame ) override;
 
     virtual SalObject*          CreateObject( SalFrame* pParent, 
SystemWindowData* pWindowData, bool bShow ) override;
     virtual void                DestroyObject( SalObject* pObject ) override;
 
     /// Gtk vclplug needs to pass GtkSalGraphics to X11SalVirtualDevice, so 
create it, and pass as pNewGraphics.
-    static std::unique_ptr<SalVirtualDevice> CreateX11VirtualDevice(const 
SalGraphics& rGraphics, tools::Long &nDX, tools::Long &nDY,
+    static std::unique_ptr<SalVirtualDevice> CreateX11VirtualDevice(const 
SalGraphics& rGraphics, sal_Int32 &nDX, sal_Int32 &nDY,
             DeviceFormat eFormat, const SystemGraphicsData* pData, 
std::unique_ptr<X11SalGraphics> pNewGraphics);
 
     virtual std::unique_ptr<SalVirtualDevice>
                                 CreateVirtualDevice( SalGraphics& rGraphics,
-                                                     tools::Long &nDX, 
tools::Long &nDY,
+                                                     sal_Int32 &nDX, sal_Int32 
&nDY,
                                                      DeviceFormat eFormat, 
const SystemGraphicsData *pData = nullptr ) override;
     virtual void                PostPrintersChanged() override;
     virtual std::unique_ptr<GenPspGraphics> CreatePrintGraphics() override;
diff --git a/vcl/inc/unx/salvd.h b/vcl/inc/unx/salvd.h
index 922b9d5e271c..78734de87d59 100644
--- a/vcl/inc/unx/salvd.h
+++ b/vcl/inc/unx/salvd.h
@@ -46,7 +46,7 @@ class X11SalVirtualDevice final : public SalVirtualDevice
     bool        bExternPixmap_;
 
 public:
-    X11SalVirtualDevice(const SalGraphics& rGraphics, tools::Long &nDX, 
tools::Long &nDY,
+    X11SalVirtualDevice(const SalGraphics& rGraphics, sal_Int32 &nDX, 
sal_Int32 &nDY,
             DeviceFormat eFormat, const SystemGraphicsData *pData, 
std::unique_ptr<X11SalGraphics> pNewGraphics);
 
     virtual ~X11SalVirtualDevice() override;
@@ -67,11 +67,10 @@ public:
     virtual void            ReleaseGraphics( SalGraphics* pGraphics ) override;
 
     /// Set new size, without saving the old contents
-    virtual bool        SetSize( tools::Long nNewDX, tools::Long nNewDY ) 
override;
+    virtual bool SetSizeUsingBuffer(sal_Int32 nNewDX, sal_Int32 nNewDY, 
sal_uInt8*, sal_Int32) override;
 
-    // SalGeometryProvider
-    virtual tools::Long GetWidth() const override { return nDX_; }
-    virtual tools::Long GetHeight() const override { return nDY_; }
+    virtual sal_Int32 GetSgpMetric(vcl::SGPmetric eMetric) const override;
+    virtual void SetScalePercentage(sal_Int32) override;
 };
 
 #endif // INCLUDED_VCL_INC_UNX_SALVD_H
diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h
index c62a68ae0455..8ab5e5d7f313 100644
--- a/vcl/inc/win/salinst.h
+++ b/vcl/inc/win/salinst.h
@@ -43,8 +43,8 @@ public:
     WinSalInstance();
     virtual ~WinSalInstance() override;
 
-    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle ) override;
-    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle ) override;
+    virtual SalFrame*       CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& rWin ) override;
+    virtual SalFrame*       CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& ) override;
     virtual void            DestroyFrame( SalFrame* pFrame ) override;
     virtual SalObject*      CreateObject( SalFrame* pParent, SystemWindowData* 
pWindowData, bool bShow ) override;
     virtual void            DestroyObject( SalObject* pObject ) override;
diff --git a/vcl/inc/win/salprn.h b/vcl/inc/win/salprn.h
index 2d02aa5b0e54..02c52be76380 100644
--- a/vcl/inc/win/salprn.h
+++ b/vcl/inc/win/salprn.h
@@ -64,7 +64,7 @@ public:
     virtual bool                    SetPrinterData( ImplJobSetup* pSetupData ) 
override;
     virtual bool                    SetData( JobSetFlags nFlags, ImplJobSetup* 
pSetupData ) override;
     virtual void                    GetPageInfo( const ImplJobSetup* 
pSetupData,
-                                                 tools::Long& rOutWidth, 
tools::Long& rOutHeight,
+                                                 sal_Int32& rOutWidth, 
sal_Int32& rOutHeight,
                                                  Point& rPageOffset,
                                                  Size& rPaperSize ) override;
     virtual sal_uInt32              GetCapabilities( const ImplJobSetup* 
pSetupData, PrinterCapType nType ) override;
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index b0395330e19e..65cf596fe783 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -140,8 +140,6 @@ struct ImplFrameData
     std::vector<VclPtr<vcl::Window> > maOwnerDrawList;    //< List of system 
windows with owner draw decoration
     std::shared_ptr<vcl::font::PhysicalFontCollection> mxFontCollection;   //< 
Font-List for this frame
     std::shared_ptr<ImplFontCache> mxFontCache; //< Font-Cache for this frame
-    sal_Int32           mnDPIX;                 //< Original Screen Resolution
-    sal_Int32           mnDPIY;                 //< Original Screen Resolution
     ImplSVEvent *       mnFocusId;              //< FocusId for PostUserLink
     ImplSVEvent *       mnMouseMoveId;          //< MoveId for PostUserLink
     tools::Long                mnLastMouseX;           //< last x mouse 
position
@@ -214,11 +212,14 @@ namespace o3tl {
 }
 
 
-class WindowImpl
+class WindowImpl final
 {
+    friend class vcl::Window;
+
 private:
     WindowImpl(const WindowImpl&) = delete;
     WindowImpl& operator=(const WindowImpl&) = delete;
+
 public:
     WindowImpl( vcl::Window& rWindow, WindowType );
     ~WindowImpl();
@@ -431,7 +432,7 @@ bool ImplLOKHandleMouseEvent( const VclPtr<vcl::Window>& 
xWindow, MouseNotifyEve
                               tools::Long nX, tools::Long nY, sal_uInt64 
nMsgTime,
                               sal_uInt16 nCode, MouseEventModifiers nMode, 
sal_uInt16 nClicks);
 
-void ImplHandleResize( vcl::Window* pWindow, tools::Long nNewWidth, 
tools::Long nNewHeight );
+void ImplHandleResize(vcl::Window* pWindow, sal_Int32 nNewWidth, sal_Int32 
nNewHeight);
 
 VCL_DLLPUBLIC void ImplWindowStateFromStr(WindowStateData& rData, 
std::string_view rStr);
 
diff --git a/vcl/inc/windowdev.hxx b/vcl/inc/windowdev.hxx
index a3d535646ccf..69d9811e8ab6 100644
--- a/vcl/inc/windowdev.hxx
+++ b/vcl/inc/windowdev.hxx
@@ -23,7 +23,7 @@
 
 namespace vcl
 {
-class WindowOutputDevice final : public ::OutputDevice
+class WindowOutputDevice : public ::OutputDevice
 {
 public:
     WindowOutputDevice(vcl::Window& rOwnerWindow);
diff --git a/vcl/ios/iosinst.cxx b/vcl/ios/iosinst.cxx
index a9fa27e5ea82..b260a01efa26 100644
--- a/vcl/ios/iosinst.cxx
+++ b/vcl/ios/iosinst.cxx
@@ -118,13 +118,13 @@ public:
     }
 };
 
-SalFrame *IosSalInstance::CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle )
+SalFrame *IosSalInstance::CreateChildFrame( SystemParentData* pParent, 
SalFrameStyleFlags nStyle, vcl::Window& rWin )
 {
     pParent = NULL;
     return new IosSalFrame( this, NULL, nStyle );
 }
 
-SalFrame *IosSalInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle )
+SalFrame *IosSalInstance::CreateFrame( SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& )
 {
     return new IosSalFrame( this, pParent, nStyle );
 }
diff --git a/vcl/qt5/QtData.cxx b/vcl/qt5/QtData.cxx
index 7d2d0418e80e..13569721b6cd 100644
--- a/vcl/qt5/QtData.cxx
+++ b/vcl/qt5/QtData.cxx
@@ -327,9 +327,7 @@ bool QtData::ErrorTrapPop(bool /*bIgnoreError*/) { return 
false; }
 bool QtData::noNativeControls()
 {
     static const bool bNoNative
-        = ((nullptr != getenv("SAL_VCL_QT5_NO_NATIVE")) && (nullptr != 
ImplGetSVData())
-           && ImplGetSVData()->maAppData.mxToolkitName
-           && ImplGetSVData()->maAppData.mxToolkitName->match("qt5"));
+        = (nullptr != getenv("SAL_VCL_QT5_NO_NATIVE"));
     return bNoNative;
 }
 
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 440cd8048d76..282a24f913d3 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -100,8 +100,9 @@ sal_Int32 screenNumber(const QScreen* pScreen)
 }
 }
 
-QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
-    : m_pTopLevel(nullptr)
+QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags nStyle, vcl::Window& 
rWin, bool bUseCairo)
+    : SalFrame(rWin)
+    , m_pTopLevel(nullptr)
     , m_bUseCairo(bUseCairo)
     , m_bNullRegion(true)
     , m_bGraphicsInUse(false)
@@ -197,7 +198,31 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
     fixICCCMwindowGroup();
 }
 
-void QtFrame::screenChanged(QScreen*) { m_pQWidget->fakeResize(); }
+void QtFrame::screenChanged(QScreen* pScreen)
+{
+    SAL_DEBUG(__func__ << " " << m_pQWidget->size() << " " << 
pScreen->devicePixelRatio() << " "
+                       << GetWidth() << " " << GetHeight());
+
+    maGeometry.nDisplayScreenNumber = screenNumber(pScreen);
+#if 1
+    if (m_pSvpGraphics)
+    {
+//        m_pSvpGraphics->setDevicePixelRatioF(devicePixelRatioF());
+        m_pSvpGraphics->ReleaseFonts();
+    }
+    if (m_pQtGraphics)
+    {
+//        m_pQtGraphics->setDevicePixelRatioF(devicePixelRatioF());
+        m_pQtGraphics->ReleaseFonts();
+    }
+#endif
+    m_pQWidget->fakeResize();
+    CallCallback(SalEvent::SettingsChanged, nullptr);
+#if 0
+    SalPaintEvent aPaintEvt(0, 0, GetWidth(), GetHeight(), true);
+    CallCallback(SalEvent::Paint, &aPaintEvt);
+#endif
+}
 
 void QtFrame::FillSystemEnvData(SystemEnvData& rData, sal_IntPtr pWindow, 
QWidget* pWidget)
 {
@@ -303,6 +328,8 @@ SalGraphics* QtFrame::AcquireGraphics()
     if (m_bGraphicsInUse)
         return nullptr;
 
+    SAL_DEBUG(__func__ << " " << this);
+
     m_bGraphicsInUse = true;
 
     if (m_bUseCairo)
@@ -313,8 +340,7 @@ SalGraphics* QtFrame::AcquireGraphics()
             m_pSvpGraphics.reset(new QtSvpGraphics(this));
             m_pSurface.reset(
                 cairo_image_surface_create(CAIRO_FORMAT_ARGB32, aSize.width(), 
aSize.height()));
-            m_pSvpGraphics->setSurface(m_pSurface.get(),
-                                       basegfx::B2IVector(aSize.width(), 
aSize.height()));
+            m_pSvpGraphics->setSurface(m_pSurface.get());
             cairo_surface_set_user_data(m_pSurface.get(), 
QtSvpGraphics::getDamageKey(),
                                         &m_aDamageHandler, nullptr);
         }
@@ -624,8 +650,10 @@ void QtFrame::SetPosSize(tools::Long nX, tools::Long nY, 
tools::Long nWidth, too
     asChild()->move(round(nX / devicePixelRatioF()), round(nY / 
devicePixelRatioF()));
 }
 
-void QtFrame::GetClientSize(tools::Long& rWidth, tools::Long& rHeight)
+void QtFrame::GetClientSize(sal_Int32& rWidth, sal_Int32& rHeight)
 {
+    SAL_DEBUG(__func__ << " " << m_pQWidget->width() << " " << 
m_pQWidget->height() << " "
+                       << devicePixelRatioF());
     rWidth = round(m_pQWidget->width() * devicePixelRatioF());
     rHeight = round(m_pQWidget->height() * devicePixelRatioF());
 }
@@ -1509,4 +1537,33 @@ void QtFrame::handleDragLeave()
     m_bInDrag = false;
 }
 
+void QtFrame::GetDPI(sal_Int32& rDPIX, sal_Int32& rDPIY)
+{
+    char* pForceDpi;
+    if ((pForceDpi = getenv("SAL_FORCEDPI")))
+    {
+        OString sForceDPI(pForceDpi);
+        rDPIX = rDPIY = sForceDPI.toInt32();
+        return;
+    }
+
+    QScreen* pScreen = screen();
+    if (!pScreen)
+        return;
+
+    rDPIX = pScreen->logicalDotsPerInchX() * pScreen->devicePixelRatio() + 0.5;
+    rDPIY = pScreen->logicalDotsPerInchY() * pScreen->devicePixelRatio() + 0.5;
+}
+
+sal_Int32 QtFrame::GetSgpMetric(vcl::SGPmetric eMetric) const
+{
+    switch (eMetric)
+    {
+        case vcl::SGPmetric::Width: return asChild()->width() * 
GetDPIScaleFactor();
+        case vcl::SGPmetric::Height: return asChild()->height() * 
GetDPIScaleFactor();
+        default:
+            return GetWindow()->GetOutDev()->GetSgpMetric(eMetric);
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtGraphics.cxx b/vcl/qt5/QtGraphics.cxx
index d809556ce219..3bda88974f1d 100644
--- a/vcl/qt5/QtGraphics.cxx
+++ b/vcl/qt5/QtGraphics.cxx
@@ -42,8 +42,10 @@ QtGraphics::QtGraphics( QtFrame *pFrame, QImage *pQImage )
         if (!QtData::noNativeControls())
             m_pWidgetDraw.reset(new QtGraphics_Controls(*this));
     }
+#if 0
     if (m_pFrame)
-        setDevicePixelRatioF(m_pFrame->devicePixelRatioF());
+        setScale(m_pFrame->devicePixelRatioF());
+#endif
 }
 
 QtGraphics::~QtGraphics() { ReleaseFonts(); }
@@ -103,4 +105,15 @@ void QtGraphics::handleDamage(const tools::Rectangle& 
rDamagedRegion)
     aPainter.update(toQRect(rDamagedRegion));
 }
 
+sal_Int32 QtGraphics::GetSgpMetric(vcl::SGPmetric eMetric) const
+{
+    QImage* pImage = 
static_cast<QtGraphics_Controls*>(m_pWidgetDraw.get())->getImage();
+    assert(pImage || m_pFrame);
+    if (pImage)
+        return GetSgpMetricFromQImage(eMetric, *pImage);
+    if (m_pFrame)
+        return m_pFrame->GetWindow()->GetOutDev()->GetSgpMetric(eMetric);
+    return -1;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtGraphics_Controls.cxx b/vcl/qt5/QtGraphics_Controls.cxx
index e6e3d820da59..4e0a530a8fe1 100644
--- a/vcl/qt5/QtGraphics_Controls.cxx
+++ b/vcl/qt5/QtGraphics_Controls.cxx
@@ -25,8 +25,8 @@
 #include <QtWidgets/QLabel>
 
 #include <QtTools.hxx>
-#include <QtGraphicsBase.hxx>
 #include <vcl/decoview.hxx>
+#include <salgdi.hxx>
 
 /**
   Conversion function between VCL ControlState together with
@@ -74,7 +74,7 @@ static void 
lcl_ApplyBackgroundColorToStyleOption(QStyleOption& rOption,
     }
 }
 
-QtGraphics_Controls::QtGraphics_Controls(const QtGraphicsBase& rGraphics)
+QtGraphics_Controls::QtGraphics_Controls(const SalGraphics& rGraphics)
     : m_rGraphics(rGraphics)
 {
 }
@@ -268,7 +268,7 @@ bool QtGraphics_Controls::drawNativeControl(ControlType 
type, ControlPart part,
     {
         m_image.reset(new QImage(widgetRect.width(), widgetRect.height(),
                                  QImage::Format_ARGB32_Premultiplied));
-        m_image->setDevicePixelRatio(m_rGraphics.devicePixelRatioF());
+        m_image->setDevicePixelRatio(m_rGraphics.GetDPIScaleFactor());
     }
 
     // Default image color - just once
@@ -1094,14 +1094,14 @@ bool 
QtGraphics_Controls::hitTestNativeControl(ControlType nType, ControlPart nP
 
 inline int QtGraphics_Controls::downscale(int size, Round eRound)
 {
-    return static_cast<int>(eRound == Round::Ceil ? ceil(size / 
m_rGraphics.devicePixelRatioF())
-                                                  : floor(size / 
m_rGraphics.devicePixelRatioF()));
+    return static_cast<int>(eRound == Round::Ceil ? ceil(size / 
m_rGraphics.GetDPIScaleFactor())
+                                                  : floor(size / 
m_rGraphics.GetDPIScaleFactor()));
 }
 
 inline int QtGraphics_Controls::upscale(int size, Round eRound)
 {
-    return static_cast<int>(eRound == Round::Ceil ? ceil(size * 
m_rGraphics.devicePixelRatioF())
-                                                  : floor(size * 
m_rGraphics.devicePixelRatioF()));
+    return static_cast<int>(eRound == Round::Ceil ? ceil(size * 
m_rGraphics.GetDPIScaleFactor())
+                                                  : floor(size * 
m_rGraphics.GetDPIScaleFactor()));
 }
 
 inline QRect QtGraphics_Controls::downscale(const QRect& rect)
diff --git a/vcl/qt5/QtGraphics_GDI.cxx b/vcl/qt5/QtGraphics_GDI.cxx
index f87de50827df..431f659c1fcf 100644
--- a/vcl/qt5/QtGraphics_GDI.cxx
+++ b/vcl/qt5/QtGraphics_GDI.cxx
@@ -23,6 +23,7 @@
 #include <QtPainter.hxx>
 
 #include <sal/log.hxx>
+#include <window.h>
 
 #include <QtGui/QPainter>
 #include <QtGui/QScreen>
@@ -736,29 +737,4 @@ bool 
QtGraphicsBackend::supportsOperation(OutDevSupportType eType) const
     }
 }
 
-void QtGraphics::GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY)
-{
-    char* pForceDpi;
-    if ((pForceDpi = getenv("SAL_FORCEDPI")))
-    {
-        OString sForceDPI(pForceDpi);
-        rDPIX = rDPIY = sForceDPI.toInt32();
-        return;
-    }
-
-    if (!m_pFrame)
-        return;
-
-#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
-    QScreen* pScreen = m_pFrame->GetQWidget()->screen();
-#else
-    if (!m_pFrame->GetQWidget()->window()->windowHandle())
-        return;
-
-    QScreen* pScreen = 
m_pFrame->GetQWidget()->window()->windowHandle()->screen();
-#endif
-    rDPIX = pScreen->logicalDotsPerInchX() * pScreen->devicePixelRatio() + 0.5;
-    rDPIY = pScreen->logicalDotsPerInchY() * pScreen->devicePixelRatio() + 0.5;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx
index 5522ea15c31a..1234cbc0c9ec 100644
--- a/vcl/qt5/QtInstance.cxx
+++ b/vcl/qt5/QtInstance.cxx
@@ -297,21 +297,21 @@ void QtInstance::localeChanged()
 
 void QtInstance::deleteObjectLater(QObject* pObject) { pObject->deleteLater(); 
}
 
-SalFrame* QtInstance::CreateChildFrame(SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle)
+SalFrame* QtInstance::CreateChildFrame(SystemParentData* /*pParent*/, 
SalFrameStyleFlags nStyle, vcl::Window& rWin)
 {
     SalFrame* pRet(nullptr);
-    RunInMainThread([&, this]() { pRet = new QtFrame(nullptr, nStyle, 
useCairo()); });
+    RunInMainThread([&, this]() { pRet = new QtFrame(nullptr, nStyle, rWin, 
useCairo()); });
     assert(pRet);
     return pRet;
 }
 
-SalFrame* QtInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nStyle)
+SalFrame* QtInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags 
nStyle, vcl::Window& rWin)
 {
     assert(!pParent || dynamic_cast<QtFrame*>(pParent));
 
     SalFrame* pRet(nullptr);
     RunInMainThread(
-        [&, this]() { pRet = new QtFrame(static_cast<QtFrame*>(pParent), 
nStyle, useCairo()); });
+        [&, this]() { pRet = new QtFrame(static_cast<QtFrame*>(pParent), 
nStyle, rWin, useCairo()); });
     assert(pRet);
     return pRet;
 }
@@ -345,7 +345,7 @@ void QtInstance::DestroyObject(SalObject* pObject)
 }
 
 std::unique_ptr<SalVirtualDevice>
-QtInstance::CreateVirtualDevice(SalGraphics& rGraphics, tools::Long& nDX, 
tools::Long& nDY,
+QtInstance::CreateVirtualDevice(SalGraphics& rGraphics, sal_Int32& nDX, 
sal_Int32& nDY,
                                 DeviceFormat /*eFormat*/, const 
SystemGraphicsData* pGd)
 {
     if (m_bUseCairo)
@@ -362,8 +362,7 @@ QtInstance::CreateVirtualDevice(SalGraphics& rGraphics, 
tools::Long& nDX, tools:
     }
     else
     {
-        std::unique_ptr<SalVirtualDevice> pVD(new QtVirtualDevice(/*scale*/ 
1));
-        pVD->SetSize(nDX, nDY);
+        std::unique_ptr<SalVirtualDevice> pVD(new QtVirtualDevice(nDX, nDY, 
rGraphics.GetDPIScalePercentage()));
         return pVD;
     }
 }
diff --git a/vcl/qt5/QtSvpGraphics.cxx b/vcl/qt5/QtSvpGraphics.cxx
index 8ae869a1c247..7b49ff3df806 100644
--- a/vcl/qt5/QtSvpGraphics.cxx
+++ b/vcl/qt5/QtSvpGraphics.cxx
@@ -26,11 +26,16 @@
 
 QtSvpGraphics::QtSvpGraphics(QtFrame* pFrame)
     : m_pFrame(pFrame)
+    , m_nScalePercentage(-1)
 {
     if (!QtData::noNativeControls())
         m_pWidgetDraw.reset(new QtGraphics_Controls(*this));
+    SAL_DEBUG(__func__ << " " << m_pFrame);
+#if 1
     if (m_pFrame)
-        setDevicePixelRatioF(m_pFrame->devicePixelRatioF());
+       SAL_DEBUG(__func__ << " " << m_pFrame->devicePixelRatioF());

... etc. - the rest is truncated

Reply via email to