include/vcl/graphic/BitmapHelper.hxx      |   34 +++++++++
 vcl/source/graphic/UnoGraphicProvider.cxx |  104 +++++++++++++++++-------------
 2 files changed, 95 insertions(+), 43 deletions(-)

New commits:
commit ef261d4e80e784519a94b23f78ca4fb42d8bcbd9
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Nov 7 12:34:21 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Nov 8 05:35:17 2024 +0100

    Factor out conversion of awt::XBitmap to BitmapEx in vcl
    
    As a step to unify and deduplicate this in several places.
    Three functional changes added to the new vcl::GetBitmal function:
    
    1. The mask is inverted from transparency to alpha, as done in
       VCLUnoHelper::GetBitmap (toolkit/source/helper/vclunohelper.cxx)
       since commit 81994cb2b8b32453a92bcb011830fcb884f22ff3 (Convert
       internal vcl bitmap formats transparency->alpha (II), 2023-07-25).
    
    2. When awt::XBitmap::getMaskDIB returns no mask, use
       ReadDIBBitmapEx to also try to read the alpha inside the data
       in awt::XBitmap::getDIB, as done in InsertSubMenuItems
       (framework/source/fwe/helper/actiontriggerhelper.cxx).
    
    3. As an optimization, query awt::XBitmap for graphic::XGraphic
       before all the bit processing.
    
    Change-Id: I686751664a5bd612bda1d446b200a9386b1991b4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176185
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/vcl/graphic/BitmapHelper.hxx 
b/include/vcl/graphic/BitmapHelper.hxx
new file mode 100644
index 000000000000..04cb5e39ab96
--- /dev/null
+++ b/include/vcl/graphic/BitmapHelper.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * 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 <com/sun/star/uno/Reference.hxx>
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/dllapi.h>
+
+namespace com::sun::star::awt
+{
+class XBitmap;
+}
+namespace com::sun::star::uno
+{
+class Any;
+}
+
+namespace vcl
+{
+VCL_DLLPUBLIC BitmapEx GetBitmap(const css::uno::Reference<css::awt::XBitmap>& 
xBitmap);
+
+// Checks if the Any contains graphic::XGraphic; or if awt::XBitmap is there, 
converts it
+VCL_DLLPUBLIC css::uno::Reference<css::graphic::XGraphic> GetGraphic(const 
css::uno::Any& any);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/source/graphic/UnoGraphicProvider.cxx 
b/vcl/source/graphic/UnoGraphicProvider.cxx
index ad9a94baa849..84abd74f291b 100644
--- a/vcl/source/graphic/UnoGraphicProvider.cxx
+++ b/vcl/source/graphic/UnoGraphicProvider.cxx
@@ -24,6 +24,7 @@
 #include <imagerepository.hxx>
 #include <tools/fract.hxx>
 #include <unotools/ucbstreamhelper.hxx>
+#include <vcl/graphic/BitmapHelper.hxx>
 #include <vcl/graphicfilter.hxx>
 #include <vcl/stdtext.hxx>
 #include <vcl/wmfexternal.hxx>
@@ -52,6 +53,58 @@
 
 using namespace com::sun::star;
 
+namespace vcl
+{
+BitmapEx GetBitmap(const css::uno::Reference<css::awt::XBitmap>& xBitmap)
+{
+    BitmapEx aBmp;
+    if (auto xGraphic = xBitmap.query<css::graphic::XGraphic>())
+    {
+        Graphic aGraphic(xGraphic);
+        aBmp = aGraphic.GetBitmapEx();
+    }
+    else if (xBitmap)
+    {
+        // This is an unknown implementation of a XBitmap interface
+        Bitmap aMask;
+        if (css::uno::Sequence<sal_Int8> aBytes = xBitmap->getMaskDIB(); 
aBytes.hasElements())
+        {
+            SvMemoryStream aMem(aBytes.getArray(), aBytes.getLength(), 
StreamMode::READ);
+            ReadDIB(aMask, aMem, true);
+            aMask.Invert(); // Convert from transparency to alpha
+        }
+        css::uno::Sequence<sal_Int8> aBytes = xBitmap->getDIB();
+        SvMemoryStream aMem(aBytes.getArray(), aBytes.getLength(), 
StreamMode::READ);
+        if (!aMask.IsEmpty())
+        {
+            Bitmap aDIB;
+            ReadDIB(aDIB, aMem, true);
+            aBmp = BitmapEx(aDIB, aMask);
+        }
+        else
+        {
+            ReadDIBBitmapEx(aBmp, aMem, true);
+        }
+    }
+    return aBmp;
+}
+
+css::uno::Reference<css::graphic::XGraphic> GetGraphic(const css::uno::Any& 
any)
+{
+    if (auto xRet = any.query<css::graphic::XGraphic>())
+        return xRet;
+
+    if (BitmapEx aBmpEx = GetBitmap(any.query<css::awt::XBitmap>()); 
!aBmpEx.IsEmpty())
+    {
+        rtl::Reference pUnoGraphic(new unographic::Graphic);
+        pUnoGraphic->init(aBmpEx);
+        return pUnoGraphic;
+    }
+
+    return {};
+}
+}
+
 namespace {
 
 class GraphicProvider : public ::cppu::WeakImplHelper< 
css::graphic::XGraphicProvider2,
@@ -84,7 +137,6 @@ private:
 
     static css::uno::Reference< css::graphic::XGraphic > implLoadMemory( 
std::u16string_view rResourceURL );
     static css::uno::Reference< css::graphic::XGraphic > 
implLoadRepositoryImage( std::u16string_view rResourceURL );
-    static css::uno::Reference< css::graphic::XGraphic > implLoadBitmap( const 
css::uno::Reference< css::awt::XBitmap >& rBitmap );
     static css::uno::Reference< css::graphic::XGraphic > 
implLoadStandardImage( std::u16string_view rResourceURL );
 };
 
@@ -189,43 +241,11 @@ uno::Reference< ::graphic::XGraphic > 
GraphicProvider::implLoadStandardImage( st
 }
 
 
-uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadBitmap( const 
uno::Reference< awt::XBitmap >& xBtm )
-{
-    uno::Reference< ::graphic::XGraphic > xRet;
-    uno::Sequence< sal_Int8 > aBmpSeq( xBtm->getDIB() );
-    uno::Sequence< sal_Int8 > aMaskSeq( xBtm->getMaskDIB() );
-    SvMemoryStream aBmpStream( aBmpSeq.getArray(), aBmpSeq.getLength(), 
StreamMode::READ );
-    Bitmap aBmp;
-    BitmapEx aBmpEx;
-
-    ReadDIB(aBmp, aBmpStream, true);
-
-    if( aMaskSeq.hasElements() )
-    {
-        SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), 
StreamMode::READ );
-        Bitmap aMask;
-
-        ReadDIB(aMask, aMaskStream, true);
-        aBmpEx = BitmapEx( aBmp, aMask );
-    }
-    else
-        aBmpEx = BitmapEx( aBmp );
-
-    if( !aBmpEx.IsEmpty() )
-    {
-        rtl::Reference<::unographic::Graphic> pUnoGraphic = new 
::unographic::Graphic;
-
-        pUnoGraphic->init( aBmpEx );
-        xRet = pUnoGraphic;
-    }
-    return xRet;
-}
-
 uno::Reference< beans::XPropertySet > SAL_CALL 
GraphicProvider::queryGraphicDescriptor( const uno::Sequence< 
beans::PropertyValue >& rMediaProperties )
 {
     OUString aURL;
     uno::Reference< io::XInputStream > xIStm;
-    uno::Reference< awt::XBitmap >xBtm;
+    uno::Any aBtm;
 
     for( const auto& rMediaProperty : rMediaProperties )
     {
@@ -242,7 +262,7 @@ uno::Reference< beans::XPropertySet > SAL_CALL 
GraphicProvider::queryGraphicDesc
         }
         else if (aName == "Bitmap")
         {
-            aValue >>= xBtm;
+            aBtm = aValue;
         }
     }
 
@@ -276,11 +296,9 @@ uno::Reference< beans::XPropertySet > SAL_CALL 
GraphicProvider::queryGraphicDesc
             xRet = pDescriptor;
         }
     }
-    else if( xBtm.is() )
+    else if (aBtm.hasValue())
     {
-        uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) 
);
-        if( xGraphic.is() )
-            xRet.set( xGraphic, uno::UNO_QUERY );
+        xRet.set(vcl::GetGraphic(aBtm), uno::UNO_QUERY);
     }
 
     return xRet;
@@ -292,7 +310,7 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
     OUString                                aPath;
 
     uno::Reference< io::XInputStream > xIStm;
-    uno::Reference< awt::XBitmap >xBtm;
+    uno::Any aBtm;
 
     uno::Sequence< ::beans::PropertyValue > aFilterData;
 
@@ -314,7 +332,7 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
         }
         else if (aName == "Bitmap")
         {
-            aValue >>= xBtm;
+            aBtm = aValue;
         }
         else if (aName == "FilterData")
         {
@@ -375,9 +393,9 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL 
GraphicProvider::queryGraphic( co
         if( !xRet.is() )
             pIStm = ::utl::UcbStreamHelper::CreateStream( aPath, 
StreamMode::READ );
     }
-    else if( xBtm.is() )
+    else if (aBtm.hasValue())
     {
-        xRet = implLoadBitmap( xBtm );
+        xRet = vcl::GetGraphic(aBtm);
     }
 
     if( pIStm )

Reply via email to