vcl/source/bitmap/bitmap.cxx |   44 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 39 insertions(+), 5 deletions(-)

New commits:
commit 20854a6715154836e05b98d2e365f994d19ed676
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Aug 8 15:48:49 2025 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Aug 9 11:07:45 2025 +0200

    tdf#167867 Start center: transparency is missing in logo (GEN)
    
    regression from
        commit 2939f4b52d96ef0bd76896dc857f43d4de402d25
        Author: Noel Grandin <noel.gran...@collabora.co.uk>
        Date:   Tue Aug 5 08:26:05 2025 +0200
        BitmapEx->Bitmap in CanvasBitmap
    
    which flushed out the fact that the cairo/gen backend
    is being very weird when drawing images with alpha,
    which is what we are doing in
       Bitmap::Bitmap(const BitmapEx&)
    
    Hit it with a large and ugly hammer for now,
    long run we won't need this conversion.
    
    Change-Id: Ia7a09402caf2c8d19833fda828a6b3050cb90604
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189197
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx
index 72a84373d14f..4c261c862857 100644
--- a/vcl/source/bitmap/bitmap.cxx
+++ b/vcl/source/bitmap/bitmap.cxx
@@ -143,11 +143,45 @@ Bitmap::Bitmap(const BitmapEx& rBitmapEx)
         mxSalBmp = rBitmapEx.GetBitmap().mxSalBmp;
     else
     {
-        ScopedVclPtrInstance<VirtualDevice> xDev(DeviceFormat::WITH_ALPHA);
-        Size aPixelSize = rBitmapEx.GetSizePixel();
-        xDev->SetOutputSizePixel(aPixelSize, /*bErase*/true, 
/*bAlphaMaskTransparent*/true);
-        xDev->DrawBitmapEx(Point(0, 0), aPixelSize, rBitmapEx);
-        mxSalBmp = xDev->GetBitmap(Point(0,0), aPixelSize).mxSalBmp;
+        Size aSize = rBitmapEx.GetSizePixel();
+        static const BitmapPalette aPalEmpty;
+        mxSalBmp = ImplGetSVData()->mpDefInst->CreateSalBitmap();
+        mxSalBmp->Create(aSize, vcl::PixelFormat::N32_BPP, aPalEmpty);
+
+        BitmapScopedReadAccess pReadColorAcc(rBitmapEx.GetBitmap());
+        BitmapScopedReadAccess pReadAlphaAcc(rBitmapEx.GetAlphaMask());
+        BitmapScopedWriteAccess pWriteAcc(*this);
+        auto nHeight = pReadColorAcc->Height();
+        auto nWidth = pReadColorAcc->Width();
+        bool bPalette = pReadColorAcc->HasPalette();
+
+        for ( tools::Long nY = 0; nY < nHeight; nY++ )
+        {
+            Scanline pScanlineColor = pReadColorAcc->GetScanline( nY );
+            Scanline pScanlineAlpha = pReadAlphaAcc->GetScanline( nY );
+            Scanline pScanlineWrite = pWriteAcc->GetScanline( nY );
+            for (tools::Long nX = 0; nX < nWidth; ++nX)
+            {
+                BitmapColor aCol;
+                if (bPalette)
+                    aCol = 
pReadColorAcc->GetPaletteColor(pReadColorAcc->GetIndexFromData(pScanlineColor, 
nX));
+                else
+                    aCol = pReadColorAcc->GetPixelFromData(pScanlineColor, nX);
+                auto nAlpha = pReadAlphaAcc->GetPixelFromData(pScanlineAlpha, 
nX).GetIndex();
+                aCol.SetAlpha(nAlpha);
+                pWriteAcc->SetPixelOnData(pScanlineWrite, nX, aCol);
+            }
+        }
+
+// So.... in theory the following code should work, and be much more 
efficient. In practice, the gen/cairo
+// code is doing something weird involving masks that results in alpha not 
doing the same thing as on the other
+// backends.
+//        ScopedVclPtrInstance<VirtualDevice> xDev(DeviceFormat::WITH_ALPHA);
+//        Size aPixelSize = rBitmapEx.GetSizePixel();
+//        xDev->SetOutputSizePixel(aPixelSize, /*bErase*/true, 
/*bAlphaMaskTransparent*/true);
+//        xDev->DrawBitmapEx(Point(0, 0), aPixelSize, rBitmapEx);
+//        mxSalBmp = xDev->GetBitmap(Point(0,0), aPixelSize).mxSalBmp;
+
     }
 }
 

Reply via email to