svx/inc/tbxcolorupdate.hxx             |   10 ++++++++++
 svx/source/tbxctrls/tbxcolorupdate.cxx |   27 ++++++++++++++++++++++-----
 vcl/inc/image.h                        |    5 ++++-
 vcl/source/image/Image.cxx             |    2 ++
 vcl/source/image/ImplImage.cxx         |   24 ++++++++++++++++++++++--
 5 files changed, 60 insertions(+), 8 deletions(-)

New commits:
commit c3da84a10260b3260ee42df900e2ff01119e4f7c
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Nov 11 15:52:51 2022 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Fri Nov 11 20:36:14 2022 +0100

    Resolves: tdf#151898 get hidpi font/highlight color icons
    
    Most of this wouldn't be necessary if we could solve the split alpha
    problem. In the meantime, let Image take a MetaFile as an arg, record
    what we want to do in the metafile, and play it back when we need to
    generate the bitmap for to render the image. That way we don't have
    alpha to worry about during the recording, and we only have one alpha in
    the final rendering, as opposed to having two alphas in a source and in
    destination VirtualDevice, which is problematic in most backends.
    
    Change-Id: I5b0d7c498473271f4ab2743f75614b1b93a0e9c9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142593
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/svx/inc/tbxcolorupdate.hxx b/svx/inc/tbxcolorupdate.hxx
index 0ad6f502243a..d496a6921fab 100644
--- a/svx/inc/tbxcolorupdate.hxx
+++ b/svx/inc/tbxcolorupdate.hxx
@@ -83,6 +83,8 @@ namespace svx
         virtual OUString GetQuickHelpText() const = 0;
         virtual void SetImage(VirtualDevice* pVirDev) = 0;
         virtual VclPtr<VirtualDevice> CreateVirtualDevice() const = 0;
+        // true -> use Device to Record to Metafile, false -> Render to Device
+        virtual bool RecordVirtualDevice() const = 0;
         virtual vcl::ImageType GetImageSize() const = 0;
         virtual Size GetItemSize(const Size& rImageSize) const = 0;
     };
@@ -103,6 +105,10 @@ namespace svx
         virtual OUString GetQuickHelpText() const override;
         virtual void SetImage(VirtualDevice* pVirDev) override;
         virtual VclPtr<VirtualDevice> CreateVirtualDevice() const override;
+        virtual bool RecordVirtualDevice() const  override
+        {
+            return true;
+        }
         virtual vcl::ImageType GetImageSize() const override;
         virtual Size GetItemSize(const Size& rImageSize) const override;
     };
@@ -121,6 +127,10 @@ namespace svx
         virtual OUString GetQuickHelpText() const override;
         virtual void SetImage(VirtualDevice* pVirDev) override;
         virtual VclPtr<VirtualDevice> CreateVirtualDevice() const override;
+        virtual bool RecordVirtualDevice() const  override
+        {
+            return false;
+        }
         virtual vcl::ImageType GetImageSize() const override;
         virtual Size GetItemSize(const Size& rImageSize) const override;
     };
diff --git a/svx/source/tbxctrls/tbxcolorupdate.cxx 
b/svx/source/tbxctrls/tbxcolorupdate.cxx
index 37c8db06cf50..4e438c3ede9c 100644
--- a/svx/source/tbxctrls/tbxcolorupdate.cxx
+++ b/svx/source/tbxctrls/tbxcolorupdate.cxx
@@ -27,6 +27,7 @@
 
 #include <utility>
 #include <vcl/commandinfoprovider.hxx>
+#include <vcl/gdimtf.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/toolbox.hxx>
 #include <vcl/virdev.hxx>
@@ -102,15 +103,21 @@ namespace svx
 
     void VclToolboxButtonColorUpdater::SetImage(VirtualDevice* pVirDev)
     {
-        mpTbx->SetItemImage(mnBtnId, Image(pVirDev->GetBitmapEx(Point(0,0), 
maBmpSize)));
+        GDIMetaFile* pMtf = pVirDev->GetConnectMetaFile();
+
+        assert(pMtf && "should have been set in 
ToolboxButtonColorUpdaterBase::Update");
+
+        pMtf->Stop();
+        pMtf->WindStart();
+
+        Graphic aGraphic(*pMtf);
+
+        mpTbx->SetItemImage(mnBtnId, Image(aGraphic.GetXGraphic()));
     }
 
     VclPtr<VirtualDevice> VclToolboxButtonColorUpdater::CreateVirtualDevice() 
const
     {
-        auto xRet = VclPtr<VirtualDevice>::Create(*mpTbx->GetOutDev(),
-            DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
-        xRet->SetBackground(mpTbx->GetControlBackground());
-        return xRet;
+        return VclPtr<VirtualDevice>::Create(*mpTbx->GetOutDev());
     }
 
     vcl::ImageType VclToolboxButtonColorUpdater::GetImageSize() const
@@ -172,6 +179,16 @@ namespace svx
         pVirDev->SetOutputSizePixel(aItemSize);
         maBmpSize = aItemSize;
 
+        std::unique_ptr<GDIMetaFile> xMetaFile;
+        if (RecordVirtualDevice())
+        {
+            xMetaFile.reset(new GDIMetaFile);
+            xMetaFile->SetPrefSize(pVirDev->GetOutputSize());
+            xMetaFile->SetPrefMapMode(pVirDev->GetMapMode());
+            xMetaFile->Record(pVirDev.get());
+            pVirDev->EnableOutput(false);
+        }
+
         if (maBmpSize.Width() == maBmpSize.Height())
             // tdf#84985 align color bar with icon bottom edge; integer 
arithmetic e.g. 26 - 26/4 <> 26 * 3/4
             maUpdRect = tools::Rectangle(Point( 0, maBmpSize.Height() - 
maBmpSize.Height() / 4), Size(maBmpSize.Width(), maBmpSize.Height() / 4));
diff --git a/vcl/inc/image.h b/vcl/inc/image.h
index 5d0cc9fcb671..cb75b45b837d 100644
--- a/vcl/inc/image.h
+++ b/vcl/inc/image.h
@@ -21,6 +21,7 @@
 #define INCLUDED_VCL_INC_IMAGE_H
 
 #include <vcl/bitmapex.hxx>
+#include <vcl/gdimtf.hxx>
 
 class SalGraphics;
 
@@ -32,7 +33,8 @@ private:
     Size maSizePixel;
     /// If set - defines the bitmap via images.zip*
     OUString maStockName;
-
+    /// rare case of dynamically created Image contents
+    std::unique_ptr<GDIMetaFile> mxMetaFile;
 
     /// Original bitmap - or cache of a potentially scaled bitmap
     BitmapEx maBitmapEx;
@@ -42,6 +44,7 @@ private:
 
 public:
     ImplImage(const BitmapEx& rBitmapEx);
+    ImplImage(const GDIMetaFile& rMetaFile);
     ImplImage(OUString aStockName);
 
     bool isStock() const
diff --git a/vcl/source/image/Image.cxx b/vcl/source/image/Image.cxx
index 2b0a9521c8c1..06937ab7f1e5 100644
--- a/vcl/source/image/Image.cxx
+++ b/vcl/source/image/Image.cxx
@@ -47,6 +47,8 @@ Image::Image(uno::Reference<graphic::XGraphic> const & 
rxGraphic)
         OUString aPath;
         if (aGraphic.getOriginURL().startsWith("private:graphicrepository/", 
&aPath))
             mpImplData = std::make_shared<ImplImage>(aPath);
+        else if (aGraphic.GetType() == GraphicType::GdiMetafile)
+            mpImplData = 
std::make_shared<ImplImage>(aGraphic.GetGDIMetaFile());
         else
             ImplInit(aGraphic.GetBitmapEx());
     }
diff --git a/vcl/source/image/ImplImage.cxx b/vcl/source/image/ImplImage.cxx
index 7883c3b1e6f6..20469d8b4292 100644
--- a/vcl/source/image/ImplImage.cxx
+++ b/vcl/source/image/ImplImage.cxx
@@ -21,7 +21,9 @@
 #include <utility>
 #include <vcl/svapp.hxx>
 #include <vcl/bitmapex.hxx>
+#include <vcl/gdimtf.hxx>
 #include <vcl/settings.hxx>
+#include <vcl/virdev.hxx>
 #include <vcl/BitmapFilter.hxx>
 #include <vcl/ImageTree.hxx>
 #include <bitmap/BitmapDisabledImageFilter.hxx>
@@ -43,6 +45,13 @@ ImplImage::ImplImage(OUString aStockName)
 {
 }
 
+ImplImage::ImplImage(const GDIMetaFile& rMetaFile)
+    : maBitmapChecksum(0)
+    , maSizePixel(rMetaFile.GetPrefSize())
+    , mxMetaFile(new GDIMetaFile(rMetaFile))
+{
+}
+
 bool ImplImage::loadStockAtScale(SalGraphics* pGraphics, BitmapEx &rBitmapEx)
 {
     BitmapEx aBitmapEx;
@@ -142,14 +151,25 @@ bool ImplImage::isEqual(const ImplImage &ref) const
 
 BitmapEx const & ImplImage::getBitmapExForHiDPI(bool bDisabled, SalGraphics* 
pGraphics)
 {
-    if (isStock() && pGraphics)
+    if ((isStock() || mxMetaFile) && pGraphics)
     {   // check we have the right bitmap cached.
         double fScale = 1.0;
         pGraphics->ShouldDownscaleIconsAtSurface(&fScale);
         Size aTarget(maSizePixel.Width()*fScale,
                      maSizePixel.Height()*fScale);
         if (maBitmapEx.GetSizePixel() != aTarget)
-            loadStockAtScale(pGraphics, maBitmapEx);
+        {
+            if (isStock())
+                loadStockAtScale(pGraphics, maBitmapEx);
+            else // if (mxMetaFile)
+            {
+                ScopedVclPtrInstance<VirtualDevice> 
aVDev(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+                aVDev->SetOutputSizePixel(aTarget);
+                mxMetaFile->WindStart();
+                mxMetaFile->Play(*aVDev, Point(), aTarget);
+                maBitmapEx = aVDev->GetBitmapEx(Point(), aTarget);
+            }
+        }
     }
     return getBitmapEx(bDisabled);
 }

Reply via email to