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 81994cb2b8 (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.kaganski@collabora.com>
Tested-by: Jenkins
This commit is contained in:
@@ -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: */
|
||||
@@ -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 )
|
||||
|
||||
Reference in New Issue
Block a user