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 )