[Libreoffice-commits] core.git: Branch 'feature/scaling-geometry-provider' - 94 commits - android/source basegfx/source basic/source bridges/source chart2/IwyuFilter_chart2.yaml chart2/source comphelper/source compilerplugins/clang configmgr/source configure.ac connectivity/source cppuhelper/source cui/inc cui/source cui/uiconfig dbaccess/source desktop/source desktop/uiconfig distro-configs/Jenkins distro-configs/LibreOfficeVanillaMacAppStore.conf download.lst drawinglayer/source editeng/source external/ct2n external/firebird external/languagetool external/libwebp external/Module_external.mk external/openldap extras/source filter/source formula/source fpicker/source framework/inc framework/IwyuFilter_framework.yaml framework/source helpcontent2 hwpfilter/source i18nutil/source include/basegfx include/o3tl include/oox include/sal include/svx include/tools include/unotools include/vcl Makefile.fetch Makefile.in offapi/com offapi/UnoApi_offapi.mk officecfg/registry oox/source package/source readlic ense_oo/license README.md Repository.mk scaddins/source scp2/AutoInstall.mk scp2/InstallModule_extensions.mk scp2/source sc/qa sc/source sc/uiconfig sd/qa sd/source setup_native/source sfx2/inc sfx2/sdi sfx2/source shell/source solenv/vs sot/source starmath/Library_sm.mk starmath/source starmath/uiconfig starmath/UIConfig_smath.mk starmath/util stoc/source svl/source svtools/source svx/source svx/uiconfig sw/CppunitTest_sw_core_text.mk sw/inc sw/qa sw/sdi sw/source sw/uiconfig tools/source translations ucbhelper/source ucb/source unotools/source vcl/android vcl/headless vcl/inc vcl/ios vcl/Library_vcl.mk vcl/osx vcl/qt5 vcl/qt6 vcl/skia vcl/source vcl/unx wizards/source writerfilter/source xmloff/source xmlscript/source

Thu, 28 Apr 2022 02:10:27 -0700

Rebased ref, commits from common ancestor:
commit 5bee79b22699da428c57d9e79ef3b5fdbe936cc2
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Thu Apr 28 11:07:56 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Apr 28 11:07:56 2022 +0200

    Yesterdays work

diff --git a/vcl/qt6/QtSvpVirtualDevice.hxx b/vcl/qt6/QtSvpVirtualDevice.cxx
similarity index 90%
rename from vcl/qt6/QtSvpVirtualDevice.hxx
rename to vcl/qt6/QtSvpVirtualDevice.cxx
index 1639ab1a2256..bbed3a54525a 100644
--- a/vcl/qt6/QtSvpVirtualDevice.hxx
+++ b/vcl/qt6/QtSvpVirtualDevice.cxx
@@ -7,6 +7,6 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include "../qt5/QtSvpVirtualDevice.hxx"
+#include "../qt5/QtSvpVirtualDevice.cxx"
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit ec517c18b51a48afdaaf85e1038321eed8344b29
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Thu Apr 28 10:50:08 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Apr 28 10:50:08 2022 +0200

    More work

diff --git a/vcl/inc/qt5/QtSvpVirtualDevice.hxx 
b/vcl/inc/qt5/QtSvpVirtualDevice.hxx
new file mode 100644
index 000000000000..4718148ad657
--- /dev/null
+++ b/vcl/inc/qt5/QtSvpVirtualDevice.hxx
@@ -0,0 +1,31 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <headless/svpvd.hxx>
+
+class VCL_DLLPUBLIC QtSvpVirtualDevice : public SvpSalVirtualDevice
+{
+public:
+    QtSvpVirtualDevice(SalGraphics& rGraphics, cairo_surface_t* 
pPreExistingTarget);
+    SalGraphics* AcquireGraphics() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/qt5/QtSvpVirtualDevice.hxx b/vcl/qt5/QtSvpVirtualDevice.cxx
similarity index 100%
rename from vcl/qt5/QtSvpVirtualDevice.hxx
rename to vcl/qt5/QtSvpVirtualDevice.cxx
commit 4492c1695b2966a378189bc76c6a82beb495ed98
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Tue Apr 26 19:39:44 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Wed Apr 27 09:53:37 2022 +0200

    More work on per-window native scaling

diff --git a/framework/inc/uiconfiguration/imagemanager.hxx 
b/framework/inc/uiconfiguration/imagemanager.hxx
index aacc8bbd3c72..5b6ef4dd3d38 100644
--- a/framework/inc/uiconfiguration/imagemanager.hxx
+++ b/framework/inc/uiconfiguration/imagemanager.hxx
@@ -22,7 +22,7 @@
 #include <memory>
 
 #include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/ui/XImageManager.hpp>
+#include <com/sun/star/ui/XImageManager2.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
 #include <cppuhelper/implbase.hxx>
@@ -32,10 +32,10 @@
 namespace framework
 {
     class ImageManagerImpl;
-    class ImageManager final : public ::cppu::WeakImplHelper< 
css::ui::XImageManager, css::lang::XServiceInfo>
+    class ImageManager final : public ::cppu::WeakImplHelper< 
css::ui::XImageManager2, css::lang::XServiceInfo>
     {
         public:
-            ImageManager( const css::uno::Reference< 
css::uno::XComponentContext >& rxContext, bool bForModule );
+            ImageManager(const 
css::uno::Reference<css::uno::XComponentContext>& rxContext, bool bForModule, 
sal_Int32 nScale = 100);
             virtual ~ImageManager() override;
 
             virtual OUString SAL_CALL getImplementationName() override
@@ -82,6 +82,9 @@ namespace framework
             virtual sal_Bool SAL_CALL isModified() override;
             virtual sal_Bool SAL_CALL isReadOnly() override;
 
+            // XImageManager2
+            virtual sal_Int32 SAL_CALL scalePercentage() override;
+
             // Non-UNO methods
             /// @throws css::uno::RuntimeException
             void setStorage( const css::uno::Reference< css::embed::XStorage 
>& Storage );
diff --git a/framework/inc/uielement/menubarmanager.hxx 
b/framework/inc/uielement/menubarmanager.hxx
index 710c788f2dcc..b0e8cb3e778a 100644
--- a/framework/inc/uielement/menubarmanager.hxx
+++ b/framework/inc/uielement/menubarmanager.hxx
@@ -186,6 +186,7 @@ class MenuBarManager final :
         css::uno::Reference< css::container::XIndexAccess >          
m_xDeferredItemContainer;
         OUString                                                     
m_sIconTheme;
         Timer                                                        
m_aAsyncSettingsTimer;
+        sal_Int32 m_nScalePercentage;
 };
 
 } // namespace
diff --git a/framework/inc/uielement/toolbarmanager.hxx 
b/framework/inc/uielement/toolbarmanager.hxx
index a12528415184..886c775294fa 100644
--- a/framework/inc/uielement/toolbarmanager.hxx
+++ b/framework/inc/uielement/toolbarmanager.hxx
@@ -241,6 +241,7 @@ class ToolBarManager final : public ToolbarManager_Base
         OUString                                                     
m_sIconTheme;
 
         rtl::Reference< ToolBarManager >                             
m_aOverflowManager;
+        sal_Int32 m_nScalePercentage;
 };
 
 }
diff --git a/framework/source/uiconfiguration/CommandImageResolver.cxx 
b/framework/source/uiconfiguration/CommandImageResolver.cxx
index a431ae320b35..b1f91cbdf270 100644
--- a/framework/source/uiconfiguration/CommandImageResolver.cxx
+++ b/framework/source/uiconfiguration/CommandImageResolver.cxx
@@ -62,7 +62,8 @@ OUString lclConvertToCanonicalName(const OUString& rFileName)
 
 } // end anonymous namespace
 
-CommandImageResolver::CommandImageResolver()
+CommandImageResolver::CommandImageResolver(sal_Int32 nScalePercentage)
+    : m_nScalePercentage(nScalePercentage)
 {
 }
 
@@ -70,6 +71,11 @@ CommandImageResolver::~CommandImageResolver()
 {
 }
 
+void CommandImageResolver::setScalePercentage(sal_Int32 nScale)
+{
+    m_nScalePercentage = nScale;
+}
+
 void CommandImageResolver::registerCommands(const Sequence<OUString>& 
aCommandSequence)
 {
     sal_Int32 nSequenceSize = aCommandSequence.getLength();
@@ -130,7 +136,7 @@ ImageList* CommandImageResolver::getImageList(ImageType 
nImageType)
     if (!m_pImageList[nImageType])
     {
         OUString sIconPath = 
OUString::createFromAscii(ImageType_Prefixes[nImageType]);
-        m_pImageList[nImageType].reset( new ImageList(m_aImageNameVector, 
sIconPath) );
+        m_pImageList[nImageType].reset(new ImageList(m_aImageNameVector, 
sIconPath, m_nScalePercentage));
     }
 
     return m_pImageList[nImageType].get();
@@ -144,7 +150,10 @@ Image 
CommandImageResolver::getImageFromCommandURL(ImageType nImageType, const O
         ImageList* pImageList = getImageList(nImageType);
         return pImageList->GetImage(pIterator->second);
     }
-    return Image();
+
+    Image aImage;
+    aImage.setScalePercentage(m_nScalePercentage);
+    return aImage;
 }
 
 } // end namespace vcl
diff --git a/framework/source/uiconfiguration/CommandImageResolver.hxx 
b/framework/source/uiconfiguration/CommandImageResolver.hxx
index 0622caf332bb..ad5780878095 100644
--- a/framework/source/uiconfiguration/CommandImageResolver.hxx
+++ b/framework/source/uiconfiguration/CommandImageResolver.hxx
@@ -33,13 +33,17 @@ private:
 
     o3tl::enumarray<ImageType, std::unique_ptr<ImageList>> m_pImageList;
     OUString m_sIconTheme;
+    sal_Int32 m_nScalePercentage;
 
     ImageList* getImageList(ImageType nImageType);
 
 public:
-    CommandImageResolver();
+    CommandImageResolver(sal_Int32 nScalePercentage);
     ~CommandImageResolver();
 
+    sal_Int32 scalePercentage() const { return m_nScalePercentage; }
+    void setScalePercentage(sal_Int32 nScale);
+
     void registerCommands(const css::uno::Sequence<OUString>& 
aCommandSequence);
     Image getImageFromCommandURL(ImageType nImageType, const OUString& 
rCommandURL);
 
diff --git a/framework/source/uiconfiguration/ImageList.cxx 
b/framework/source/uiconfiguration/ImageList.cxx
index 0e64d219c166..06ed15fa1425 100644
--- a/framework/source/uiconfiguration/ImageList.cxx
+++ b/framework/source/uiconfiguration/ImageList.cxx
@@ -23,12 +23,15 @@
 #include "ImageList.hxx"
 
 ImageList::ImageList()
+    : m_nScalePercentage(100)
 {
 }
 
 ImageList::ImageList(const std::vector< OUString >& rNameVector,
-                     const OUString& rPrefix)
+                     const OUString& rPrefix, sal_Int32 nScale)
+    : m_nScalePercentage(nScale)
 {
+    assert(nScale > 0);
     SAL_INFO( "vcl", "vcl: ImageList::ImageList(const vector< OUString >& ..." 
);
 
     maImages.reserve( rNameVector.size() );
@@ -103,6 +106,7 @@ void ImageList::AddImage( const OUString& rImageName, const 
Image& rImage )
 
 void ImageList::ReplaceImage( const OUString& rImageName, const Image& rImage )
 {
+    assert(rImage.scalePercentage() == m_nScalePercentage);
     const sal_uInt16 nId = ImplGetImageId( rImageName );
 
     if( nId )
diff --git a/framework/source/uiconfiguration/ImageList.hxx 
b/framework/source/uiconfiguration/ImageList.hxx
index 0951b8369d2a..bd706699ba7e 100644
--- a/framework/source/uiconfiguration/ImageList.hxx
+++ b/framework/source/uiconfiguration/ImageList.hxx
@@ -40,7 +40,7 @@ class ImageList
 public:
                     explicit ImageList();
                     ImageList( const std::vector<OUString>& rNameVector,
-                               const OUString& rPrefix);
+                               const OUString& rPrefix, sal_Int32 nScale);
 
     void            InsertFromHorizontalStrip( const BitmapEx &rBitmapEx,
                                    const std::vector< OUString > &rNameVector 
);
@@ -62,11 +62,14 @@ public:
     const OUString & GetImageName( sal_uInt16 nPos ) const;
     void            GetImageNames( ::std::vector< OUString >& rNames ) const;
 
+    sal_Int32 scalePercentage() const { return m_nScalePercentage; }
+
 private:
 
     std::vector< std::unique_ptr<ImageAryData> >   maImages;
     std::unordered_map< OUString, ImageAryData * > maNameHash;
     OUString               maPrefix;
+    const sal_Int32 m_nScalePercentage;
 
     sal_uInt16  ImplGetImageId( const OUString& rImageName ) const;
     void ImplAddImage( std::u16string_view aPrefix, const OUString &aName, 
sal_uInt16 nId, const Image &aImage );
diff --git a/framework/source/uiconfiguration/imagemanager.cxx 
b/framework/source/uiconfiguration/imagemanager.cxx
index 1e104b6df6a1..6875141e6a49 100644
--- a/framework/source/uiconfiguration/imagemanager.cxx
+++ b/framework/source/uiconfiguration/imagemanager.cxx
@@ -38,8 +38,8 @@ using namespace ::com::sun::star::beans;
 namespace framework
 {
 
-ImageManager::ImageManager( const uno::Reference< uno::XComponentContext >& 
rxContext, bool bForModule ) :
-    m_pImpl( new ImageManagerImpl(rxContext, this, bForModule) )
+ImageManager::ImageManager(const uno::Reference< uno::XComponentContext>& 
rxContext, bool bForModule, sal_Int32 nScale)
+    : m_pImpl(new ImageManagerImpl(rxContext, this, bForModule, nScale))
 {
 }
 
@@ -160,6 +160,11 @@ sal_Bool SAL_CALL ImageManager::isReadOnly()
     return m_pImpl->isReadOnly();
 }
 
+sal_Int32 SAL_CALL ImageManager::scalePercentage()
+{
+    return m_pImpl->m_nScalePercentage;
+}
+
 } // namespace framework
 
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.cxx 
b/framework/source/uiconfiguration/imagemanagerimpl.cxx
index c60e7d3c1dd2..268df1d25122 100644
--- a/framework/source/uiconfiguration/imagemanagerimpl.cxx
+++ b/framework/source/uiconfiguration/imagemanagerimpl.cxx
@@ -100,8 +100,9 @@ static GlobalImageList* getGlobalImageList( const 
uno::Reference< uno::XComponen
     return pGlobalImageList;
 }
 
-CmdImageList::CmdImageList( const uno::Reference< uno::XComponentContext >& 
rxContext, const OUString& aModuleIdentifier ) :
+CmdImageList::CmdImageList( const uno::Reference< uno::XComponentContext >& 
rxContext, const OUString& aModuleIdentifier, sal_Int32 nScale) :
     m_bInitialized(false),
+    m_aResolver(nScale),
     m_aModuleIdentifier( aModuleIdentifier ),
     m_xContext( rxContext )
 {
@@ -473,15 +474,17 @@ CmdImageList* 
ImageManagerImpl::implts_getDefaultImageList()
     return m_pDefaultImageList.get();
 }
 
-ImageManagerImpl::ImageManagerImpl( const uno::Reference< 
uno::XComponentContext >& rxContext,::cppu::OWeakObject* pOwner,bool 
_bUseGlobal ) :
-    m_xContext( rxContext )
+ImageManagerImpl::ImageManagerImpl( const uno::Reference< 
uno::XComponentContext >& rxContext,
+        ::cppu::OWeakObject* pOwner, bool bUseGlobal, sal_Int32 nScale)
+    : m_xContext(rxContext)
     , m_pOwner(pOwner)
     , m_aResourceString( "private:resource/images/moduleimages" )
-    , m_bUseGlobal(_bUseGlobal)
+    , m_bUseGlobal(bUseGlobal)
     , m_bReadOnly( true )
     , m_bInitialized( false )
     , m_bModified( false )
     , m_bDisposed( false )
+    , m_nScalePercentage(nScale)
 {
     for ( vcl::ImageType n : o3tl::enumrange<vcl::ImageType>() )
     {
@@ -571,9 +574,13 @@ void ImageManagerImpl::initialize( const Sequence< Any >& 
aArguments )
             {
                 aPropValue.Value >>= m_xUserRootCommit;
             }
+           else if (aPropValue.Name == "ScalePercentage")
+                aPropValue.Value >>= m_nScalePercentage;
         }
     }
 
+    SAL_DEBUG(__func__ << " " << m_nScalePercentage);
+
     if ( m_xUserConfigStorage.is() )
     {
         uno::Reference< XPropertySet > xPropSet( m_xUserConfigStorage, 
UNO_QUERY );
@@ -588,6 +595,7 @@ void ImageManagerImpl::initialize( const Sequence< Any >& 
aArguments )
     implts_initialize();
 
     m_bInitialized = true;
+    SAL_DEBUG(__func__ << " " << m_nScalePercentage);
 }
 
 // XImageManagerImpl
@@ -734,6 +742,8 @@ Sequence< uno::Reference< XGraphic > > 
ImageManagerImpl::getImages(
                 aImage = rGlobalImageList->getImageFromCommandURL( nIndex, 
rURL );
         }
 
+        aImage.setScalePercentage(m_nScalePercentage);
+        SAL_DEBUG(__func__ << " " << m_nScalePercentage << " " << 
aImage.scalePercentage());
         aGraphSeqRange[n++] = GetXGraphic(aImage);
     }
 
diff --git a/framework/source/uiconfiguration/imagemanagerimpl.hxx 
b/framework/source/uiconfiguration/imagemanagerimpl.hxx
index 88f4a8349398..178926556fd2 100644
--- a/framework/source/uiconfiguration/imagemanagerimpl.hxx
+++ b/framework/source/uiconfiguration/imagemanagerimpl.hxx
@@ -44,7 +44,8 @@ namespace framework
     class CmdImageList
     {
         public:
-            CmdImageList(const css::uno::Reference< 
css::uno::XComponentContext >& rxContext, const OUString& aModuleIdentifier);
+            CmdImageList(const css::uno::Reference< 
css::uno::XComponentContext >& rxContext, 
+                         const OUString& aModuleIdentifier, sal_Int32 
nScalePercentage = 100);
             virtual ~CmdImageList();
 
             virtual Image getImageFromCommandURL(vcl::ImageType nImageType, 
const OUString& rCommandURL);
@@ -77,8 +78,9 @@ namespace framework
     {
         public:
             ImageManagerImpl(const css::uno::Reference< 
css::uno::XComponentContext >& rxContext
-                ,::cppu::OWeakObject *pOwner
-                ,bool _bUseGlobal);
+                , ::cppu::OWeakObject *pOwner
+                , bool bUseGlobal
+               , sal_Int32 nScalePercentage = 100);
             ~ImageManagerImpl();
 
             void dispose();
@@ -176,12 +178,13 @@ namespace framework
             
comphelper::OInterfaceContainerHelper4<css::ui::XUIConfigurationListener>       
m_aConfigListeners;
             o3tl::enumarray<vcl::ImageType,std::unique_ptr<ImageList>>         
             m_pUserImageList;
             o3tl::enumarray<vcl::ImageType,bool>                               
             m_bUserImageListModified;
-            bool                                                               
             m_bUseGlobal;
+        const bool m_bUseGlobal;
             bool                                                               
             m_bReadOnly;
             bool                                                               
             m_bInitialized;
             bool                                                               
             m_bModified;
             bool                                                               
             m_bDisposed;
-   };
+        sal_Int32 m_nScalePercentage;
+    };
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx 
b/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx
index 65ff144913f9..7a1d5724aec8 100644
--- a/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx
+++ b/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx
@@ -30,7 +30,7 @@
 #include <com/sun/star/ui/UIElementType.hpp>
 #include <com/sun/star/ui/ConfigurationEvent.hpp>
 #include <com/sun/star/ui/ModuleAcceleratorConfiguration.hpp>
-#include <com/sun/star/ui/XModuleUIConfigurationManager2.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManager3.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
 #include <com/sun/star/lang/IllegalAccessException.hpp>
 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
@@ -81,7 +81,7 @@ namespace {
 class ModuleUIConfigurationManager : public cppu::WeakImplHelper<
                                        css::lang::XServiceInfo,
                                        css::lang::XComponent,
-                                       css::ui::XModuleUIConfigurationManager2 
>
+                                       css::ui::XModuleUIConfigurationManager3 
>
 {
 public:
     ModuleUIConfigurationManager(
@@ -136,6 +136,9 @@ public:
     virtual sal_Bool SAL_CALL isModified() override;
     virtual sal_Bool SAL_CALL isReadOnly() override;
 
+    // XUIConfigurationManager3
+    virtual css::uno::Reference<css::uno::XInterface> SAL_CALL 
getScaledImageManager(::sal_Int16 nScalePercentage) override;
+
 private:
     // private data types
     enum Layer
@@ -216,7 +219,7 @@ private:
     std::mutex                                                m_mutex;
     comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> 
m_aEventListeners;
     comphelper::OInterfaceContainerHelper4<css::ui::XUIConfigurationListener> 
m_aConfigListeners;
-    rtl::Reference< ImageManager >                            
m_xModuleImageManager;
+    std::unordered_map<sal_Int16, rtl::Reference<ImageManager>> 
m_xModuleImageManagers;
     css::uno::Reference< css::ui::XAcceleratorConfiguration > 
m_xModuleAcceleratorManager;
 };
 
@@ -907,10 +910,7 @@ void SAL_CALL ModuleUIConfigurationManager::dispose()
         m_aConfigListeners.disposeAndClear( aGuard, aEvent );
     }
 
-    /* SAFE AREA 
-----------------------------------------------------------------------------------------------
 */
-    SolarMutexClearableGuard aGuard;
-    Reference< XComponent > xModuleImageManager( m_xModuleImageManager );
-    m_xModuleImageManager.clear();
+    SolarMutexGuard aGuard;
     m_xModuleAcceleratorManager.clear();
     m_aUIElements[LAYER_USERDEFINED].clear();
     m_aUIElements[LAYER_DEFAULT].clear();
@@ -919,17 +919,18 @@ void SAL_CALL ModuleUIConfigurationManager::dispose()
     m_xUserRootCommit.clear();
     m_bModified = false;
     m_bDisposed = true;
-    aGuard.clear();
-    /* SAFE AREA 
-----------------------------------------------------------------------------------------------
 */
 
-    try
-    {
-        if ( xModuleImageManager.is() )
-            xModuleImageManager->dispose();
-    }
-    catch ( const Exception& )
-    {
-    }
+    for (auto xImageManager : m_xModuleImageManagers)
+        try
+        {
+            if (xImageManager.second.is())
+                 xImageManager.second->dispose();
+        }
+        catch (const Exception&)
+        {
+        }
+
+    m_xModuleImageManagers.clear();
 }
 
 void SAL_CALL ModuleUIConfigurationManager::addEventListener( const Reference< 
XEventListener >& xListener )
@@ -1397,27 +1398,40 @@ void SAL_CALL 
ModuleUIConfigurationManager::insertSettings( const OUString& NewR
     }
 }
 
-Reference< XInterface > SAL_CALL 
ModuleUIConfigurationManager::getImageManager()
+Reference< XInterface > SAL_CALL 
ModuleUIConfigurationManager::getScaledImageManager(sal_Int16 nScaleFactor)
 {
     SolarMutexGuard g;
 
     if ( m_bDisposed )
         throw DisposedException();
 
-    if ( !m_xModuleImageManager.is() )
+    rtl::Reference<ImageManager> xImageManager;
+
+    auto const & aManagerIter = m_xModuleImageManagers.find(nScaleFactor);
+    if (aManagerIter == m_xModuleImageManagers.end())
     {
-        m_xModuleImageManager = new ImageManager( m_xContext, 
/*bForModule*/true );
+        xImageManager = new ImageManager(m_xContext, /*bForModule*/ true);
+       m_xModuleImageManagers[nScaleFactor] = xImageManager;
+       SAL_DEBUG(__func__ << " " << nScaleFactor);
 
         uno::Sequence<uno::Any> aPropSeq(comphelper::InitAnyPropertySequence(
         {
             {"UserConfigStorage", uno::Any(m_xUserConfigStorage)},
             {"ModuleIdentifier", uno::Any(m_aModuleIdentifier)},
             {"UserRootCommit", uno::Any(m_xUserRootCommit)},
+           {"ScalePercentage", uno::Any(nScaleFactor)}
         }));
-        m_xModuleImageManager->initialize( aPropSeq );
+        xImageManager->initialize(aPropSeq);
     }
+    else
+        xImageManager = aManagerIter->second;
+
+    return Reference< XInterface >( 
static_cast<cppu::OWeakObject*>(xImageManager.get()), UNO_QUERY );
+}
 
-    return Reference< XInterface >( 
static_cast<cppu::OWeakObject*>(m_xModuleImageManager.get()), UNO_QUERY );
+Reference< XInterface > SAL_CALL 
ModuleUIConfigurationManager::getImageManager()
+{
+    return getScaledImageManager(100);
 }
 
 Reference< ui::XAcceleratorConfiguration > SAL_CALL 
ModuleUIConfigurationManager::getShortCutManager()
diff --git a/framework/source/uiconfiguration/uiconfigurationmanager.cxx 
b/framework/source/uiconfiguration/uiconfigurationmanager.cxx
index 881bd2b8f490..9aab1f012b66 100644
--- a/framework/source/uiconfiguration/uiconfigurationmanager.cxx
+++ b/framework/source/uiconfiguration/uiconfigurationmanager.cxx
@@ -1202,9 +1202,9 @@ void SAL_CALL UIConfigurationManager::setStorage( const 
Reference< XStorage >& S
     if ( m_xAccConfig.is() )
         m_xAccConfig->setStorage( m_xDocConfigStorage );
 
-    auto const & aManagerIter = m_xImageManagers.find(100);
-    if (aManagerIter != m_xImageManagers.end())
-        aManagerIter->second->setStorage(m_xDocConfigStorage);
+    for (auto& xImageManager : m_xImageManagers)
+        if (xImageManager.second.is())
+            xImageManager.second->setStorage(m_xDocConfigStorage);
 
     if ( m_xDocConfigStorage.is() )
     {
diff --git a/framework/source/uielement/menubarmanager.cxx 
b/framework/source/uielement/menubarmanager.cxx
index c363ccffb9b6..13f116821066 100644
--- a/framework/source/uielement/menubarmanager.cxx
+++ b/framework/source/uielement/menubarmanager.cxx
@@ -37,6 +37,7 @@
 #include <com/sun/star/ui/ItemType.hpp>
 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManager3.hpp>
 #include <com/sun/star/ui/ItemStyle.hpp>
 #include <com/sun/star/frame/status/Visibility.hpp>
 #include <com/sun/star/util/URLTransformer.hpp>
@@ -48,6 +49,7 @@
 #include <uno/current_context.hxx>
 #include <unotools/cmdoptions.hxx>
 #include <toolkit/awt/vclxmenu.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/sysdata.hxx>
 #include <vcl/menu.hxx>
@@ -58,6 +60,7 @@
 #include <svtools/miscopt.hxx>
 #include <uielement/menubarmerger.hxx>
 #include <tools/urlobj.hxx>
+#include <vcl/window.hxx>
 
 using namespace ::cppu;
 using namespace ::com::sun::star;
@@ -94,6 +97,7 @@ MenuBarManager::MenuBarManager(
     , m_xURLTransformer(_xURLTransformer)
     , m_sIconTheme( SvtMiscOptions().GetIconTheme() )
     , m_aAsyncSettingsTimer( "framework::MenuBarManager::Deactivate 
m_aAsyncSettingsTimer" )
+    , m_nScalePercentage(100)
 {
     m_xPopupMenuControllerFactory = 
frame::thePopupMenuControllerFactory::get(m_xContext);
     FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, 
bDelete );
@@ -907,6 +911,10 @@ void MenuBarManager::FillMenuManager( Menu* pMenu, const 
Reference< XFrame >& rF
     m_pVCLMenu          = pMenu;
     m_xDispatchProvider = rDispatchProvider;
 
+    vcl::Window* pWindow = 
VCLUnoHelper::GetWindow(rFrame->getComponentWindow());
+    m_nScalePercentage = pWindow->GetOutDev()->GetDPIScalePercentage();
+    SAL_DEBUG(__func__ << " " << m_nScalePercentage);
+
     const StyleSettings& rSettings = 
Application::GetSettings().GetStyleSettings();
     m_bShowMenuImages   = rSettings.GetUseImagesInMenus();
     m_bRetrieveImages   = false;
@@ -1221,7 +1229,11 @@ void MenuBarManager::RetrieveImageManagers()
         Reference< XModuleUIConfigurationManagerSupplier > 
xModuleCfgMgrSupplier =
             theModuleUIConfigurationManagerSupplier::get( m_xContext );
         Reference< XUIConfigurationManager > xUICfgMgr = 
xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
-        m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
+       Reference<XModuleUIConfigurationManager3> xUICfgMgr3(xUICfgMgr, 
UNO_QUERY);
+       if (xUICfgMgr3.is())
+            
m_xModuleImageManager.set(xUICfgMgr3->getScaledImageManager(m_nScalePercentage),
 UNO_QUERY);
+       else
+            m_xModuleImageManager.set(xUICfgMgr->getImageManager(), UNO_QUERY);
         m_xModuleImageManager->addConfigurationListener( Reference< 
XUIConfigurationListener >(this) );
     }
 }
@@ -1556,9 +1568,11 @@ void MenuBarManager::FillMenuImages(Reference< XFrame > 
const & _xFrame, Menu* _
             {
                 OUString aMenuItemCommand = _pMenu->GetItemCommand( nId );
                 Image aImage = 
vcl::CommandInfoProvider::GetImageForCommand(aMenuItemCommand, _xFrame);
+               SAL_DEBUG(__func__ << " " << !!aImage << " " << 
aImage.scalePercentage());
                 if ( !aImage )
                     aImage = 
Image(aAddonOptions.GetImageFromURL(aMenuItemCommand, false));
 
+               SAL_DEBUG(__func__ << " " << aImage.scalePercentage());
                 _pMenu->SetItemImage( nId, aImage );
             }
             else
diff --git a/framework/source/uielement/toolbarmanager.cxx 
b/framework/source/uielement/toolbarmanager.cxx
index 42d6163dcf8b..1194cb39179c 100644
--- a/framework/source/uielement/toolbarmanager.cxx
+++ b/framework/source/uielement/toolbarmanager.cxx
@@ -49,6 +49,7 @@
 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManager3.hpp>
 #include <com/sun/star/ui/ImageType.hpp>
 #include <com/sun/star/ui/UIElementType.hpp>
 #include <com/sun/star/lang/DisposedException.hpp>
@@ -579,6 +580,7 @@ ToolBarManager::ToolBarManager( const Reference< 
XComponentContext >& rxContext,
     m_xContext( rxContext ),
     m_aAsyncUpdateControllersTimer( "framework::ToolBarManager 
m_aAsyncUpdateControllersTimer" ),
     m_sIconTheme( SvtMiscOptions().GetIconTheme() )
+    , m_nScalePercentage(100)
 {
     Init();
 }
@@ -600,6 +602,7 @@ ToolBarManager::ToolBarManager( const Reference< 
XComponentContext >& rxContext,
     m_xContext( rxContext ),
     m_aAsyncUpdateControllersTimer( "framework::ToolBarManager 
m_aAsyncUpdateControllersTimer" ),
     m_sIconTheme( SvtMiscOptions().GetIconTheme() )
+    , m_nScalePercentage(100)
 {
     Init();
 }
@@ -608,6 +611,10 @@ void ToolBarManager::Init()
 {
     OSL_ASSERT( m_xContext.is() );
 
+    vcl::Window* pWindow = 
VCLUnoHelper::GetWindow(m_xFrame->getComponentWindow());
+    m_nScalePercentage = pWindow->GetOutDev()->GetDPIScalePercentage();
+    SAL_DEBUG(__func__ << " " << m_nScalePercentage);
+
     m_pImpl->Init();
 
     m_xToolbarControllerFactory = frame::theToolbarControllerFactory::get( 
m_xContext );
@@ -1339,7 +1346,11 @@ void ToolBarManager::InitImageManager()
         Reference< XModuleUIConfigurationManagerSupplier > 
xModuleCfgMgrSupplier =
             theModuleUIConfigurationManagerSupplier::get( m_xContext );
         Reference< XUIConfigurationManager > xUICfgMgr = 
xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier );
-        m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY );
+        Reference<XModuleUIConfigurationManager3> xUICfgMgr3(xUICfgMgr, 
UNO_QUERY);
+        if (xUICfgMgr3.is())
+             
m_xModuleImageManager.set(xUICfgMgr3->getScaledImageManager(m_nScalePercentage),
 UNO_QUERY);
+        else
+             m_xModuleImageManager.set(xUICfgMgr->getImageManager(), 
UNO_QUERY);
         m_xModuleImageManager->addConfigurationListener( Reference< 
XUIConfigurationListener >(this) );
     }
 }
diff --git a/include/vcl/image.hxx b/include/vcl/image.hxx
index 8f3f75176396..cb537cae870b 100644
--- a/include/vcl/image.hxx
+++ b/include/vcl/image.hxx
@@ -47,6 +47,7 @@ public:
     explicit Image(StockImage, OUString const & rPNGFilePath);
 
     void setScalePercentage(sal_Int32);
+    sal_Int32 scalePercentage() const;
     Size GetSizePixel() const;
     BitmapEx GetBitmapEx() const;
 
@@ -60,6 +61,7 @@ public:
         return !(Image::operator==(rImage));
     }
 
+    bool isStock() const;
     OUString GetStock() const;
 
     void Draw(OutputDevice* pOutDev, const Point& rPos, DrawImageFlags nStyle, 
const Size* pSize = nullptr);
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 0fb2287cf342..1f8a8708502c 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -4050,8 +4050,10 @@ $(eval $(call 
gb_UnoApi_add_idlfiles,offapi,com/sun/star/ui,\
        XDecks \
        XDockingAreaAcceptor \
        XImageManager \
+       XImageManager2 \
        XModuleUIConfigurationManager \
        XModuleUIConfigurationManager2 \
+       XModuleUIConfigurationManager3 \
        XModuleUIConfigurationManagerSupplier \
        XPanel \
        XPanels \
diff --git a/offapi/com/sun/star/ui/ImageManager.idl 
b/offapi/com/sun/star/ui/ImageManager.idl
index f8b5b1a4dee0..fd6a97e637cb 100644
--- a/offapi/com/sun/star/ui/ImageManager.idl
+++ b/offapi/com/sun/star/ui/ImageManager.idl
@@ -19,7 +19,7 @@
 #ifndef __com_sun_star_ui_ImageManager_idl__
 #define __com_sun_star_ui_ImageManager_idl__
 
-#include <com/sun/star/ui/XImageManager.idl>
+#include <com/sun/star/ui/XImageManager2.idl>
 
 module com {  module sun {  module star {  module ui {
 
@@ -28,7 +28,7 @@ module com {  module sun {  module star {  module ui {
 
     @since LibreOffice 4.1
 */
-service ImageManager : XImageManager;
+service ImageManager : XImageManager2;
 
 }; }; }; }; // com.sun.star.ui
 
diff --git a/offapi/com/sun/star/ui/ModuleUIConfigurationManager.idl 
b/offapi/com/sun/star/ui/ModuleUIConfigurationManager.idl
index 3c418fadd964..eb6200f27268 100644
--- a/offapi/com/sun/star/ui/ModuleUIConfigurationManager.idl
+++ b/offapi/com/sun/star/ui/ModuleUIConfigurationManager.idl
@@ -19,7 +19,7 @@
 #ifndef __com_sun_star_ui_ModuleUIConfigurationManager_idl__
 #define __com_sun_star_ui_ModuleUIConfigurationManager_idl__
 
-#include <com/sun/star/ui/XModuleUIConfigurationManager2.idl>
+#include <com/sun/star/ui/XModuleUIConfigurationManager3.idl>
 #include <com/sun/star/configuration/CorruptedUIConfigurationException.idl>
 #include <com/sun/star/beans/UnknownPropertyException.idl>
 #include <com/sun/star/lang/WrappedTargetException.idl>
@@ -43,7 +43,7 @@ module com { module sun { module star { module ui {
     @since OOo 2.0
 */
 
-service ModuleUIConfigurationManager : XModuleUIConfigurationManager2
+service ModuleUIConfigurationManager : XModuleUIConfigurationManager3
 {
     /** provides a function to initialize a module user interface 
configuration manager instance.
 
diff --git a/offapi/com/sun/star/ui/UIConfigurationManager.idl 
b/offapi/com/sun/star/ui/UIConfigurationManager.idl
index 9b5fa98240af..2cf12f1e9795 100644
--- a/offapi/com/sun/star/ui/UIConfigurationManager.idl
+++ b/offapi/com/sun/star/ui/UIConfigurationManager.idl
@@ -19,7 +19,7 @@
 #ifndef __com_sun_star_ui_UIConfigurationManager_idl__
 #define __com_sun_star_ui_UIConfigurationManager_idl__
 
-#include <com/sun/star/ui/XUIConfigurationManager2.idl>
+#include <com/sun/star/ui/XUIConfigurationManager3.idl>
 
 module com { module sun { module star { module ui {
 
@@ -29,7 +29,7 @@ module com { module sun { module star { module ui {
     @since OOo 2.0
 */
 
-service UIConfigurationManager : XUIConfigurationManager2;
+service UIConfigurationManager : XUIConfigurationManager3;
 
 
 }; }; }; };
diff --git a/offapi/com/sun/star/ui/XImageManager.idl 
b/offapi/com/sun/star/ui/XImageManager.idl
index 1bf87c9fc15f..5e931bf13c6b 100644
--- a/offapi/com/sun/star/ui/XImageManager.idl
+++ b/offapi/com/sun/star/ui/XImageManager.idl
@@ -210,6 +210,8 @@ interface XImageManager
             com::sun::star::embed::XTransactedObject
             property which makes it possible to commit a root storage.
             </li>
+            <li><b>ScalePercentage</b> specifies the optional scaling.
+            </li>
         </ul>
     */
     interface ::com::sun::star::lang::XInitialization;
diff --git a/offapi/com/sun/star/ui/XImageManager2.idl 
b/offapi/com/sun/star/ui/XImageManager2.idl
new file mode 100644
index 000000000000..7d234ea25ecd
--- /dev/null
+++ b/offapi/com/sun/star/ui/XImageManager2.idl
@@ -0,0 +1,42 @@
+/* -*- 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/.
+ */
+
+#ifndef __com_sun_star_ui_XImageManager2_idl__
+#define __com_sun_star_ui_XImageManager2_idl__
+
+#include <com/sun/star/ui/XImageManager.idl>
+
+module com { module sun { module star { module ui {
+
+/** specifies access functions to an images manager interface to add,
+    replace and remove images associations to command URLs.
+
+    <p>
+    An image manager controls a number of image sets which are specified
+    by an ImageType.
+    </p>
+*/
+
+interface XImageManager2 : ::com::sun::star::ui::XImageManager
+{
+    /** resets the image manager to default data.
+
+        <p>
+        This means that all user images of the instance will be removed.
+        </p>
+    */
+    long scalePercentage();
+};
+
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/ui/XModuleUIConfigurationManager3.idl 
b/offapi/com/sun/star/ui/XModuleUIConfigurationManager3.idl
new file mode 100644
index 000000000000..48afd5440998
--- /dev/null
+++ b/offapi/com/sun/star/ui/XModuleUIConfigurationManager3.idl
@@ -0,0 +1,39 @@
+/* -*- 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/.
+ */
+
+#ifndef __com_sun_star_ui_XModuleUIConfigurationManager3_idl__
+#define __com_sun_star_ui_XModuleUIConfigurationManager3_idl__
+
+#include <com/sun/star/ui/XModuleUIConfigurationManager2.idl>
+
+module com { module sun { module star { module ui {
+
+/**
+    @since LibreOffice 7.4
+*/
+
+interface XModuleUIConfigurationManager3 : 
::com::sun::star::ui::XModuleUIConfigurationManager2
+{
+    /** retrieves the image manager from the user interface configuration
+        manager with a particular scaled percentage.
+
+        @param nImageType
+            specifies the image type for this operation.
+
+        @return
+            the image manager of the user interface configuration manager.
+    */
+    com::sun::star::uno::XInterface getScaledImageManager([in] short 
nScalePercentage);
+};
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/ui/XUIConfigurationManager3.idl 
b/offapi/com/sun/star/ui/XUIConfigurationManager3.idl
index c028afcd9ca6..e7604a14ccba 100644
--- a/offapi/com/sun/star/ui/XUIConfigurationManager3.idl
+++ b/offapi/com/sun/star/ui/XUIConfigurationManager3.idl
@@ -5,16 +5,6 @@
  * 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/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
 #ifndef __com_sun_star_ui_XUIConfigurationManager3_idl__
diff --git a/vcl/inc/image.h b/vcl/inc/image.h
index 373bb656ce89..3b88c376c4d3 100644
--- a/vcl/inc/image.h
+++ b/vcl/inc/image.h
@@ -41,10 +41,7 @@ public:
     ImplImage(const BitmapEx& rBitmapEx);
     ImplImage(const OUString &aStockName);
 
-    bool isStock() const
-    {
-        return maStockName.getLength() > 0;
-    }
+    bool isStock() const { return !maStockName.isEmpty(); }
 
     const OUString & getStock() const
     {
diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx
index fd38a0380000..e74d6a3bc89a 100644
--- a/vcl/qt5/QtMenu.cxx
+++ b/vcl/qt5/QtMenu.cxx
@@ -529,11 +529,14 @@ void QtMenu::SetItemImage(unsigned, SalMenuItem* pItem, 
const Image& rImage)
 
     // Save new image to use it in DoFullMenuUpdate
     pSalMenuItem->maImage = rImage;
+    if (!rImage)
+        return;
 
     QAction* pAction = pSalMenuItem->getAction();
     if (!pAction)
         return;
 
+    assert(!mpFrame || rImage.scalePercentage() == 
mpFrame->GetDPIScalePercentage());
     pAction->setIcon(QPixmap::fromImage(toQImage(rImage)));
 }
 
diff --git a/vcl/source/helper/commandinfoprovider.cxx 
b/vcl/source/helper/commandinfoprovider.cxx
index 5c280bb663c3..adc92abe476b 100644
--- a/vcl/source/helper/commandinfoprovider.cxx
+++ b/vcl/source/helper/commandinfoprovider.cxx
@@ -20,15 +20,20 @@
 #include <vcl/commandinfoprovider.hxx>
 #include <vcl/keycod.hxx>
 #include <vcl/mnemonic.hxx>
+#include <vcl/toolkit/unowrap.hxx>
+#include <vcl/window.hxx>
 #include <comphelper/string.hxx>
 #include <comphelper/sequence.hxx>
 #include <comphelper/processfactory.hxx>
+#include <comphelper/servicehelper.hxx>
 #include <cppuhelper/weakref.hxx>
 
 #include <com/sun/star/frame/XFrame.hpp>
 #include <com/sun/star/frame/ModuleManager.hpp>
 #include <com/sun/star/frame/theUICommandDescription.hpp>
 #include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager3.hpp>
+#include <com/sun/star/ui/XModuleUIConfigurationManager3.hpp>
 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
 #include <com/sun/star/ui/ImageType.hpp>
@@ -337,6 +342,14 @@ OUString GetRealCommandForCommand(const 
css::uno::Sequence<css::beans::PropertyV
     return GetCommandProperty("TargetURL", rProperties);
 }
 
+OutputDevice* lcl_getVclWindowFromFrame(const Reference<frame::XFrame>& 
rxFrame)
+{
+    const Reference<css::awt::XWindow> 
xFrameWindow(rxFrame->getContainerWindow(), UNO_SET_THROW);
+    auto pWrapper = UnoWrapperBase::GetUnoWrapper();
+    VclPtr<vcl::Window> pWindow = pWrapper->GetWindow(xFrameWindow);
+    return pWindow ? pWindow->GetOutDev() : nullptr;
+}
+
 Reference<graphic::XGraphic> GetXGraphicForCommand(const OUString& 
rsCommandName,
                                                    const 
Reference<frame::XFrame>& rxFrame,
                                                    vcl::ImageType eImageType)
@@ -351,14 +364,24 @@ Reference<graphic::XGraphic> GetXGraphicForCommand(const 
OUString& rsCommandName
     else if (eImageType == vcl::ImageType::Size32)
         nImageType |= ui::ImageType::SIZE_32;
 
+    OutputDevice* pOutDev = nullptr;
     try
     {
         Reference<frame::XController> xController(rxFrame->getController(), 
UNO_SET_THROW);
         Reference<ui::XUIConfigurationManagerSupplier> 
xSupplier(xController->getModel(), UNO_QUERY);
         if (xSupplier.is())
         {
-            Reference<ui::XUIConfigurationManager> 
xDocUICfgMgr(xSupplier->getUIConfigurationManager());
-            Reference<ui::XImageManager> 
xDocImgMgr(xDocUICfgMgr->getImageManager(), UNO_QUERY);
+            Reference<ui::XUIConfigurationManager> 
xDocUICfgMgr(xSupplier->getUIConfigurationManager(), UNO_SET_THROW);
+            pOutDev = lcl_getVclWindowFromFrame(rxFrame);
+            Reference<ui::XImageManager> xDocImgMgr;
+            if (pOutDev)
+            {
+                const sal_Int32 nScalePercentage = 
pOutDev->GetDPIScalePercentage();
+                Reference<ui::XUIConfigurationManager3> 
xDocUICfgMgr3(xDocUICfgMgr, UNO_QUERY_THROW);
+                
xDocImgMgr.set(xDocUICfgMgr3->getScaledImageManager(nScalePercentage), 
UNO_QUERY);
+            }
+            else
+                xDocImgMgr.set(xDocUICfgMgr->getImageManager(), UNO_QUERY);
 
             Sequence< Reference<graphic::XGraphic> > aGraphicSeq;
             Sequence<OUString> aImageCmdSeq { rsCommandName };
@@ -377,12 +400,20 @@ Reference<graphic::XGraphic> GetXGraphicForCommand(const 
OUString& rsCommandName
         Reference<ui::XModuleUIConfigurationManagerSupplier> 
xModuleCfgMgrSupplier(GetModuleConfigurationSupplier());
         Reference<ui::XUIConfigurationManager> 
xUICfgMgr(xModuleCfgMgrSupplier->getUIConfigurationManager(GetModuleIdentifier(rxFrame)));
 
-        Sequence< Reference<graphic::XGraphic> > aGraphicSeq;
-        Reference<ui::XImageManager> 
xModuleImageManager(xUICfgMgr->getImageManager(), UNO_QUERY);
+        Reference<ui::XImageManager> xModuleImageManager;
+        if (!pOutDev)
+            pOutDev = lcl_getVclWindowFromFrame(rxFrame);
+        if (pOutDev)
+        {
+            const sal_Int32 nScalePercentage = 
pOutDev->GetDPIScalePercentage();
+            Reference<ui::XModuleUIConfigurationManager3> 
xUICfgMgr3(xUICfgMgr, UNO_QUERY_THROW);
+            
xModuleImageManager.set(xUICfgMgr3->getScaledImageManager(nScalePercentage), 
UNO_QUERY);
+        }
+        else
+            xModuleImageManager.set(xUICfgMgr->getImageManager(), UNO_QUERY);
 
         Sequence<OUString> aImageCmdSeq { rsCommandName };
-
-        aGraphicSeq = xModuleImageManager->getImages(nImageType, aImageCmdSeq);
+        Sequence< Reference<graphic::XGraphic> > 
aGraphicSeq(xModuleImageManager->getImages(nImageType, aImageCmdSeq));
 
         Reference<graphic::XGraphic> xGraphic(aGraphicSeq[0]);
 
diff --git a/vcl/source/image/Image.cxx b/vcl/source/image/Image.cxx
index b6476c46d124..31b10b2adf3e 100644
--- a/vcl/source/image/Image.cxx
+++ b/vcl/source/image/Image.cxx
@@ -82,6 +82,13 @@ void Image::setScalePercentage(sal_Int32 nScale)
        mpImplData->setScalePercentage(nScale);
 }
 
+sal_Int32 Image::scalePercentage() const
+{
+    if (mpImplData)
+        mpImplData->GetDPIScalePercentage();
+    return -1;
+}
+
 OUString Image::GetStock() const
 {
     if (mpImplData)
@@ -89,6 +96,11 @@ OUString Image::GetStock() const
     return OUString();
 }
 
+bool Image::isStock() const
+{
+    return mpImplData ? mpImplData->isStock() : false;
+}
+
 Size Image::GetSizePixel() const
 {
     if (mpImplData)
diff --git a/vcl/source/image/ImplImage.cxx b/vcl/source/image/ImplImage.cxx
index 6daadd006f62..61bec49f7a4c 100644
--- a/vcl/source/image/ImplImage.cxx
+++ b/vcl/source/image/ImplImage.cxx
@@ -39,7 +39,7 @@ ImplImage::ImplImage(const BitmapEx &rBitmapEx)
 ImplImage::ImplImage(const OUString &aStockName)
     : maBitmapChecksum(0)
     , maStockName(aStockName)
-    , m_nScalePercentage(100)
+    , m_nScalePercentage(-1)
 {
 }
 
@@ -86,6 +86,19 @@ bool ImplImage::loadStockAtScale(BitmapEx* pBitmapEx) const
 
 sal_Int32 ImplImage::GetSgpMetric(vcl::SGPmetric eMetric) const
 {
+    using namespace vcl;
+
+    switch (eMetric)
+    {
+        case SGPmetric::DPIX:
+        case vcl::SGPmetric::DPIY:
+            return round(96 * m_nScalePercentage / 100.0);
+        case SGPmetric::ScalePercentage: return m_nScalePercentage;
+        case SGPmetric::OffScreen: return true;
+        default:
+            break;
+    }
+
     if (isStock() && maBitmapEx.IsEmpty())
     {
         if (loadStockAtScale(const_cast<BitmapEx*>(&maBitmapEx)))
@@ -97,17 +110,11 @@ sal_Int32 ImplImage::GetSgpMetric(vcl::SGPmetric eMetric) 
const
             SAL_WARN("vcl", "Failed to load stock icon " << maStockName);
     }
 
-    using namespace vcl;
     switch (eMetric)
     {
-        case vcl::SGPmetric::Width: return 
maBitmapEx.GetSizePixel().getWidth();
-        case vcl::SGPmetric::Height: return 
maBitmapEx.GetSizePixel().getHeight();
-        case vcl::SGPmetric::DPIX:
-        case vcl::SGPmetric::DPIY:
-            return round(96 * m_nScalePercentage / 100.0);
-        case vcl::SGPmetric::ScalePercentage: return m_nScalePercentage;
-        case vcl::SGPmetric::OffScreen: return true;
-        case vcl::SGPmetric::BitCount: return 
static_cast<sal_Int32>(maBitmapEx.getPixelFormat());
+        case SGPmetric::Width: return maBitmapEx.GetSizePixel().getWidth();
+        case SGPmetric::Height: return maBitmapEx.GetSizePixel().getHeight();
+        case SGPmetric::BitCount: return 
static_cast<sal_Int32>(maBitmapEx.getPixelFormat());
         default:
             return -1;
     }
@@ -147,11 +154,12 @@ bool ImplImage::isEqual(const ImplImage &ref) const
 void ImplImage::setScalePercentage(sal_Int32 nScale)
 {
     assert(nScale > 0);
-    if (m_nScalePercentage == nScale || !isStock())
+    if (m_nScalePercentage == nScale)
        return;
     SAL_WARN_IF(!maBitmapEx.IsEmpty(), "vcl", "image scale changed after 
loading(" << m_nScalePercentage << "% >> " << nScale << "%); invalidaing 
image!");
+    if (m_nScalePercentage > 0 && isStock())
+        maBitmapEx.SetEmpty();
     m_nScalePercentage = nScale;
-    maBitmapEx.SetEmpty();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/image/ImplImageTree.cxx 
b/vcl/source/image/ImplImageTree.cxx
index 5d9f1b527c38..860ec5294f84 100644
--- a/vcl/source/image/ImplImageTree.cxx
+++ b/vcl/source/image/ImplImageTree.cxx
@@ -339,7 +339,8 @@ OUString ImplImageTree::fallbackStyle(std::u16string_view 
rsStyle)
 bool ImplImageTree::loadImage(OUString const & rName, OUString const & rStyle, 
BitmapEx & rBitmap, bool localized,
                               const ImageLoadFlags eFlags, sal_Int32 
nScalePercentage)
 {
-//    assert(nScalePercentage != 100 && eFlags != 
ImageLoadFlags::IgnoreScalingFactor);
+    // debug assert to catch non-scaled images
+    assert(nScalePercentage != 100 && eFlags != 
ImageLoadFlags::IgnoreScalingFactor);
     OUString aCurrentStyle(rStyle);
     while (!aCurrentStyle.isEmpty())
     {
commit 44bd338c3911c530dddba54d8634ad35b4754503
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Apr 25 17:21:16 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Wed Apr 27 09:53:37 2022 +0200

    more work

diff --git a/framework/IwyuFilter_framework.yaml 
b/framework/IwyuFilter_framework.yaml
index 88b8dfae4ae3..441e1fbe2a77 100644
--- a/framework/IwyuFilter_framework.yaml
+++ b/framework/IwyuFilter_framework.yaml
@@ -41,6 +41,8 @@ excludelist:
     framework/source/fwe/helper/configimporter.cxx:
     # Actually used
     - com/sun/star/ui/XUIConfigurationManager2.hpp
+    # Actually used
+    - com/sun/star/ui/XUIConfigurationManager3.hpp
     framework/source/fwe/helper/undomanagerhelper.cxx:
     # Actually used
     - com/sun/star/document/XUndoManager.hpp
diff --git a/framework/source/uiconfiguration/uiconfigurationmanager.cxx 
b/framework/source/uiconfiguration/uiconfigurationmanager.cxx
index b3b443b99d5c..881bd2b8f490 100644
--- a/framework/source/uiconfiguration/uiconfigurationmanager.cxx
+++ b/framework/source/uiconfiguration/uiconfigurationmanager.cxx
@@ -40,7 +40,7 @@
 #include <com/sun/star/ui/ConfigurationEvent.hpp>
 #include <com/sun/star/ui/DocumentAcceleratorConfiguration.hpp>
 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
-#include <com/sun/star/ui/XUIConfigurationManager2.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager3.hpp>
 #include <com/sun/star/lang/XComponent.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 
@@ -71,7 +71,7 @@ namespace {
 
 class UIConfigurationManager :   public ::cppu::WeakImplHelper<
                                         css::lang::XServiceInfo  ,
-                                        css::ui::XUIConfigurationManager2 >
+                                        css::ui::XUIConfigurationManager3 >
 {
 public:
     virtual OUString SAL_CALL getImplementationName() override
@@ -124,6 +124,9 @@ public:
     virtual void SAL_CALL setStorage( const css::uno::Reference< 
css::embed::XStorage >& Storage ) override;
     virtual sal_Bool SAL_CALL hasStorage() override;
 
+    // XUIConfigurationManager3
+    virtual css::uno::Reference<css::uno::XInterface> SAL_CALL 
getScaledImageManager(::sal_Int16 nScalePercentage) override;
+
 private:
     // private data types
     enum NotifyOp
@@ -193,7 +196,7 @@ private:
     std::mutex                                                m_mutex;
     comphelper::OInterfaceContainerHelper4<css::lang::XEventListener>          
     m_aEventListeners;
     comphelper::OInterfaceContainerHelper4<css::ui::XUIConfigurationListener>  
     m_aConfigListeners;
-    rtl::Reference< ImageManager >                            m_xImageManager;
+    std::unordered_map<sal_Int16, rtl::Reference<ImageManager>> 
m_xImageManagers;
     css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xAccConfig;
 };
 
@@ -698,16 +701,17 @@ void SAL_CALL UIConfigurationManager::dispose()
 
     {
         SolarMutexGuard g;
-        try
-        {
-            if ( m_xImageManager.is() )
-                m_xImageManager->dispose();
-        }
-        catch ( const Exception& )
-        {
-        }
+        for (auto xImageManager : m_xImageManagers)
+            try
+            {
+                if (xImageManager.second.is())
+                     xImageManager.second->dispose();
+            }
+            catch (const Exception&)
+            {
+            }
 
-        m_xImageManager.clear();
+        m_xImageManagers.clear();
         m_aUIElements.clear();
         m_xDocConfigStorage.clear();
         m_bModified = false;
@@ -1115,14 +1119,18 @@ void SAL_CALL UIConfigurationManager::insertSettings( 
const OUString& NewResourc
     }
 }
 
-Reference< XInterface > SAL_CALL UIConfigurationManager::getImageManager()
+Reference< XInterface > SAL_CALL 
UIConfigurationManager::getScaledImageManager(sal_Int16 nScaleFactor)
 {
     if ( m_bDisposed )
         throw DisposedException();
 
-    if ( !m_xImageManager.is() )
+    rtl::Reference<ImageManager> xImageManager;
+
+    auto const & aManagerIter = m_xImageManagers.find(nScaleFactor);
+    if (aManagerIter == m_xImageManagers.end())
     {
-        m_xImageManager = new ImageManager( m_xContext, /*bForModule*/false );
+        xImageManager = new ImageManager(m_xContext, /*bForModule*/ false);
+        m_xImageManagers[nScaleFactor] = xImageManager;
 
         Sequence<Any> aPropSeq(comphelper::InitAnyPropertySequence(
         {
@@ -1130,10 +1138,17 @@ Reference< XInterface > SAL_CALL 
UIConfigurationManager::getImageManager()
             {"ModuleIdentifier", Any(OUString())},
         }));
 
-        m_xImageManager->initialize( aPropSeq );
+        xImageManager->initialize( aPropSeq );
     }
+    else
+        xImageManager = aManagerIter->second;
+
+    return 
Reference<XInterface>(static_cast<cppu::OWeakObject*>(xImageManager.get()), 
UNO_QUERY);
+}
 
-    return Reference< XInterface >( 
static_cast<cppu::OWeakObject*>(m_xImageManager.get()), UNO_QUERY );
+Reference<XInterface> SAL_CALL UIConfigurationManager::getImageManager()
+{
+    return getScaledImageManager(100);
 }
 
 Reference< XAcceleratorConfiguration > SAL_CALL 
UIConfigurationManager::getShortCutManager()
@@ -1187,8 +1202,9 @@ void SAL_CALL UIConfigurationManager::setStorage( const 
Reference< XStorage >& S
     if ( m_xAccConfig.is() )
         m_xAccConfig->setStorage( m_xDocConfigStorage );
 
-    if ( m_xImageManager )
-        m_xImageManager->setStorage( m_xDocConfigStorage );
+    auto const & aManagerIter = m_xImageManagers.find(100);
+    if (aManagerIter != m_xImageManagers.end())
+        aManagerIter->second->setStorage(m_xDocConfigStorage);
 
     if ( m_xDocConfigStorage.is() )
     {
diff --git a/include/vcl/image.hxx b/include/vcl/image.hxx
index 6c130bf4cd2b..8f3f75176396 100644
--- a/include/vcl/image.hxx
+++ b/include/vcl/image.hxx
@@ -46,6 +46,7 @@ public:
     explicit Image(OUString const & rPNGFileUrl);
     explicit Image(StockImage, OUString const & rPNGFilePath);
 
+    void setScalePercentage(sal_Int32);
     Size GetSizePixel() const;
     BitmapEx GetBitmapEx() const;
 
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 4c2277c1830c..1b26e492e072 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -380,8 +380,14 @@ protected:
     ///@{
 
 public:
-    SAL_DLLPRIVATE void         SetDPIX( sal_Int32 nDPIX ) { mnDPIX = nDPIX; }
-    SAL_DLLPRIVATE void         SetDPIY( sal_Int32 nDPIY ) { mnDPIY = nDPIY; }
+    SAL_DLLPRIVATE void SetDPIX(sal_Int32 nDPIX);
+    SAL_DLLPRIVATE void SetDPIY(sal_Int32 nDPIY);
+
+    /** Sets the DPI values
+     *
+     * Use <= 0 to keep the old value
+     */
+    SAL_DLLPRIVATE void SetDPI(sal_Int32 nDPIX, sal_Int32 nDPIY);
 
     OutDevType                  GetOutDevType() const { return meOutDevType; }
     virtual bool IsVirtual() const;
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index a9b92639a667..0fb2287cf342 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -4064,6 +4064,7 @@ $(eval $(call 
gb_UnoApi_add_idlfiles,offapi,com/sun/star/ui,\
        XUIConfigurationListener \
        XUIConfigurationManager \
        XUIConfigurationManager2 \
+       XUIConfigurationManager3 \
        XUIConfigurationManagerSupplier \
        XUIConfigurationPersistence \
        XUIConfigurationStorage \
diff --git a/offapi/com/sun/star/ui/XUIConfigurationManager3.idl 
b/offapi/com/sun/star/ui/XUIConfigurationManager3.idl
new file mode 100644
index 000000000000..c028afcd9ca6
--- /dev/null
+++ b/offapi/com/sun/star/ui/XUIConfigurationManager3.idl
@@ -0,0 +1,49 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef __com_sun_star_ui_XUIConfigurationManager3_idl__
+#define __com_sun_star_ui_XUIConfigurationManager3_idl__
+
+#include <com/sun/star/ui/XUIConfigurationManager2.idl>
+
+module com { module sun { module star { module ui {
+
+/**
+    @since LibreOffice 7.4
+*/
+
+interface XUIConfigurationManager3 : 
::com::sun::star::ui::XUIConfigurationManager2
+{
+    /** retrieves the image manager from the user interface configuration
+        manager with a particular scaled percentage.
+
+        @param nImageType
+            specifies the image type for this operation.
+
+        @return
+            the image manager of the user interface configuration manager.
+    */
+    com::sun::star::uno::XInterface getScaledImageManager([in] short 
nScalePercentage);
+};
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index e6e731f79ee5..6a5953447838 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -142,6 +142,8 @@ void Button::SetModeImage( const Image& rImage )
 
 Image const & Button::GetModeImage( ) const
 {
+    if (!!(mpButtonData->maImage))
+        
mpButtonData->maImage.setScalePercentage(GetOutDev()->GetDPIScalePercentage());
     return mpButtonData->maImage;
 }
 
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
index 146a4865a7a4..0241d609474b 100644
--- a/vcl/source/gdi/virdev.cxx
+++ b/vcl/source/gdi/virdev.cxx
@@ -143,6 +143,7 @@ void VirtualDevice::ImplInitVirDev( const OutputDevice* 
pOutDev,
 
     ImplSVData* pSVData = ImplGetSVData();
 
+    assert(pOutDev);
     if ( !pOutDev )
         pOutDev = ImplGetDefaultWindow()->GetOutDev();
     if( !pOutDev )
diff --git a/vcl/source/image/Image.cxx b/vcl/source/image/Image.cxx
index 1336f561fc3f..b6476c46d124 100644
--- a/vcl/source/image/Image.cxx
+++ b/vcl/source/image/Image.cxx
@@ -76,6 +76,12 @@ void Image::ImplInit(const BitmapEx& rBitmapEx)
         mpImplData = std::make_shared<ImplImage>(rBitmapEx);
 }
 
+void Image::setScalePercentage(sal_Int32 nScale)
+{
+    if (mpImplData)
+       mpImplData->setScalePercentage(nScale);
+}
+
 OUString Image::GetStock() const
 {
     if (mpImplData)
diff --git a/vcl/source/image/ImplImageTree.cxx 
b/vcl/source/image/ImplImageTree.cxx
index 94ccb84d844f..5d9f1b527c38 100644
--- a/vcl/source/image/ImplImageTree.cxx
+++ b/vcl/source/image/ImplImageTree.cxx
@@ -339,6 +339,7 @@ OUString ImplImageTree::fallbackStyle(std::u16string_view 
rsStyle)
 bool ImplImageTree::loadImage(OUString const & rName, OUString const & rStyle, 
BitmapEx & rBitmap, bool localized,
                               const ImageLoadFlags eFlags, sal_Int32 
nScalePercentage)
 {
+//    assert(nScalePercentage != 100 && eFlags != 
ImageLoadFlags::IgnoreScalingFactor);
     OUString aCurrentStyle(rStyle);
     while (!aCurrentStyle.isEmpty())
     {
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 775ff1525bbb..a2f5137d0e19 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -818,4 +818,32 @@ void OutputDevice::ImplDisposeCanvas()
     }
 }
 
+sal_Int32 lcl_updateScalePercentage(sal_Int32 nDPIX, sal_Int32 nDPIY)
+{
+     return round((nDPIX + nDPIY) * 100 / (96 * 2));
+}
+
+void OutputDevice::SetDPIX(sal_Int32 nDPIX)
+{
+    assert(nDPIX >= 0);
+    mnDPIX = nDPIX;
+    mnDPIScalePercentage = lcl_updateScalePercentage(mnDPIX, mnDPIY);
+}
+
+void OutputDevice::SetDPIY(sal_Int32 nDPIY)
+{
+    assert(nDPIY >= 0);
+    mnDPIY = nDPIY;
+    mnDPIScalePercentage = lcl_updateScalePercentage(mnDPIX, mnDPIY);
+}
+
+void OutputDevice::SetDPI(sal_Int32 nDPIX, sal_Int32 nDPIY)
+{
+    if (nDPIX > 0)
+        mnDPIX = nDPIX;
+    if (nDPIY > 0)
+        mnDPIY = nDPIY;
+    mnDPIScalePercentage = lcl_updateScalePercentage(mnDPIX, mnDPIY);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
index 64879c682d2c..4634742bd83a 100644
--- a/vcl/source/window/toolbox.cxx
+++ b/vcl/source/window/toolbox.cxx
@@ -1479,6 +1479,7 @@ bool ToolBox::ImplCalcItem()
                         // we're drawing images only
                         if ( bImage || !bText )
                         {
+                           
item.maImage.setScalePercentage(GetOutDev()->GetDPIScalePercentage());
                             item.maItemSize = item.maImage.GetSizePixel();
                         }
                         else
@@ -1499,6 +1500,7 @@ bool ToolBox::ImplCalcItem()
                         }
                         else
                         {
+                           
item.maImage.setScalePercentage(GetOutDev()->GetDPIScalePercentage());
                             item.maItemSize = item.maImage.GetSizePixel();
                         }
                     }
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 4726fcc375bb..43bb67c20edf 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -915,27 +915,6 @@ void WindowOutputDevice::ReleaseGraphics( bool bRelease )
     mpNextGraphics  = nullptr;
 }
 
-static sal_Int32 CountDPIScaleFactor(sal_Int32 nDPI)
-{
-#ifndef MACOSX
-    // Setting of HiDPI is unfortunately all only a heuristic; and to add
-    // insult to an injury, the system is constantly lying to us about
-    // the DPI and whatnot
-    // eg. fdo#77059 - set the value from which we do consider the
-    // screen HiDPI to greater than 168
-    if (nDPI > 216)      // 96 * 2   + 96 / 4
-        return 250;
-    else if (nDPI > 168) // 96 * 2   - 96 / 4
-        return 200;
-    else if (nDPI > 120) // 96 * 1.5 - 96 / 4
-        return 150;
-#else
-    (void)nDPI;
-#endif
-
-    return 100;
-}
-
 void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* 
pSystemParentData )
 {
     SAL_WARN_IF( !mpWindowImpl->mbFrame && !pParent && GetType() != 
WindowType::FIXEDIMAGE, "vcl.window",
@@ -1088,16 +1067,18 @@ void Window::ImplInit( vcl::Window* pParent, WinBits 
nStyle, SystemParentData* p
     {
         if ( pParent )
         {
-            GetOutDev()->mnDPIX = pParent->mpWindowImpl->mpFrame->GetDPIX();
-            GetOutDev()->mnDPIY = pParent->mpWindowImpl->mpFrame->GetDPIY();
+            sal_Int32 nDPIX, nDPIY;
+            pParent->mpWindowImpl->mpFrame->GetDPI(nDPIX, nDPIY);
+            GetOutDev()->SetDPI(nDPIX, nDPIY);
         }
         else
         {
             OutputDevice *pOutDev = GetOutDev();
             if ( pOutDev->AcquireGraphics() )
             {
-                GetOutDev()->mnDPIX = mpWindowImpl->mpFrame->GetDPIX();
-                GetOutDev()->mnDPIY = mpWindowImpl->mpFrame->GetDPIY();
+                sal_Int32 nDPIX, nDPIY;
+                mpWindowImpl->mpFrame->GetDPI(nDPIX, nDPIY);
+                GetOutDev()->SetDPI(nDPIX, nDPIY);
             }
         }
 
@@ -1146,11 +1127,9 @@ void Window::ImplInit( vcl::Window* pParent, WinBits 
nStyle, SystemParentData* p
     }
 
     // setup the scale factor for HiDPI displays
-#if 0
-    mpWindowImpl->mxOutDev->mnDPIScalePercentage = 
CountDPIScaleFactor(GetOutDev()->mnDPIY);
-    GetOutDev()->mnDPIX = mnDPIX;
-    mpWindowImpl->mxOutDev->mnDPIY = GetOutDev()->mnDPIY;
-#endif
+    sal_Int32 nDPIX, nDPIY;
+    mpWindowImpl->mpFrame->GetDPI(nDPIX, nDPIY);
+    GetOutDev()->SetDPI(nDPIX, nDPIY);
 
     if (!utl::ConfigManager::IsFuzzing())
     {
@@ -1351,16 +1330,17 @@ void Window::ImplInitResolutionSettings()
     if (mpWindowImpl->mbFrame)
     {
         // setup the scale factor for HiDPI displays
-        GetOutDev()->mnDPIScalePercentage = 
CountDPIScaleFactor(GetOutDev()->mnDPIY);
+        sal_Int32 nDPIX, nDPIY;
+        mpWindowImpl->mpFrame->GetDPI(nDPIX, nDPIY);
+        GetOutDev()->SetDPI(nDPIX, nDPIY);
+        SAL_DEBUG(__func__ << " " << GetOutDev()->mnDPIScalePercentage);
         const StyleSettings& rStyleSettings = 
GetOutDev()->mxSettings->GetStyleSettings();
         SetPointFont(*GetOutDev(), rStyleSettings.GetAppFont());
     }
     else if ( mpWindowImpl->mpParent )
     {
         OutputDevice *pParentOutDev = mpWindowImpl->mpParent->GetOutDev();
-        GetOutDev()->mnDPIX = pParentOutDev->mnDPIX;
-        GetOutDev()->mnDPIY = pParentOutDev->mnDPIY;
-        GetOutDev()->mnDPIScalePercentage = 
pParentOutDev->mnDPIScalePercentage;
+        GetOutDev()->SetDPI(pParentOutDev->mnDPIX, pParentOutDev->mnDPIY);
     }
 
     // update the recalculated values for logical units
@@ -2777,7 +2757,7 @@ void Window::setPosSizePixel( tools::Long nX, tools::Long 
nY,
         // Adjust resize with the hack of different client size and frame 
geometries to fix
         // native menu bars. Eventually this should be replaced by proper 
mnTopBorder usage.
         sal_Int32 nNewWidth, nNewHeight;
-       pWindow->mpWindowImpl->mpFrame->GetClientSize(nNewWidth, nNewHeight);
+        pWindow->mpWindowImpl->mpFrame->GetClientSize(nNewWidth, nNewHeight);
 
         // Resize should be called directly. If we haven't
         // set the correct size, we get a second resize from
commit c460576707a6c8f47efdc2d8010927edc7d1c2dc
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Apr 25 12:47:57 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Wed Apr 27 09:53:37 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 d584fc70f3b510e3725660050cc4457fed3530c8
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Apr 25 12:15:17 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Wed Apr 27 09:53:36 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 efe333f2b10a738c2f60f3f12c4de7642f504360
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Wed Apr 20 12:27:53 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Wed Apr 27 09:53:36 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 411a2dd4961d..ecce7fa8af21 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 02c281fea3cb..107f6a0b1948 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);
@@ -1014,12 +1022,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 c97048dada12..b0185888e77e 100644
--- a/vcl/headless/svpgdi.cxx
+++ b/vcl/headless/svpgdi.cxx
@@ -38,17 +38,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)

... etc. - the rest is truncated

Reply via email to