framework/inc/uiconfiguration/imagemanager.hxx                    |    9 +
 framework/inc/uielement/menubarmanager.hxx                        |    1 
 framework/inc/uielement/toolbarmanager.hxx                        |    1 
 framework/source/uiconfiguration/CommandImageResolver.cxx         |   15 ++
 framework/source/uiconfiguration/CommandImageResolver.hxx         |    6 -
 framework/source/uiconfiguration/ImageList.cxx                    |    6 -
 framework/source/uiconfiguration/ImageList.hxx                    |    5 
 framework/source/uiconfiguration/imagemanager.cxx                 |    9 +
 framework/source/uiconfiguration/imagemanagerimpl.cxx             |   18 ++-
 framework/source/uiconfiguration/imagemanagerimpl.hxx             |   13 +-
 framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx |   58 
++++++----
 framework/source/uiconfiguration/uiconfigurationmanager.cxx       |    6 -
 framework/source/uielement/menubarmanager.cxx                     |   16 ++
 framework/source/uielement/toolbarmanager.cxx                     |   13 ++
 include/vcl/image.hxx                                             |    2 
 offapi/UnoApi_offapi.mk                                           |    2 
 offapi/com/sun/star/ui/ImageManager.idl                           |    4 
 offapi/com/sun/star/ui/ModuleUIConfigurationManager.idl           |    4 
 offapi/com/sun/star/ui/UIConfigurationManager.idl                 |    4 
 offapi/com/sun/star/ui/XImageManager.idl                          |    2 
 offapi/com/sun/star/ui/XImageManager2.idl                         |   42 
+++++++
 offapi/com/sun/star/ui/XModuleUIConfigurationManager3.idl         |   39 ++++++
 offapi/com/sun/star/ui/XUIConfigurationManager3.idl               |   10 -
 vcl/inc/image.h                                                   |    5 
 vcl/qt5/QtMenu.cxx                                                |    3 
 vcl/source/helper/commandinfoprovider.cxx                         |   43 
++++++-
 vcl/source/image/Image.cxx                                        |   12 ++
 vcl/source/image/ImplImage.cxx                                    |   32 +++--
 vcl/source/image/ImplImageTree.cxx                                |    3 
 29 files changed, 297 insertions(+), 86 deletions(-)

New commits:
commit 445d634cc63dd3f4541da9564a6cfbc36c25433c
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Tue Apr 26 19:39:44 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Tue Apr 26 19:39:44 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())
     {

Reply via email to