include/vcl/outdev.hxx | 10 -- vcl/source/outdev/bitmap.cxx | 155 +++++++++++++++++++++---------------------- 2 files changed, 76 insertions(+), 89 deletions(-)
New commits: commit 0de1d5e85efb70c2c28eedf783aaab9097460927 Author: Christopher Sherlock <chris.sherloc...@gmail.com> AuthorDate: Mon Jul 28 16:39:26 2025 +1000 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue Jul 29 13:12:12 2025 +0200 Make function that blends bitmaps be local Change-Id: I81dc7474b603e3fb1eca2d7606f71999b2f87749 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188459 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index 1b4ad3210631..9f9b04b34e93 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1461,16 +1461,6 @@ private: tools::Rectangle aDstRect, tools::Rectangle aBmpRect, Size const & aOutSz, Point const & aOutPt); - - static SAL_DLLPRIVATE Bitmap BlendBitmapWithAlpha( - Bitmap& aBmp, - BitmapReadAccess const * pP, - BitmapReadAccess const * pA, - const sal_Int32 nDstHeight, - const sal_Int32 nDstWidth, - const sal_Int32* pMapX, - const sal_Int32* pMapY ); - ///@} diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 4205188fab36..9b878363a55b 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -411,6 +411,81 @@ private: }; +// Co = Cs + Cd*(1-As) premultiplied alpha -or- +// Co = (AsCs + AdCd*(1-As)) / Ao +sal_uInt8 CalcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha, + const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor ) +{ + int c = nResAlpha ? ( static_cast<int>(nSourceAlpha)*nSourceColor + static_cast<int>(nDstAlpha)*nDestColor - + static_cast<int>(nDstAlpha)*nDestColor*nSourceAlpha/255 ) / static_cast<int>(nResAlpha) : 0; + return sal_uInt8( c ); +} + +BitmapColor AlphaBlend( int nX, int nY, + const tools::Long nMapX, + const tools::Long nMapY, + BitmapReadAccess const * pP, + BitmapReadAccess const * pA, + BitmapReadAccess const * pB) +{ + BitmapColor aDstCol,aSrcCol; + aSrcCol = pP->GetColor( nMapY, nMapX ); + aDstCol = pB->GetColor( nY, nX ); + + const sal_uInt8 nSrcAlpha = pA->GetPixelIndex( nMapY, nMapX ); + const sal_uInt8 nDstAlpha = aDstCol.GetAlpha(); + + // Perform porter-duff compositing 'over' operation + + // Co = Cs + Cd*(1-As) + // Ad = As + Ad*(1-As) + sal_uInt8 nResAlpha = static_cast<int>(nSrcAlpha) + static_cast<int>(nDstAlpha) + - static_cast<int>(nDstAlpha) * nSrcAlpha / 255; + aDstCol.SetAlpha(nResAlpha); + aDstCol.SetRed( CalcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) ); + aDstCol.SetBlue( CalcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) ); + aDstCol.SetGreen( CalcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) ); + + return aDstCol; +} + +Bitmap lcl_BlendBitmapWithAlpha( + Bitmap& aBmp, + BitmapReadAccess const * pP, + BitmapReadAccess const * pA, + const sal_Int32 nDstHeight, + const sal_Int32 nDstWidth, + const sal_Int32* pMapX, + const sal_Int32* pMapY ) + +{ + Bitmap res; + + { + BitmapScopedWriteAccess pB(aBmp); + if (pB && pP && pA) + { + for( int nY = 0; nY < nDstHeight; nY++ ) + { + const tools::Long nMapY = pMapY[ nY ]; + Scanline pScanlineB = pB->GetScanline(nY); + + for( int nX = 0; nX < nDstWidth; nX++ ) + { + const tools::Long nMapX = pMapX[ nX ]; + BitmapColor aDstCol = AlphaBlend(nX, nY, nMapX, nMapY, pP, pA, pB.get()); + + pB->SetPixelOnData(pScanlineB, nX, aDstCol); + } + } + } + pB.reset(); + res = aBmp; + } + + return res; +} + } // end anonymous namespace void OutputDevice::DrawDeviceAlphaBitmapSlowPath(const Bitmap& rBitmap, @@ -466,7 +541,7 @@ void OutputDevice::DrawDeviceAlphaBitmapSlowPath(const Bitmap& rBitmap, { Bitmap aNewBitmap; - aNewBitmap = BlendBitmapWithAlpha( + aNewBitmap = lcl_BlendBitmapWithAlpha( aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(), nDstHeight, nDstWidth, @@ -514,82 +589,4 @@ void OutputDevice::DrawImage( const Point& rPos, const Size& rSize, } } -namespace -{ - // Co = Cs + Cd*(1-As) premultiplied alpha -or- - // Co = (AsCs + AdCd*(1-As)) / Ao - sal_uInt8 CalcColor( const sal_uInt8 nSourceColor, const sal_uInt8 nSourceAlpha, - const sal_uInt8 nDstAlpha, const sal_uInt8 nResAlpha, const sal_uInt8 nDestColor ) - { - int c = nResAlpha ? ( static_cast<int>(nSourceAlpha)*nSourceColor + static_cast<int>(nDstAlpha)*nDestColor - - static_cast<int>(nDstAlpha)*nDestColor*nSourceAlpha/255 ) / static_cast<int>(nResAlpha) : 0; - return sal_uInt8( c ); - } - - BitmapColor AlphaBlend( int nX, int nY, - const tools::Long nMapX, - const tools::Long nMapY, - BitmapReadAccess const * pP, - BitmapReadAccess const * pA, - BitmapReadAccess const * pB) - { - BitmapColor aDstCol,aSrcCol; - aSrcCol = pP->GetColor( nMapY, nMapX ); - aDstCol = pB->GetColor( nY, nX ); - - const sal_uInt8 nSrcAlpha = pA->GetPixelIndex( nMapY, nMapX ); - const sal_uInt8 nDstAlpha = aDstCol.GetAlpha(); - - // Perform porter-duff compositing 'over' operation - - // Co = Cs + Cd*(1-As) - // Ad = As + Ad*(1-As) - sal_uInt8 nResAlpha = static_cast<int>(nSrcAlpha) + static_cast<int>(nDstAlpha) - - static_cast<int>(nDstAlpha) * nSrcAlpha / 255; - aDstCol.SetAlpha(nResAlpha); - aDstCol.SetRed( CalcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) ); - aDstCol.SetBlue( CalcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) ); - aDstCol.SetGreen( CalcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) ); - - return aDstCol; - } -} - -Bitmap OutputDevice::BlendBitmapWithAlpha( - Bitmap& aBmp, - BitmapReadAccess const * pP, - BitmapReadAccess const * pA, - const sal_Int32 nDstHeight, - const sal_Int32 nDstWidth, - const sal_Int32* pMapX, - const sal_Int32* pMapY ) - -{ - Bitmap res; - - { - BitmapScopedWriteAccess pB(aBmp); - if (pB && pP && pA) - { - for( int nY = 0; nY < nDstHeight; nY++ ) - { - const tools::Long nMapY = pMapY[ nY ]; - Scanline pScanlineB = pB->GetScanline(nY); - - for( int nX = 0; nX < nDstWidth; nX++ ) - { - const tools::Long nMapX = pMapX[ nX ]; - BitmapColor aDstCol = AlphaBlend(nX, nY, nMapX, nMapY, pP, pA, pB.get()); - - pB->SetPixelOnData(pScanlineB, nX, aDstCol); - } - } - } - pB.reset(); - res = aBmp; - } - - return res; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */