vcl/inc/impgraph.hxx | 52 ++++++++ vcl/source/gdi/impgraph.cxx | 268 +++++++++++++++++++++++++------------------- 2 files changed, 203 insertions(+), 117 deletions(-)
New commits: commit 50f1900733e21e234620d852300378e301dc9f28 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Sun Jan 19 11:47:02 2025 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Sat Feb 22 03:32:34 2025 +0100 vcl: introduce BitmapContainer and use it in ImpGraphic for bitmap So we can move bitmap specific methods in this BitmapContainer including the memory managment and swapping. Change-Id: I9cec104d70da426084337ccdf2efbcdef2d8ad3f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180620 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/inc/impgraph.hxx b/vcl/inc/impgraph.hxx index 6c2df711fab0..77e89f5b02ac 100644 --- a/vcl/inc/impgraph.hxx +++ b/vcl/inc/impgraph.hxx @@ -57,15 +57,61 @@ enum class GraphicContentType : sal_Int32 Vector }; -class SAL_DLLPUBLIC_RTTI ImpGraphic final : public vcl::graphic::MemoryManaged +class SAL_DLLPUBLIC_RTTI BitmapContainer final +{ +public: + BitmapEx maBitmapEx; + + BitmapContainer() = default; + + BitmapContainer(BitmapEx const& rBitmapEx) + : maBitmapEx(rBitmapEx) + {} + + bool operator==(const BitmapContainer& rOther) const + { + return maBitmapEx == rOther.maBitmapEx; + } + + void createSwapInfo(ImpSwapInfo& rSwapInfo); + + bool isAlpha() + { + return maBitmapEx.IsAlpha(); + } + + const BitmapEx& getBitmapExRef() const + { + return maBitmapEx; + } + + Size getPrefSize() const + { + Size aSize = maBitmapEx.GetPrefSize(); + if (!aSize.Width() || !aSize.Height()) + aSize = maBitmapEx.GetSizePixel(); + return aSize; + } + + MapMode getPrefMapMode() const + { + const Size aSize = maBitmapEx.GetPrefSize(); + if (aSize.Width() && aSize.Height()) + return maBitmapEx.GetPrefMapMode(); + return {}; + } +}; + +class SAL_DLLPUBLIC_RTTI ImpGraphic final : public vcl::graphic::MemoryManaged { friend class Graphic; friend class GraphicID; private: + BitmapEx maCachedBitmap; + GDIMetaFile maMetaFile; + std::shared_ptr<BitmapContainer> mpBitmapContainer; - GDIMetaFile maMetaFile; - BitmapEx maBitmapEx; /// If maBitmapEx is empty, this preferred size will be set on it when it gets initialized. Size maExPrefSize; ImpSwapInfo maSwapInfo; diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index aaf954d71363..db073a515180 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -89,8 +89,9 @@ ImpGraphic::ImpGraphic(bool bDefault) ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) : MemoryManaged(rImpGraphic) + , maCachedBitmap(rImpGraphic.maCachedBitmap) , maMetaFile(rImpGraphic.maMetaFile) - , maBitmapEx(rImpGraphic.maBitmapEx) + , mpBitmapContainer(rImpGraphic.mpBitmapContainer) , maSwapInfo(rImpGraphic.maSwapInfo) , mpSwapFile(rImpGraphic.mpSwapFile) , mpGfxLink(rImpGraphic.mpGfxLink) @@ -108,14 +109,15 @@ ImpGraphic::ImpGraphic(const ImpGraphic& rImpGraphic) if (rImpGraphic.mpAnimation) { mpAnimation = std::make_unique<Animation>(*rImpGraphic.mpAnimation); - maBitmapEx = mpAnimation->GetBitmapEx(); + maCachedBitmap = mpAnimation->GetBitmapEx(); } } ImpGraphic::ImpGraphic(ImpGraphic&& rImpGraphic) noexcept : MemoryManaged(rImpGraphic) + , maCachedBitmap(std::move(rImpGraphic.maCachedBitmap)) , maMetaFile(std::move(rImpGraphic.maMetaFile)) - , maBitmapEx(std::move(rImpGraphic.maBitmapEx)) + , mpBitmapContainer(std::move(rImpGraphic.mpBitmapContainer)) , maSwapInfo(std::move(rImpGraphic.maSwapInfo)) , mpAnimation(std::move(rImpGraphic.mpAnimation)) , mpSwapFile(std::move(rImpGraphic.mpSwapFile)) @@ -160,7 +162,7 @@ ImpGraphic::ImpGraphic(GraphicExternalLink aGraphicExternalLink) ImpGraphic::ImpGraphic(const BitmapEx& rBitmapEx) : MemoryManaged(!rBitmapEx.IsEmpty()) - , maBitmapEx(rBitmapEx) + , mpBitmapContainer(new BitmapContainer(rBitmapEx)) , meType(rBitmapEx.IsEmpty() ? GraphicType::NONE : GraphicType::Bitmap) { ensureCurrentSizeInBytes(); @@ -176,7 +178,7 @@ ImpGraphic::ImpGraphic(const std::shared_ptr<VectorGraphicData>& rVectorGraphicD ImpGraphic::ImpGraphic(const Animation& rAnimation) : MemoryManaged(true) - , maBitmapEx(rAnimation.GetBitmapEx()) + , maCachedBitmap(rAnimation.GetBitmapEx()) , mpAnimation(std::make_unique<Animation>(rAnimation)) , meType(GraphicType::Bitmap) { @@ -195,7 +197,7 @@ ImpGraphic::~ImpGraphic() { } -ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) +ImpGraphic& ImpGraphic::operator=(const ImpGraphic& rImpGraphic) { if( &rImpGraphic != this ) { @@ -210,16 +212,19 @@ ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic ) mpAnimation.reset(); - if ( rImpGraphic.mpAnimation ) + if (rImpGraphic.mpAnimation) { - mpAnimation = std::make_unique<Animation>( *rImpGraphic.mpAnimation ); - maBitmapEx = mpAnimation->GetBitmapEx(); + mpAnimation = std::make_unique<Animation>(*rImpGraphic.mpAnimation); + maCachedBitmap = mpAnimation->GetBitmapEx(); } else { - maBitmapEx = rImpGraphic.maBitmapEx; + maCachedBitmap = rImpGraphic.maCachedBitmap; } + if (rImpGraphic.mpBitmapContainer) + mpBitmapContainer = rImpGraphic.mpBitmapContainer; + mbSwapOut = rImpGraphic.mbSwapOut; mpSwapFile = rImpGraphic.mpSwapFile; mbPrepared = rImpGraphic.mbPrepared; @@ -242,8 +247,9 @@ ImpGraphic& ImpGraphic::operator=(ImpGraphic&& rImpGraphic) mnSizeBytes = rImpGraphic.mnSizeBytes; maSwapInfo = std::move(rImpGraphic.maSwapInfo); mbDummyContext = rImpGraphic.mbDummyContext; + maCachedBitmap = std::move(rImpGraphic.maCachedBitmap); mpAnimation = std::move(rImpGraphic.mpAnimation); - maBitmapEx = std::move(rImpGraphic.maBitmapEx); + mpBitmapContainer = std::move(rImpGraphic.mpBitmapContainer); mbSwapOut = rImpGraphic.mbSwapOut; mpSwapFile = std::move(rImpGraphic.mpSwapFile); mpGfxLink = std::move(rImpGraphic.mpGfxLink); @@ -286,25 +292,21 @@ bool ImpGraphic::operator==( const ImpGraphic& rOther ) const case GraphicType::Bitmap: { - if(maVectorGraphicData) + if (maVectorGraphicData) { - if(maVectorGraphicData == rOther.maVectorGraphicData) - { + if (maVectorGraphicData == rOther.maVectorGraphicData) // equal instances bRet = true; - } - else if(rOther.maVectorGraphicData) - { + else if (rOther.maVectorGraphicData) // equal content bRet = (*maVectorGraphicData) == (*rOther.maVectorGraphicData); - } } - else if( mpAnimation ) + else if (mpAnimation && rOther.mpAnimation && *rOther.mpAnimation == *mpAnimation) { - if( rOther.mpAnimation && ( *rOther.mpAnimation == *mpAnimation ) ) - bRet = true; + bRet = true; } - else if( !rOther.mpAnimation && ( rOther.maBitmapEx == maBitmapEx ) ) + else if (mpBitmapContainer && rOther.mpBitmapContainer + && mpBitmapContainer->maBitmapEx == rOther.mpBitmapContainer->maBitmapEx) { bRet = true; } @@ -322,13 +324,32 @@ const std::shared_ptr<VectorGraphicData>& ImpGraphic::getVectorGraphicData() con return maVectorGraphicData; } +void BitmapContainer::createSwapInfo(ImpSwapInfo& rSwapInfo) +{ + rSwapInfo.maSizePixel = maBitmapEx.GetSizePixel(); + + rSwapInfo.maPrefMapMode = getPrefMapMode(); + rSwapInfo.maPrefSize = getPrefSize(); + rSwapInfo.mbIsAnimated = false; + rSwapInfo.mbIsEPS = false; + rSwapInfo.mbIsTransparent = isAlpha(); + rSwapInfo.mbIsAlpha = isAlpha(); + rSwapInfo.mnAnimationLoopCount = 0; + rSwapInfo.mnPageIndex = -1; +} + void ImpGraphic::createSwapInfo() { if (isSwappedOut()) return; - if (!maBitmapEx.IsEmpty()) - maSwapInfo.maSizePixel = maBitmapEx.GetSizePixel(); + if (mpBitmapContainer) + { + mpBitmapContainer->createSwapInfo(maSwapInfo); + return; + } + else if (!maCachedBitmap.IsEmpty()) + maSwapInfo.maSizePixel = maCachedBitmap.GetSizePixel(); else maSwapInfo.maSizePixel = Size(); @@ -344,7 +365,8 @@ void ImpGraphic::createSwapInfo() void ImpGraphic::clearGraphics() { - maBitmapEx.Clear(); + maCachedBitmap.Clear(); + mpBitmapContainer.reset(); maMetaFile.Clear(); mpAnimation.reset(); maVectorGraphicData.reset(); @@ -428,38 +450,36 @@ bool ImpGraphic::isSupportedGraphic() const bool ImpGraphic::isTransparent() const { - bool bRet(true); - if (mbSwapOut) { - bRet = maSwapInfo.mbIsTransparent; + return maSwapInfo.mbIsTransparent; } - else if (meType == GraphicType::Bitmap && !maVectorGraphicData) + else if (meType == GraphicType::Bitmap) { - bRet = mpAnimation ? mpAnimation->IsTransparent() : maBitmapEx.IsAlpha(); + if (maVectorGraphicData) + return true; + else if (mpBitmapContainer) + return mpBitmapContainer->isAlpha(); + else if (mpAnimation) + return mpAnimation->IsTransparent(); } - return bRet; + return true; } bool ImpGraphic::isAlpha() const { - bool bRet(false); - if (mbSwapOut) + return maSwapInfo.mbIsAlpha; + + if (meType == GraphicType::Bitmap) { - bRet = maSwapInfo.mbIsAlpha; - } - else if (maVectorGraphicData) - { - bRet = true; - } - else if (meType == GraphicType::Bitmap) - { - bRet = (nullptr == mpAnimation && maBitmapEx.IsAlpha()); + if (maVectorGraphicData) + return true; + else if (mpBitmapContainer) + return mpBitmapContainer->isAlpha(); } - - return bRet; + return false; } bool ImpGraphic::isAnimated() const @@ -490,20 +510,20 @@ bool ImpGraphic::makeAvailable() void ImpGraphic::updateBitmapFromVectorGraphic(const Size& pixelSize) const { assert (maVectorGraphicData); - + auto* pThisRW = const_cast<ImpGraphic*>(this); // use maBitmapEx as local buffer for rendered vector image if (pixelSize.Width() && pixelSize.Height()) { - if (maBitmapEx.IsEmpty() || maBitmapEx.GetSizePixel() != pixelSize) - const_cast<ImpGraphic*>(this)->maBitmapEx = maVectorGraphicData->getBitmap(pixelSize); + if (maCachedBitmap.IsEmpty() || maCachedBitmap.GetSizePixel() != pixelSize) + pThisRW->maCachedBitmap = maVectorGraphicData->getBitmap(pixelSize); } else // maVectorGraphicData caches the replacement, so updating unconditionally is cheap { - const_cast<ImpGraphic*>(this)->maBitmapEx = maVectorGraphicData->getReplacement(); + pThisRW->maCachedBitmap = maVectorGraphicData->getReplacement(); } if (maExPrefSize.getWidth() && maExPrefSize.getHeight()) - const_cast<ImpGraphic*>(this)->maBitmapEx.SetPrefSize(maExPrefSize); + pThisRW->maCachedBitmap.SetPrefSize(maExPrefSize); } Bitmap ImpGraphic::getBitmap(const GraphicConversionParameters& rParameters) const @@ -512,21 +532,21 @@ Bitmap ImpGraphic::getBitmap(const GraphicConversionParameters& rParameters) con ensureAvailable(); - if( meType == GraphicType::Bitmap ) + if (meType == GraphicType::Bitmap) { if (!mpAnimation && maVectorGraphicData) updateBitmapFromVectorGraphic(rParameters.getSizePixel()); - const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maBitmapEx ); + const BitmapEx& rRetBmpEx = mpAnimation ? mpAnimation->GetBitmapEx() : (mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap); - aRetBmp = rRetBmpEx.GetBitmap( COL_WHITE ); + aRetBmp = rRetBmpEx.GetBitmap(COL_WHITE); - if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) + if (rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) aRetBmp.Scale(rParameters.getSizePixel()); } else if( ( meType != GraphicType::Default ) && isSupportedGraphic() ) { - if(maBitmapEx.IsEmpty()) + if (maCachedBitmap.IsEmpty()) { // calculate size ScopedVclPtrInstance< VirtualDevice > aVDev; @@ -589,11 +609,11 @@ Bitmap ImpGraphic::getBitmap(const GraphicConversionParameters& rParameters) con draw(*aVDev, Point(), aDrawSize); // use maBitmapEx as local buffer for rendered metafile - const_cast< ImpGraphic* >(this)->maBitmapEx = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() ); + const_cast<ImpGraphic*>(this)->maCachedBitmap = aVDev->GetBitmapEx( Point(), aVDev->GetOutputSizePixel() ); } } - aRetBmp = maBitmapEx.GetBitmap(); + aRetBmp = maCachedBitmap.GetBitmap(); } if( !aRetBmp.IsEmpty() ) @@ -607,38 +627,34 @@ Bitmap ImpGraphic::getBitmap(const GraphicConversionParameters& rParameters) con BitmapEx ImpGraphic::getBitmapEx(const GraphicConversionParameters& rParameters) const { - BitmapEx aRetBmpEx; - ensureAvailable(); - if( meType == GraphicType::Bitmap ) + BitmapEx aBitmapEx; + + if (meType == GraphicType::Bitmap) { - if (!mpAnimation && maVectorGraphicData) + if (maVectorGraphicData) updateBitmapFromVectorGraphic(rParameters.getSizePixel()); - aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maBitmapEx ); + aBitmapEx = mpAnimation ? mpAnimation->GetBitmapEx() : (mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap); - if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) - { - aRetBmpEx.Scale( - rParameters.getSizePixel(), - BmpScaleFlag::Fast); - } + if (rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) + aBitmapEx.Scale(rParameters.getSizePixel(), BmpScaleFlag::Fast); } - else if( ( meType != GraphicType::Default ) && isSupportedGraphic() ) + else if (meType != GraphicType::Default && isSupportedGraphic()) { - if(maBitmapEx.IsEmpty()) + if (maCachedBitmap.IsEmpty()) { const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) ); // use maBitmapEx as local buffer for rendered metafile - const_cast< ImpGraphic* >(this)->maBitmapEx = BitmapEx(getBitmap(rParameters), aMonoMask.getBitmap(rParameters)); + const_cast<ImpGraphic*>(this)->maCachedBitmap = BitmapEx(getBitmap(rParameters), aMonoMask.getBitmap(rParameters)); } - aRetBmpEx = maBitmapEx; + aBitmapEx = maCachedBitmap; } - return aRetBmpEx; + return aBitmapEx; } Animation ImpGraphic::getAnimation() const @@ -655,7 +671,11 @@ Animation ImpGraphic::getAnimation() const const BitmapEx& ImpGraphic::getBitmapExRef() const { ensureAvailable(); - return maBitmapEx; + + if (mpBitmapContainer) + return mpBitmapContainer->getBitmapExRef(); + else + return maCachedBitmap; } const GDIMetaFile& ImpGraphic::getGDIMetaFile() const @@ -704,21 +724,23 @@ const GDIMetaFile& ImpGraphic::getGDIMetaFile() const // survive copying (change this if not wanted) ImpGraphic* pThat = const_cast< ImpGraphic* >(this); + BitmapEx aBitmapEx = mpBitmapContainer ? mpBitmapContainer->maBitmapEx : maCachedBitmap; + // #123983# directly create a metafile with the same PrefSize and PrefMapMode // the bitmap has, this will be an always correct metafile - if(maBitmapEx.IsAlpha()) + if (aBitmapEx.IsAlpha()) { - pThat->maMetaFile.AddAction(new MetaBmpExScaleAction(Point(), maBitmapEx.GetPrefSize(), maBitmapEx)); + pThat->maMetaFile.AddAction(new MetaBmpExScaleAction(Point(), aBitmapEx.GetPrefSize(), aBitmapEx)); } else { - pThat->maMetaFile.AddAction(new MetaBmpScaleAction(Point(), maBitmapEx.GetPrefSize(), maBitmapEx.GetBitmap())); + pThat->maMetaFile.AddAction(new MetaBmpScaleAction(Point(), aBitmapEx.GetPrefSize(), aBitmapEx.GetBitmap())); } pThat->maMetaFile.Stop(); pThat->maMetaFile.WindStart(); - pThat->maMetaFile.SetPrefSize(maBitmapEx.GetPrefSize()); - pThat->maMetaFile.SetPrefMapMode(maBitmapEx.GetPrefMapMode()); + pThat->maMetaFile.SetPrefSize(aBitmapEx.GetPrefSize()); + pThat->maMetaFile.SetPrefMapMode(aBitmapEx.GetPrefMapMode()); } return maMetaFile; @@ -750,7 +772,7 @@ Size ImpGraphic::getPrefSize() const { case GraphicType::Bitmap: { - if (maVectorGraphicData && maBitmapEx.IsEmpty()) + if (maVectorGraphicData && maCachedBitmap.IsEmpty()) { if (!maExPrefSize.getWidth() || !maExPrefSize.getHeight()) { @@ -765,7 +787,7 @@ Size ImpGraphic::getPrefSize() const // from MapUnit::MapPoint to MapUnit::MapTwip elsewhere // in the code. if (maVectorGraphicData->getType() == VectorGraphicDataType::Pdf) - aSize = Size(basegfx::fround(rRange.getWidth() / 20.0f), basegfx::fround(rRange.getHeight() / 20.0f)); + aSize = Size(basegfx::fround(rRange.getWidth() / 20.0f), basegfx::fround(rRange.getHeight() / 20.0f)); else #endif aSize = Size(basegfx::fround<tools::Long>(rRange.getWidth()), basegfx::fround<tools::Long>(rRange.getHeight())); @@ -775,14 +797,16 @@ Size ImpGraphic::getPrefSize() const aSize = maExPrefSize; } } - else + else if (mpAnimation || maVectorGraphicData) { - aSize = maBitmapEx.GetPrefSize(); + aSize = maCachedBitmap.GetPrefSize(); - if( !aSize.Width() || !aSize.Height() ) - { - aSize = maBitmapEx.GetSizePixel(); - } + if (!aSize.Width() || !aSize.Height()) + aSize = maCachedBitmap.GetSizePixel(); + } + else if (mpBitmapContainer) + { + aSize = mpBitmapContainer->getPrefSize(); } } break; @@ -813,16 +837,19 @@ void ImpGraphic::setValuesForPrefSize(const Size& rPrefSize) if (maVectorGraphicData) { maExPrefSize = rPrefSize; + maCachedBitmap.SetPrefSize(rPrefSize); } - // #108077# Push through pref size to animation object, // will be lost on copy otherwise - if (mpAnimation) + else if (mpAnimation) { - const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize(rPrefSize); + const_cast<BitmapEx&>(mpAnimation->GetBitmapEx()).SetPrefSize(rPrefSize); + maCachedBitmap.SetPrefSize(rPrefSize); + } + else if (mpBitmapContainer) + { + mpBitmapContainer->maBitmapEx.SetPrefSize(rPrefSize); } - - maBitmapEx.SetPrefSize(rPrefSize); } break; @@ -859,17 +886,20 @@ MapMode ImpGraphic::getPrefMapMode() const { case GraphicType::Bitmap: { - if (maVectorGraphicData && maBitmapEx.IsEmpty()) + if (maVectorGraphicData && maCachedBitmap.IsEmpty()) { // svg not yet buffered in maBitmapEx, return default PrefMapMode aMapMode = MapMode(MapUnit::Map100thMM); } + else if (mpBitmapContainer) + { + aMapMode = mpBitmapContainer->getPrefMapMode(); + } else { - const Size aSize(maBitmapEx.GetPrefSize()); - + const Size aSize = maCachedBitmap.GetPrefSize(); if (aSize.Width() && aSize.Height()) - aMapMode = maBitmapEx.GetPrefMapMode(); + aMapMode = maCachedBitmap.GetPrefMapMode(); } } break; @@ -900,16 +930,17 @@ void ImpGraphic::setValuesForPrefMapMod(const MapMode& rPrefMapMode) // ignore for Vector Graphic Data. If this is really used (except the grfcache) // it can be extended by using maBitmapEx as buffer for updateBitmapFromVectorGraphic() } - else - { - // #108077# Push through pref mapmode to animation object, - // will be lost on copy otherwise - if (mpAnimation) - { - const_cast<BitmapEx&>(mpAnimation->GetBitmapEx()).SetPrefMapMode(rPrefMapMode); - } - maBitmapEx.SetPrefMapMode(rPrefMapMode); + // #108077# Push through pref mapmode to animation object, + // will be lost on copy otherwise + else if (mpAnimation) + { + const_cast<BitmapEx&>(mpAnimation->GetBitmapEx()).SetPrefMapMode(rPrefMapMode); + maCachedBitmap.SetPrefMapMode(rPrefMapMode); + } + else if (mpBitmapContainer) + { + mpBitmapContainer->maBitmapEx.SetPrefMapMode(rPrefMapMode); } } break; @@ -963,7 +994,10 @@ sal_uLong ImpGraphic::getSizeBytes() const } else { - mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maBitmapEx.GetSizeBytes(); + if (mpAnimation) + mnSizeBytes = mpAnimation->GetSizeBytes(); + else if (mpBitmapContainer) + mnSizeBytes = mpBitmapContainer->maBitmapEx.GetSizeBytes(); } } break; @@ -1002,7 +1036,8 @@ void ImpGraphic::draw(OutputDevice& rOutDev, { if (maVectorGraphicData) updateBitmapFromVectorGraphic(rOutDev.LogicToPixel(rDestSize)); - maBitmapEx.Draw(&rOutDev, rDestPt, rDestSize); + + getBitmapExRef().Draw(&rOutDev, rDestPt, rDestSize); } } break; @@ -1167,10 +1202,10 @@ bool ImpGraphic::swapOutGraphic(SvStream& rStream) rStream.WriteInt32(sal_Int32(GraphicContentType::Animation)); WriteAnimation(rStream, *mpAnimation); } - else + else if (mpBitmapContainer) { rStream.WriteInt32(sal_Int32(GraphicContentType::Bitmap)); - WriteDIBBitmapEx(maBitmapEx, rStream); + WriteDIBBitmapEx(mpBitmapContainer->maBitmapEx, rStream); } } break; @@ -1329,14 +1364,19 @@ void ImpGraphic::updateFromLoadedGraphic(const ImpGraphic* pGraphic) { // Move over only graphic content mpAnimation.reset(); + if (pGraphic->mpAnimation) { mpAnimation = std::make_unique<Animation>(*pGraphic->mpAnimation); - maBitmapEx = mpAnimation->GetBitmapEx(); + maCachedBitmap = mpAnimation->GetBitmapEx(); + } + else if (pGraphic->mpBitmapContainer) + { + mpBitmapContainer = pGraphic->mpBitmapContainer; } else { - maBitmapEx = pGraphic->maBitmapEx; + maCachedBitmap = pGraphic->maCachedBitmap; } maMetaFile = pGraphic->maMetaFile; @@ -1546,7 +1586,7 @@ bool ImpGraphic::swapInGraphic(SvStream& rStream) ReadDIBBitmapEx(aBitmapEx, rStream); if (!rStream.GetError()) { - maBitmapEx = aBitmapEx; + mpBitmapContainer = std::make_shared<BitmapContainer>(aBitmapEx); bReturn = true; } } @@ -1559,7 +1599,7 @@ bool ImpGraphic::swapInGraphic(SvStream& rStream) if (!rStream.GetError()) { mpAnimation = std::move(pAnimation); - maBitmapEx = mpAnimation->GetBitmapEx(); + maCachedBitmap = mpAnimation->GetBitmapEx(); bReturn = true; } } @@ -1674,8 +1714,8 @@ BitmapChecksum ImpGraphic::getChecksum() const mnChecksum = maVectorGraphicData->GetChecksum(); else if (mpAnimation) mnChecksum = mpAnimation->GetChecksum(); - else - mnChecksum = maBitmapEx.GetChecksum(); + else if (mpBitmapContainer) + mnChecksum = mpBitmapContainer->maBitmapEx.GetChecksum(); } break;