drawinglayer/source/processor2d/vclhelperbufferdevice.cxx |    2 
 include/vcl/bitmap.hxx                                    |   42 +++
 include/vcl/outdev.hxx                                    |    8 
 include/vcl/print.hxx                                     |    2 
 vcl/backendtest/outputdevice/bitmap.cxx                   |    4 
 vcl/headless/CairoCommon.cxx                              |   35 --
 vcl/headless/SvpGraphicsBackend.cxx                       |    5 
 vcl/inc/headless/CairoCommon.hxx                          |    2 
 vcl/inc/headless/SvpGraphicsBackend.hxx                   |    2 
 vcl/inc/qt5/QtGraphics.hxx                                |    2 
 vcl/inc/quartz/salgdi.h                                   |    2 
 vcl/inc/salgdi.hxx                                        |    6 
 vcl/inc/salgdiimpl.hxx                                    |    1 
 vcl/inc/skia/gdiimpl.hxx                                  |   10 
 vcl/inc/win/salbmp.h                                      |    2 
 vcl/inc/win/salgdi.h                                      |    1 
 vcl/qa/cppunit/BackendTest.cxx                            |    9 
 vcl/qa/cppunit/outdev.cxx                                 |    6 
 vcl/qa/cppunit/skia/skia.cxx                              |    2 
 vcl/qt5/QtGraphics_GDI.cxx                                |   22 -
 vcl/quartz/AquaGraphicsBackend.cxx                        |   12 
 vcl/skia/gdiimpl.cxx                                      |  103 +------
 vcl/source/bitmap/bitmap.cxx                              |  189 ++++++++++++++
 vcl/source/gdi/print.cxx                                  |    2 
 vcl/source/gdi/salgdilayout.cxx                           |    6 
 vcl/source/outdev/bitmapex.cxx                            |   61 +---
 vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx           |    5 
 vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx           |    2 
 vcl/win/gdi/gdiimpl.cxx                                   |    5 
 vcl/win/gdi/gdiimpl.hxx                                   |    1 
 vcl/win/gdi/salbmp.cxx                                    |   44 ---
 vcl/win/gdi/salgdi_gdiplus.cxx                            |    3 
 32 files changed, 316 insertions(+), 282 deletions(-)

New commits:
commit aba63efcdb1b084c6ef68ecb8df2e648e993af13
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Mon Sep 1 13:45:41 2025 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Thu Sep 4 17:06:46 2025 +0200

    converting the SalGraphics backend from BitmapEx->Bitmap (3)
    
    pass a single SalBitmap in drawTransformedBitmap
    
    Change-Id: Iacb67804e47867f4ab85b394b14f052807925b75
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190498
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx 
b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 9358759ea90d..1e6cf9042d1b 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -547,7 +547,7 @@ void impBufferDevice::paint(double fTrans)
                                                      aSizePixel.Width(), 
aSizePixel.Height(),
                                                      maDestPixel.TopLeft().X(),
                                                      
maDestPixel.TopLeft().Y()),
-                                                 BitmapEx(aContent), 1 - 
fTrans);
+                                                 aContent, 1 - fTrans);
             }
             else
             {
diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index ce8f5450bcbd..59e6d119086b 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -183,6 +183,48 @@ public:
                             sal_Int32 nX,
                             sal_Int32 nY) const;
 
+    /** Create transformed Bitmap
+
+        @param fWidth
+        The target width in pixels
+
+        @param fHeight
+        The target height in pixels
+
+        @param rTransformation
+        The back transformation for each pixel in (0 .. fWidth),(0 .. fHeight) 
to
+        local pixel coordinates
+    */
+    [[nodiscard]]
+    Bitmap              TransformBitmap(
+                            double fWidth,
+                            double fHeight,
+                            const basegfx::B2DHomMatrix& rTransformation) 
const;
+
+    /** Create transformed Bitmap
+
+        @param rTransformation
+        The transformation from unit coordinates to the unit range
+
+        @param rVisibleRange
+        The relative visible range in unit coordinates, relative to (0,0,1,1) 
which
+        defines the whole target area
+
+        @param fMaximumArea
+        A limitation for the maximum size of pixels to use for the result
+
+        The target size of the result bitmap is defined by transforming the 
given
+        rTargetRange with the given rTransformation; the area of the result is
+        linearly scaled to not exceed the given fMaximumArea
+
+        @return The transformed bitmap
+    */
+    [[nodiscard]]
+    SAL_DLLPRIVATE Bitmap getTransformed(
+                            const basegfx::B2DHomMatrix& rTransformation,
+                            const basegfx::B2DRange& rVisibleRange,
+                            double fMaximumArea) const;
+
     /** Convert bitmap format
 
         @param eConversion
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 812a982d153f..d1bdfff13411 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1388,10 +1388,6 @@ public:
         @param fAlpha
         Optional additional alpha to use for drawing (0 to 1, 1 being no 
change).
     */
-    void                        DrawTransformedBitmapEx(
-                                    const basegfx::B2DHomMatrix& 
rTransformation,
-                                    const BitmapEx& rBitmapEx,
-                                    double fAlpha = 1.0);
     void                        DrawTransformedBitmapEx(
                                     const basegfx::B2DHomMatrix& 
rTransformation,
                                     const Bitmap& rBitmap,
@@ -1415,13 +1411,13 @@ protected:
     /** Transform and draw a bitmap directly
 
      @param     aFullTransform      The B2DHomMatrix used for the 
transformation
-     @param     rBitmapEx           Reference to the bitmap to be transformed 
and drawn
+     @param     rBitmap             Reference to the bitmap to be transformed 
and drawn
 
      @return true if it was able to draw the bitmap, false if not
      */
     virtual bool                DrawTransformBitmapExDirect(
                                     const basegfx::B2DHomMatrix& 
aFullTransform,
-                                    const BitmapEx& rBitmapEx,
+                                    const Bitmap& rBitmap,
                                     double fAlpha = 1.0);
 
     /** Transform and reduce the area that needs to be drawn of the bitmap and 
return the new
diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx
index a4d49341c9c0..9b6d4f9ad8ca 100644
--- a/include/vcl/print.hxx
+++ b/include/vcl/print.hxx
@@ -164,7 +164,7 @@ protected:
                                     const Point& rSrcPtPixel, const Size& 
rSrcSizePixel) override;
 
     bool                        DrawTransformBitmapExDirect( const 
basegfx::B2DHomMatrix& aFullTransform,
-                                    const BitmapEx& rBitmapEx, double fAlpha = 
1.0) override;
+                                    const Bitmap& rBitmap, double fAlpha = 
1.0) override;
 
     bool                        TransformAndReduceBitmapExToTargetRange( const 
basegfx::B2DHomMatrix& aFullTransform,
                                     basegfx::B2DRange &aVisibleRange, double 
&fMaximumArea) override;
diff --git a/vcl/backendtest/outputdevice/bitmap.cxx 
b/vcl/backendtest/outputdevice/bitmap.cxx
index e9a5c3b3a1c5..4ee9cc528dac 100644
--- a/vcl/backendtest/outputdevice/bitmap.cxx
+++ b/vcl/backendtest/outputdevice/bitmap.cxx
@@ -37,7 +37,7 @@ Bitmap 
OutputDeviceTestBitmap::setupDrawTransformedBitmap(vcl::PixelFormat aBitm
     aTransform.translate((maVDRectangle.GetWidth()  / 2.0) - 
(aBitmapSize.Width() / 2.0),
                          (maVDRectangle.GetHeight() / 2.0) - 
(aBitmapSize.Height() / 2.0));
 
-    mpVirtualDevice->DrawTransformedBitmapEx(aTransform, BitmapEx(aBitmap));
+    mpVirtualDevice->DrawTransformedBitmapEx(aTransform, aBitmap);
 
     return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), 
maVDRectangle.GetSize());
 }
@@ -59,7 +59,7 @@ Bitmap 
OutputDeviceTestBitmap::setupComplexDrawTransformedBitmap(vcl::PixelForma
     aTransform.scale(aBitmapSize.Width() * 2, aBitmapSize.Height() * 2);
     aTransform.translate(1, 1);
 
-    mpVirtualDevice->DrawTransformedBitmapEx(aTransform, BitmapEx(aBitmap));
+    mpVirtualDevice->DrawTransformedBitmapEx(aTransform, aBitmap);
 
     return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), 
maVDRectangle.GetSize());
 }
diff --git a/vcl/headless/CairoCommon.cxx b/vcl/headless/CairoCommon.cxx
index 9e6140b82676..a9bdff539014 100644
--- a/vcl/headless/CairoCommon.cxx
+++ b/vcl/headless/CairoCommon.cxx
@@ -1699,16 +1699,8 @@ void CairoCommon::drawAlphaBitmap(const SalTwoRect& 
rPosAry, const SalBitmap& rS
 
 bool CairoCommon::drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                         const basegfx::B2DPoint& rY, const 
SalBitmap& rSourceBitmap,
-                                        const SalBitmap* pAlphaBitmap, double 
fAlpha,
-                                        bool bAntiAlias)
+                                        double fAlpha, bool bAntiAlias)
 {
-    if (pAlphaBitmap && pAlphaBitmap->GetBitCount() != 8 && 
pAlphaBitmap->GetBitCount() != 1)
-    {
-        SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawTransformedBitmap 
alpha depth case: "
-                                << pAlphaBitmap->GetBitCount());
-        return false;
-    }
-
     if (fAlpha != 1.0)
         return false;
 
@@ -1725,26 +1717,6 @@ bool CairoCommon::drawTransformedBitmap(const 
basegfx::B2DPoint& rNull, const ba
         return false;
     }
 
-    // MM02 try to access buffered MaskHelper
-    std::shared_ptr<MaskHelper> aMask;
-    if (nullptr != pAlphaBitmap)
-    {
-        tryToUseMaskBuffer(*pAlphaBitmap, aMask);
-    }
-
-    // access cairo_surface_t from MaskHelper
-    cairo_surface_t* mask(nullptr);
-    if (aMask)
-    {
-        mask = aMask->getSurface(nDestWidth, nDestHeight);
-    }
-
-    if (nullptr != pAlphaBitmap && nullptr == mask)
-    {
-        SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawTransformedBitmap 
case");
-        return false;
-    }
-
     const Size aSize = rSourceBitmap.GetSize();
     cairo_t* cr = getCairoContext(false, bAntiAlias);
     clipRegion(cr);
@@ -1765,10 +1737,7 @@ bool CairoCommon::drawTransformedBitmap(const 
basegfx::B2DPoint& rNull, const ba
     cairo_clip(cr);
 
     cairo_set_source_surface(cr, source, 0, 0);
-    if (mask)
-        cairo_mask_surface(cr, mask, 0, 0);
-    else
-        cairo_paint(cr);
+    cairo_paint(cr);
 
     releaseCairoContext(cr, false, extents);
 
diff --git a/vcl/headless/SvpGraphicsBackend.cxx 
b/vcl/headless/SvpGraphicsBackend.cxx
index 14b5d72b0423..c6dad28b31f4 100644
--- a/vcl/headless/SvpGraphicsBackend.cxx
+++ b/vcl/headless/SvpGraphicsBackend.cxx
@@ -214,10 +214,9 @@ void SvpGraphicsBackend::drawAlphaBitmap(const SalTwoRect& 
rTR, const SalBitmap&
 bool SvpGraphicsBackend::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
                                                const basegfx::B2DPoint& rX,
                                                const basegfx::B2DPoint& rY,
-                                               const SalBitmap& rSourceBitmap,
-                                               const SalBitmap* pAlphaBitmap, 
double fAlpha)
+                                               const SalBitmap& rSourceBitmap, 
double fAlpha)
 {
-    return m_rCairoCommon.drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
pAlphaBitmap, fAlpha,
+    return m_rCairoCommon.drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
fAlpha,
                                                 getAntiAlias());
 }
 
diff --git a/vcl/inc/headless/CairoCommon.hxx b/vcl/inc/headless/CairoCommon.hxx
index 8b8eb9763797..a81100df7b98 100644
--- a/vcl/inc/headless/CairoCommon.hxx
+++ b/vcl/inc/headless/CairoCommon.hxx
@@ -218,7 +218,7 @@ struct VCL_DLLPUBLIC CairoCommon
 
     bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                const basegfx::B2DPoint& rY, const SalBitmap& 
rSourceBitmap,
-                               const SalBitmap* pAlphaBitmap, double fAlpha, 
bool bAntiAlias);
+                               double fAlpha, bool bAntiAlias);
 
     void drawMask(const SalTwoRect& rTR, const SalBitmap& rSalBitmap, Color 
nMaskColor,
                   bool bAntiAlias);
diff --git a/vcl/inc/headless/SvpGraphicsBackend.hxx 
b/vcl/inc/headless/SvpGraphicsBackend.hxx
index b388b8a9245a..8bc8721e55c2 100644
--- a/vcl/inc/headless/SvpGraphicsBackend.hxx
+++ b/vcl/inc/headless/SvpGraphicsBackend.hxx
@@ -103,7 +103,7 @@ public:
 
     bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                const basegfx::B2DPoint& rY, const SalBitmap& 
rSourceBitmap,
-                               const SalBitmap* pAlphaBitmap, double fAlpha) 
override;
+                               double fAlpha) override;
 
     bool drawAlphaRect(tools::Long nX, tools::Long nY, tools::Long nWidth, 
tools::Long nHeight,
                        sal_uInt8 nTransparency) override;
diff --git a/vcl/inc/qt5/QtGraphics.hxx b/vcl/inc/qt5/QtGraphics.hxx
index 6bd243d8d077..b049134a2a87 100644
--- a/vcl/inc/qt5/QtGraphics.hxx
+++ b/vcl/inc/qt5/QtGraphics.hxx
@@ -132,7 +132,7 @@ public:
 
     bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                const basegfx::B2DPoint& rY, const SalBitmap& 
rSourceBitmap,
-                               const SalBitmap* pAlphaBitmap, double fAlpha) 
override;
+                               double fAlpha) override;
 
     bool drawAlphaRect(tools::Long nX, tools::Long nY, tools::Long nWidth, 
tools::Long nHeight,
                        sal_uInt8 nTransparency) override;
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 2cbfa4392450..8ef5f4dbd807 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -344,7 +344,7 @@ public:
 
     bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                const basegfx::B2DPoint& rY, const SalBitmap& 
rSourceBitmap,
-                               const SalBitmap* pAlphaBitmap, double fAlpha) 
override;
+                               double fAlpha) override;
 
     bool drawAlphaRect(tools::Long nX, tools::Long nY, tools::Long nWidth, 
tools::Long nHeight,
                        sal_uInt8 nTransparency) override;
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 64c858fdfb6a..d2e98d540033 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -363,7 +363,6 @@ public:
                                     const basegfx::B2DPoint& rX,
                                     const basegfx::B2DPoint& rY,
                                     const SalBitmap& rSourceBitmap,
-                                    const SalBitmap* pAlphaBitmap,
                                     double fAlpha,
                                     const OutputDevice& rOutDev );
 
@@ -521,7 +520,6 @@ protected:
                                     const basegfx::B2DPoint& rX,
                                     const basegfx::B2DPoint& rY,
                                     const SalBitmap& rSourceBitmap,
-                                    const SalBitmap* pAlphaBitmap,
                                     double fAlpha) = 0;
 
     /// Returns true if the drawTransformedBitmap() call is fast, and so it 
should
@@ -793,9 +791,9 @@ public:
                                                  const basegfx::B2DPoint& rX,
                                                  const basegfx::B2DPoint& rY,
                                                  const SalBitmap& 
rSourceBitmap,
-                                                 const SalBitmap* 
pAlphaBitmap, double fAlpha) override
+                                                 double fAlpha) override
     {
-        return GetImpl()->drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
pAlphaBitmap, fAlpha);
+        return GetImpl()->drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
fAlpha);
     }
 
     bool hasFastDrawTransformedBitmap() const override
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 3f6c20785db6..46cd219e191a 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -185,7 +185,6 @@ public:
                 const basegfx::B2DPoint& rX,
                 const basegfx::B2DPoint& rY,
                 const SalBitmap& rSourceBitmap,
-                const SalBitmap* pAlphaBitmap,
                 double fAlpha) = 0;
 
     /// Only currently true for SkiaSalGraphicsImpl
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index ff9d68e9f7f8..ee14d6e86121 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -150,7 +150,7 @@ public:
     /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the 
coordinate system */
     virtual bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                        const basegfx::B2DPoint& rY, const 
SalBitmap& rSourceBitmap,
-                                       const SalBitmap* pAlphaBitmap, double 
fAlpha) override;
+                                       double fAlpha) override;
 
     virtual bool hasFastDrawTransformedBitmap() const override;
 
@@ -251,12 +251,10 @@ protected:
     void setCanvasScalingAndClipping();
     void resetCanvasScalingAndClipping();
     static void setCanvasClipRegion(SkCanvas* canvas, const vcl::Region& 
region);
-    sk_sp<SkImage> mergeCacheBitmaps(const SkiaSalBitmap& bitmap, const 
SkiaSalBitmap* alphaBitmap,
-                                     const Size& targetSize);
+    sk_sp<SkImage> mergeCacheBitmaps(const SkiaSalBitmap& bitmap, const Size& 
targetSize);
     using DirectImage = SkiaHelper::DirectImage;
-    static OString makeCachedImageKey(const SkiaSalBitmap& bitmap, const 
SkiaSalBitmap* alphaBitmap,
-                                      const Size& targetSize, DirectImage 
bitmapType,
-                                      DirectImage alphaBitmapType);
+    static OString makeCachedImageKey(const SkiaSalBitmap& bitmap, const Size& 
targetSize,
+                                      DirectImage bitmapType);
 
     // Skia uses floating point coordinates, so when we use integer 
coordinates, sometimes
     // rounding results in off-by-one errors (down), especially when drawing 
using GPU,
diff --git a/vcl/inc/win/salbmp.h b/vcl/inc/win/salbmp.h
index a6786cb9c649..200051bf64f1 100644
--- a/vcl/inc/win/salbmp.h
+++ b/vcl/inc/win/salbmp.h
@@ -50,7 +50,7 @@ public:
     void*               ImplGethDIB() const { return mpDIB; }
     HBITMAP             ImplGethDDB() const { return mhDDB; }
 
-    std::shared_ptr< Gdiplus::Bitmap > ImplGetGdiPlusBitmap(const 
WinSalBitmap* pAlphaSource = nullptr) const;
+    std::shared_ptr< Gdiplus::Bitmap > ImplGetGdiPlusBitmap() const;
 
     static void         ImplCreateDIB( const Size& rSize, vcl::PixelFormat 
ePixelFormat, const BitmapPalette& rPal,
                                        void*& rpDIB, sal_Int32 &rnDIBSize );
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 8904b8627ee5..ee862664fdb5 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -126,7 +126,6 @@ public:
                            const basegfx::B2DPoint& rX,
                            const basegfx::B2DPoint& rY,
                            const SalBitmap& rSourceBitmap,
-                           const SalBitmap* pAlphaBitmap,
                            double fAlpha) override;
 
     virtual bool       hasFastDrawTransformedBitmap() const override;
diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 3fa34f429433..212baaf49cdf 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -653,12 +653,11 @@ public:
                 for (int j = 0; j < 8; ++j)
                     pWriteAccess->SetPixel(j, i, COL_BLACK);
         }
-        BitmapEx aBitmapEx(aBitmap);
         basegfx::B2DHomMatrix aMatrix;
         // Draw with no transformation, only alpha change.
         aMatrix.scale(16, 16);
-        device->DrawTransformedBitmapEx(aMatrix, aBitmapEx, 0.5);
-        BitmapEx result(device->GetBitmap(Point(0, 0), Size(16, 16)));
+        device->DrawTransformedBitmapEx(aMatrix, aBitmap, 0.5);
+        Bitmap result(device->GetBitmap(Point(0, 0), Size(16, 16)));
         CPPUNIT_ASSERT_EQUAL(COL_GRAY, result.GetPixelColor(0, 0));
         CPPUNIT_ASSERT_EQUAL(COL_WHITE, result.GetPixelColor(15, 15));
         // Draw rotated and move to the bottom-left corner.
@@ -667,7 +666,7 @@ public:
         aMatrix.scale(16, 16);
         aMatrix.rotate(M_PI / 2);
         aMatrix.translate(8, 8);
-        device->DrawTransformedBitmapEx(aMatrix, aBitmapEx, 0.5);
+        device->DrawTransformedBitmapEx(aMatrix, aBitmap, 0.5);
         result = device->GetBitmap(Point(0, 0), Size(16, 16));
         CPPUNIT_ASSERT_EQUAL(COL_WHITE, result.GetPixelColor(0, 0));
         CPPUNIT_ASSERT_EQUAL(COL_GRAY, result.GetPixelColor(0, 15));
@@ -1401,7 +1400,7 @@ public:
                      bitmap.GetSizePixel().Height()); // draw as 10x10
         // Draw a blue bitmap to the device. The bug was that there was no 
alpha, but OutputDevice::DrawTransformBitmapExDirect()
         // supplied a fully opaque alpha done with Erase() on the alpha 
bitmap, and Skia backend didn't handle such alpha correctly.
-        device->DrawTransformedBitmapEx(matrix, BitmapEx(bitmap));
+        device->DrawTransformedBitmapEx(matrix, bitmap);
         exportDevice(u"tdf136171.png"_ustr, device);
         // The whole virtual device content now should be blue.
         CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(0, 0)));
diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx
index 040f4d91231a..a1af25f17805 100644
--- a/vcl/qa/cppunit/outdev.cxx
+++ b/vcl/qa/cppunit/outdev.cxx
@@ -356,7 +356,6 @@ CPPUNIT_TEST_FIXTURE(VclOutdevTest, 
testDrawTransformedBitmapEx)
             }
         }
     }
-    BitmapEx aBitmapEx(aBitmap);
     basegfx::B2DHomMatrix aMatrix;
     aMatrix.scale(8, 8);
     // Rotate 90 degrees clockwise, so the black part goes to the top right.
@@ -365,7 +364,7 @@ CPPUNIT_TEST_FIXTURE(VclOutdevTest, 
testDrawTransformedBitmapEx)
     aMtf.Record(pVDev.get());
 
     // Draw the rotated bitmap on the vdev.
-    pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx);
+    pVDev->DrawTransformedBitmapEx(aMatrix, aBitmap);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMtf.GetActionSize());
     MetaAction* pAction = aMtf.GetAction(0);
     CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType());
@@ -420,7 +419,6 @@ CPPUNIT_TEST_FIXTURE(VclOutdevTest, 
testDrawTransformedBitmapExFlip)
             }
         }
     }
-    BitmapEx aBitmapEx(aBitmap);
     basegfx::B2DHomMatrix aMatrix;
     // Negative y scale: bitmap should be upside down, so the black part goes 
to the bottom left.
     aMatrix.scale(8, -8);
@@ -430,7 +428,7 @@ CPPUNIT_TEST_FIXTURE(VclOutdevTest, 
testDrawTransformedBitmapExFlip)
     aMtf.Record(pVDev.get());
 
     // Draw the scaled and rotated bitmap on the vdev.
-    pVDev->DrawTransformedBitmapEx(aMatrix, aBitmapEx);
+    pVDev->DrawTransformedBitmapEx(aMatrix, aBitmap);
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aMtf.GetActionSize());
     MetaAction* pAction = aMtf.GetAction(0);
     CPPUNIT_ASSERT_EQUAL(MetaActionType::BMPEXSCALE, pAction->GetType());
diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx
index 8768699d3f70..1d1ec471b91d 100644
--- a/vcl/qa/cppunit/skia/skia.cxx
+++ b/vcl/qa/cppunit/skia/skia.cxx
@@ -149,7 +149,7 @@ void SkiaTest::testDrawShaders()
     basegfx::B2DHomMatrix matrix;
     matrix.scale(10, 10);
     matrix.rotate(M_PI / 4);
-    device->DrawTransformedBitmapEx(matrix, BitmapEx(bitmap, alpha));
+    device->DrawTransformedBitmapEx(matrix, Bitmap(bitmap, alpha));
     //savePNG("/tmp/a3.png", device);
     CPPUNIT_ASSERT_EQUAL(resultRed, device->GetPixel(Point(0, 1)));
     CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(1, 0)));
diff --git a/vcl/qt5/QtGraphics_GDI.cxx b/vcl/qt5/QtGraphics_GDI.cxx
index 06a2ad33dce6..54592258ee64 100644
--- a/vcl/qt5/QtGraphics_GDI.cxx
+++ b/vcl/qt5/QtGraphics_GDI.cxx
@@ -559,19 +559,6 @@ void QtGraphicsBackend::invert(sal_uInt32 /*nPoints*/, 
const Point* /*pPtAry*/,
 {
 }
 
-static QImage getAlphaImage(const SalBitmap& rSourceBitmap, const SalBitmap& 
rAlphaBitmap)
-{
-    assert(rSourceBitmap.GetSize() == rAlphaBitmap.GetSize());
-    assert(rAlphaBitmap.GetBitCount() == 8 || rAlphaBitmap.GetBitCount() == 1);
-
-    QImage aAlphaMask = *static_cast<const 
QtBitmap*>(&rAlphaBitmap)->GetQImage();
-
-    const QImage* pBitmap = static_cast<const 
QtBitmap*>(&rSourceBitmap)->GetQImage();
-    QImage aImage = pBitmap->convertToFormat(Qt_DefaultFormat32);
-    aImage.setAlphaChannel(aAlphaMask);
-    return aImage;
-}
-
 void QtGraphicsBackend::drawAlphaBitmap(const SalTwoRect& rPosAry, const 
SalBitmap& rSourceBitmap)
 {
     drawBitmap(rPosAry, rSourceBitmap);
@@ -580,14 +567,9 @@ void QtGraphicsBackend::drawAlphaBitmap(const SalTwoRect& 
rPosAry, const SalBitm
 bool QtGraphicsBackend::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
                                               const basegfx::B2DPoint& rX,
                                               const basegfx::B2DPoint& rY,
-                                              const SalBitmap& rSourceBitmap,
-                                              const SalBitmap* pAlphaBitmap, 
double fAlpha)
+                                              const SalBitmap& rSourceBitmap, 
double fAlpha)
 {
-    QImage aImage;
-    if (!pAlphaBitmap)
-        aImage = *static_cast<const QtBitmap*>(&rSourceBitmap)->GetQImage();
-    else
-        aImage = getAlphaImage(rSourceBitmap, *pAlphaBitmap);
+    QImage aImage = *static_cast<const QtBitmap*>(&rSourceBitmap)->GetQImage();
 
     const basegfx::B2DVector aXRel = rX - rNull;
     const basegfx::B2DVector aYRel = rY - rNull;
diff --git a/vcl/quartz/AquaGraphicsBackend.cxx 
b/vcl/quartz/AquaGraphicsBackend.cxx
index 4f0ffc6c130e..7aaa9cddd63f 100644
--- a/vcl/quartz/AquaGraphicsBackend.cxx
+++ b/vcl/quartz/AquaGraphicsBackend.cxx
@@ -1216,8 +1216,7 @@ void AquaGraphicsBackend::drawAlphaBitmap(const 
SalTwoRect& rPosAry, const SalBi
 bool AquaGraphicsBackend::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
                                                 const basegfx::B2DPoint& rX,
                                                 const basegfx::B2DPoint& rY,
-                                                const SalBitmap& rSrcBitmap,
-                                                const SalBitmap* pAlphaBmp, 
double fAlpha)
+                                                const SalBitmap& rSrcBitmap, 
double fAlpha)
 {
     if (!mrShared.checkContext())
         return true;
@@ -1226,14 +1225,9 @@ bool AquaGraphicsBackend::drawTransformedBitmap(const 
basegfx::B2DPoint& rNull,
         return false;
 
     // get the Quartz image
-    CGImageRef xImage = nullptr;
     const Size aSize = rSrcBitmap.GetSize();
-
-    if (!pAlphaBmp)
-        xImage = rSrcBitmap.CreateCroppedImage(0, 0, int(aSize.Width()), 
int(aSize.Height()));
-    else
-        xImage
-            = rSrcBitmap.CreateWithMask(*pAlphaBmp, 0, 0, int(aSize.Width()), 
int(aSize.Height()));
+    CGImageRef xImage
+        = rSrcBitmap.CreateCroppedImage(0, 0, int(aSize.Width()), 
int(aSize.Height()));
 
     if (!xImage)
         return false;
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index f123237c9b3d..629ab7552588 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -1532,17 +1532,11 @@ void SkiaSalGraphicsImpl::invert(sal_uInt32 nPoints, 
const Point* pPointArray, S
 // with the given target size. Result will be possibly cached, unless disabled.
 // Especially in raster mode scaling and alpha blending may be expensive if 
done repeatedly.
 sk_sp<SkImage> SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& 
bitmap,
-                                                      const SkiaSalBitmap* 
alphaBitmap,
                                                       const Size& targetSize)
 {
-    if (alphaBitmap)
-        assert(bitmap.GetSize() == alphaBitmap->GetSize());
-
     if (targetSize.IsEmpty())
         return {};
-    if (alphaBitmap && alphaBitmap->IsFullyOpaqueAsAlpha())
-        alphaBitmap = nullptr; // the alpha can be ignored
-    if (bitmap.PreferSkShader() && (!alphaBitmap || 
alphaBitmap->PreferSkShader()))
+    if (bitmap.PreferSkShader())
         return {};
 
     // If the bitmap has SkImage that matches the required size, try to use 
it, even
@@ -1551,48 +1545,18 @@ sk_sp<SkImage> 
SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitma
     // scale, changing GetImageKey() in the process so we'd have to re-cache, 
and then we'd need
     // to scale again in this function.
     bool bitmapReady = false;
-    bool alphaBitmapReady = false;
     if (const sk_sp<SkImage>& image = bitmap.GetSkImage(DirectImage::Yes))
     {
         assert(!bitmap.PreferSkShader());
         if (imageSize(image) == targetSize)
             bitmapReady = true;
     }
-    // If the image usable and there's no alpha, then it matches exactly 
what's wanted.
-    if (bitmapReady && !alphaBitmap)
+    // If the image usable, then it matches exactly what's wanted.
+    if (bitmapReady)
         return bitmap.GetSkImage(DirectImage::Yes);
-    if (alphaBitmap)
-    {
-        if (!alphaBitmap->GetAlphaSkImage(DirectImage::Yes)
-            && alphaBitmap->GetSkImage(DirectImage::Yes)
-            && imageSize(alphaBitmap->GetSkImage(DirectImage::Yes)) == 
targetSize)
-        {
-            // There's a usable non-alpha image, try to convert it to alpha.
-            assert(!alphaBitmap->PreferSkShader());
-            
const_cast<SkiaSalBitmap*>(alphaBitmap)->TryDirectConvertToAlphaNoScaling();
-        }
-        if (const sk_sp<SkImage>& image = 
alphaBitmap->GetAlphaSkImage(DirectImage::Yes))
-        {
-            assert(!alphaBitmap->PreferSkShader());
-            if (imageSize(image) == targetSize)
-                alphaBitmapReady = true;
-        }
-    }
-
-    if (bitmapReady && (!alphaBitmap || alphaBitmapReady))
-    {
-        // Try to find a cached image based on the already existing images.
-        OString key = makeCachedImageKey(bitmap, alphaBitmap, targetSize, 
DirectImage::Yes,
-                                         DirectImage::Yes);
-        if (sk_sp<SkImage> image = findCachedImage(key))
-        {
-            assert(imageSize(image) == targetSize);
-            return image;
-        }
-    }
 
     // Probably not much point in caching of just doing a copy.
-    if (alphaBitmap == nullptr && targetSize == bitmap.GetSize())
+    if (targetSize == bitmap.GetSize())
         return {};
     // Image too small to be worth caching if not scaling.
     if (targetSize == bitmap.GetSize() && targetSize.Width() < 100 && 
targetSize.Height() < 100)
@@ -1616,17 +1580,11 @@ sk_sp<SkImage> 
SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitma
     // that they are the same size, or that one prefers a shader or doesn't 
exist
     // (i.e. avoid two images of different size).
     bitmapReady = bitmap.GetSkImage(DirectImage::Yes) != nullptr;
-    alphaBitmapReady = alphaBitmap && 
alphaBitmap->GetAlphaSkImage(DirectImage::Yes) != nullptr;
-    if (bitmapReady && alphaBitmap && !alphaBitmapReady && 
!alphaBitmap->PreferSkShader())
-        bitmapReady = false;
-    if (alphaBitmapReady && !bitmapReady && bitmap.PreferSkShader())
-        alphaBitmapReady = false;
 
     DirectImage bitmapType = bitmapReady ? DirectImage::Yes : DirectImage::No;
-    DirectImage alphaBitmapType = alphaBitmapReady ? DirectImage::Yes : 
DirectImage::No;
 
     // Try to find a cached result, this time after possible delayed scaling.
-    OString key = makeCachedImageKey(bitmap, alphaBitmap, targetSize, 
bitmapType, alphaBitmapType);
+    OString key = makeCachedImageKey(bitmap, targetSize, bitmapType);
     if (sk_sp<SkImage> image = findCachedImage(key))
     {
         assert(imageSize(image) == targetSize);
@@ -1666,14 +1624,11 @@ sk_sp<SkImage> 
SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitma
     Size sourceSize;
     if (bitmapReady)
         sourceSize = imageSize(bitmap.GetSkImage(DirectImage::Yes));
-    else if (alphaBitmapReady)
-        sourceSize = imageSize(alphaBitmap->GetAlphaSkImage(DirectImage::Yes));
     else
         sourceSize = bitmap.GetSize();
 
     // Generate a new result and cache it.
-    sk_sp<SkSurface> tmpSurface
-        = createSkSurface(targetSize, alphaBitmap ? kPremul_SkAlphaType : 
bitmap.alphaType());
+    sk_sp<SkSurface> tmpSurface = createSkSurface(targetSize, 
bitmap.alphaType());
     if (!tmpSurface)
         return nullptr;
     SkCanvas* canvas = tmpSurface->getCanvas();
@@ -1690,12 +1645,10 @@ sk_sp<SkImage> 
SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitma
             if (!isUnitTestRunning()) // unittests want exact pixel values
                 samplingOptions = makeSamplingOptions(matrix, 1);
         }
-        if (alphaBitmap != nullptr)
+        if (bitmap.alphaType() == kPremul_SkAlphaType)
         {
             canvas->clear(SK_ColorTRANSPARENT);
-            paint.setShader(SkShaders::Blend(
-                SkBlendMode::kDstIn, bitmap.GetSkShader(samplingOptions, 
bitmapType),
-                alphaBitmap->GetAlphaSkShader(samplingOptions, 
alphaBitmapType)));
+            paint.setShader(bitmap.GetSkShader(samplingOptions, bitmapType));
             canvas->drawPaint(paint);
         }
         else if (bitmap.PreferSkShader())
@@ -1715,15 +1668,11 @@ sk_sp<SkImage> 
SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitma
     return image;
 }
 
-OString SkiaSalGraphicsImpl::makeCachedImageKey(const SkiaSalBitmap& bitmap,
-                                                const SkiaSalBitmap* 
alphaBitmap,
-                                                const Size& targetSize, 
DirectImage bitmapType,
-                                                DirectImage alphaBitmapType)
+OString SkiaSalGraphicsImpl::makeCachedImageKey(const SkiaSalBitmap& bitmap, 
const Size& targetSize,
+                                                DirectImage bitmapType)
 {
     OString key = OString::number(targetSize.Width()) + "x" + 
OString::number(targetSize.Height())
                   + "_" + bitmap.GetImageKey(bitmapType);
-    if (alphaBitmap)
-        key += "_" + alphaBitmap->GetAlphaImageKey(alphaBitmapType);
     return key;
 }
 
@@ -1745,7 +1694,7 @@ void SkiaSalGraphicsImpl::drawAlphaBitmap(const 
SalTwoRect& rPosAry, const SalBi
         imagePosAry.mnSrcHeight = imagePosAry.mnDestHeight;
         imageSize = Size(imagePosAry.mnSrcWidth, imagePosAry.mnSrcHeight);
     }
-    sk_sp<SkImage> image = mergeCacheBitmaps(rSkiaSourceBitmap, nullptr, 
imageSize * mScaling);
+    sk_sp<SkImage> image = mergeCacheBitmaps(rSkiaSourceBitmap, imageSize * 
mScaling);
     if (image)
         drawImage(imagePosAry, image, mScaling);
     else
@@ -1769,7 +1718,7 @@ void SkiaSalGraphicsImpl::drawBitmap(const SalTwoRect& 
rPosAry, const SkiaSalBit
         imagePosAry.mnSrcHeight = imagePosAry.mnDestHeight;
         imageSize = Size(imagePosAry.mnSrcWidth, imagePosAry.mnSrcHeight);
     }
-    sk_sp<SkImage> image = mergeCacheBitmaps(bitmap, nullptr, imageSize * 
mScaling);
+    sk_sp<SkImage> image = mergeCacheBitmaps(bitmap, imageSize * mScaling);
     if (image)
         drawImage(imagePosAry, image, mScaling, blendMode);
     else if (bitmap.PreferSkShader())
@@ -1880,17 +1829,11 @@ bool matrixNeedsHighQuality(const SkMatrix& matrix) { 
return ::matrixNeedsHighQu
 bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
                                                 const basegfx::B2DPoint& rX,
                                                 const basegfx::B2DPoint& rY,
-                                                const SalBitmap& rSourceBitmap,
-                                                const SalBitmap* pAlphaBitmap, 
double fAlpha)
+                                                const SalBitmap& 
rSourceBitmap, double fAlpha)
 {
     assert(dynamic_cast<const SkiaSalBitmap*>(&rSourceBitmap));
-    assert(!pAlphaBitmap || dynamic_cast<const SkiaSalBitmap*>(pAlphaBitmap));
 
     const SkiaSalBitmap& rSkiaBitmap = static_cast<const 
SkiaSalBitmap&>(rSourceBitmap);
-    const SkiaSalBitmap* pSkiaAlphaBitmap = static_cast<const 
SkiaSalBitmap*>(pAlphaBitmap);
-
-    if (pSkiaAlphaBitmap && pSkiaAlphaBitmap->IsFullyOpaqueAsAlpha())
-        pSkiaAlphaBitmap = nullptr; // the alpha can be ignored
 
     // Setup the image transformation,
     // using the rNull, rX, rY points as destinations for the (0,0), 
(Width,0), (0,Height) source points.
@@ -1909,8 +1852,7 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const 
basegfx::B2DPoint& rNull,
     // Pass size * mScaling to mergeCacheBitmaps() so that it prepares the 
size that will be needed
     // after the mScaling-scaling matrix, but otherwise calculate everything 
else using the VCL coordinates.
     Size imageSize(round(aXRel.getLength()), round(aYRel.getLength()));
-    sk_sp<SkImage> imageToDraw
-        = mergeCacheBitmaps(rSkiaBitmap, pSkiaAlphaBitmap, imageSize * 
mScaling);
+    sk_sp<SkImage> imageToDraw = mergeCacheBitmaps(rSkiaBitmap, imageSize * 
mScaling);
     if (imageToDraw)
     {
         SkMatrix matrix;
@@ -1968,19 +1910,7 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const 
basegfx::B2DPoint& rNull,
         SkSamplingOptions samplingOptions;
         if (matrixNeedsHighQuality(matrix) || (mScaling != 1 && 
!isUnitTestRunning()))
             samplingOptions = makeSamplingOptions(matrix, mScaling);
-        if (pSkiaAlphaBitmap)
-        {
-            SkPaint paint = makeBitmapPaint();
-            paint.setShader(SkShaders::Blend(SkBlendMode::kDstIn,
-                                             
rSkiaBitmap.GetSkShader(samplingOptions),
-                                             
pSkiaAlphaBitmap->GetAlphaSkShader(samplingOptions)));
-            if (fAlpha != 1.0)
-                paint.setShader(
-                    SkShaders::Blend(SkBlendMode::kDstIn, paint.refShader(),
-                                     SkShaders::Color(SkColorSetARGB(fAlpha * 
255, 0, 0, 0))));
-            canvas->drawRect(SkRect::MakeWH(aSize.Width(), aSize.Height()), 
paint);
-        }
-        else if (rSkiaBitmap.PreferSkShader() || fAlpha != 1.0)
+        if (rSkiaBitmap.PreferSkShader() || fAlpha != 1.0)
         {
             SkPaint paint = makeBitmapPaint();
             paint.setShader(rSkiaBitmap.GetSkShader(samplingOptions));
@@ -1993,7 +1923,8 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const 
basegfx::B2DPoint& rNull,
         else
         {
             SkPaint paint = makeBitmapPaint();
-            canvas->drawImage(rSkiaBitmap.GetSkImage(), 0, 0, samplingOptions, 
&paint);
+            paint.setShader(rSkiaBitmap.GetSkShader(samplingOptions));
+            canvas->drawRect(SkRect::MakeWH(aSize.Width(), aSize.Height()), 
paint);
         }
     }
     postDraw();
diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx
index a3e8dad48405..bf82cbf486f3 100644
--- a/vcl/source/bitmap/bitmap.cxx
+++ b/vcl/source/bitmap/bitmap.cxx
@@ -19,6 +19,7 @@
 
 #include <config_features.h>
 
+#include <rtl/math.hxx>
 #include <sal/log.hxx>
 #include <osl/diagnose.h>
 #include <tools/helpers.hxx>
@@ -2719,4 +2720,192 @@ tools::Polygon  Bitmap::GetContour( bool 
bContourEdgeDetect,
     return aRetPoly;
 }
 
+static Bitmap impTransformBitmap(
+    const Bitmap& rSource,
+    const Size& rDestinationSize,
+    const basegfx::B2DHomMatrix& rTransform,
+    bool bSmooth)
+{
+    Bitmap aDestination(rDestinationSize, rSource.getPixelFormat());
+    BitmapScopedWriteAccess xWrite(aDestination);
+
+    if(xWrite)
+    {
+        BitmapScopedReadAccess xRead(rSource);
+
+        if (xRead)
+        {
+            const Size aDestinationSizePixel(aDestination.GetSizePixel());
+
+            // tdf#157795 set color to black outside of bitmap bounds
+            // Due to commit 81994cb2b8b32453a92bcb011830fcb884f22ff3,
+            // transparent areas are now black instead of white.
+            // tdf#160831 only set outside color to black for alpha masks
+            // The outside color still needs to be white for the content
+            // so only apply the fix for tdf#157795 to the alpha mask.
+            const BitmapColor aOutside(ColorAlpha, 0xff, 0xff, 0xff, 0x00);
+
+            for(tools::Long y(0); y < aDestinationSizePixel.getHeight(); y++)
+            {
+                Scanline pScanline = xWrite->GetScanline( y );
+                for(tools::Long x(0); x < aDestinationSizePixel.getWidth(); 
x++)
+                {
+                    const basegfx::B2DPoint aSourceCoor(rTransform * 
basegfx::B2DPoint(x, y));
+
+                    if(bSmooth)
+                    {
+                        xWrite->SetPixelOnData(
+                            pScanline,
+                            x,
+                            xRead->GetInterpolatedColorWithFallback(
+                                aSourceCoor.getY(),
+                                aSourceCoor.getX(),
+                                aOutside));
+                    }
+                    else
+                    {
+                        // this version does the correct <= 0.0 checks, so no 
need
+                        // to do the static_cast< sal_Int32 > self and make an 
error
+                        xWrite->SetPixelOnData(
+                            pScanline,
+                            x,
+                            xRead->GetColorWithFallback(
+                                aSourceCoor.getY(),
+                                aSourceCoor.getX(),
+                                aOutside));
+                    }
+                }
+            }
+        }
+    }
+    xWrite.reset();
+
+    rSource.AdaptBitCount(aDestination);
+
+    return aDestination;
+}
+
+/// Decides if rTransformation needs smoothing or not (e.g. 180 deg rotation 
doesn't need it).
+static bool implTransformNeedsSmooth(const basegfx::B2DHomMatrix& 
rTransformation)
+{
+    basegfx::B2DVector aScale, aTranslate;
+    double fRotate, fShearX;
+    rTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+    if (aScale != basegfx::B2DVector(1, 1))
+    {
+        return true;
+    }
+
+    fRotate = fmod( fRotate, 2 * M_PI );
+    if (fRotate < 0)
+    {
+        fRotate += 2 * M_PI;
+    }
+    if (!rtl::math::approxEqual(fRotate, 0)
+        && !rtl::math::approxEqual(fRotate, M_PI_2)
+        && !rtl::math::approxEqual(fRotate, M_PI)
+        && !rtl::math::approxEqual(fRotate, 3 * M_PI_2))
+    {
+        return true;
+    }
+
+    if (!rtl::math::approxEqual(fShearX, 0))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+Bitmap Bitmap::TransformBitmap(
+    double fWidth,
+    double fHeight,
+    const basegfx::B2DHomMatrix& rTransformation) const
+{
+    if(fWidth <= 1 || fHeight <= 1)
+        return Bitmap();
+
+    // force destination to 24 bit, we want to smooth output
+    const Size aDestinationSize(basegfx::fround<tools::Long>(fWidth), 
basegfx::fround<tools::Long>(fHeight));
+    bool bSmooth = implTransformNeedsSmooth(rTransformation);
+    const Bitmap aDestination(impTransformBitmap(*this, aDestinationSize, 
rTransformation, bSmooth));
+
+    return aDestination;
+}
+
+Bitmap Bitmap::getTransformed(
+    const basegfx::B2DHomMatrix& rTransformation,
+    const basegfx::B2DRange& rVisibleRange,
+    double fMaximumArea) const
+{
+    if (IsEmpty())
+        return Bitmap();
+
+    const sal_uInt32 nSourceWidth(GetSizePixel().Width());
+    const sal_uInt32 nSourceHeight(GetSizePixel().Height());
+
+    if (!nSourceWidth || !nSourceHeight)
+        return Bitmap();
+
+    // Get aOutlineRange
+    basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0);
+
+    aOutlineRange.transform(rTransformation);
+
+    // create visible range from it by moving from relative to absolute
+    basegfx::B2DRange aVisibleRange(rVisibleRange);
+
+    aVisibleRange.transform(
+        basegfx::utils::createScaleTranslateB2DHomMatrix(
+            aOutlineRange.getRange(),
+            aOutlineRange.getMinimum()));
+
+    // get target size (which is visible range's size)
+    double fWidth(aVisibleRange.getWidth());
+    double fHeight(aVisibleRange.getHeight());
+
+    if (fWidth < 1.0 || fHeight < 1.0)
+        return Bitmap();
+
+    // test if discrete size (pixel) maybe too big and limit it
+    const double fArea(fWidth * fHeight);
+    const bool bNeedToReduce(basegfx::fTools::more(fArea, fMaximumArea));
+    double fReduceFactor(1.0);
+
+    if(bNeedToReduce)
+    {
+        fReduceFactor = sqrt(fMaximumArea / fArea);
+        fWidth *= fReduceFactor;
+        fHeight *= fReduceFactor;
+    }
+
+    // Build complete transform from source pixels to target pixels.
+    // Start by scaling from source pixel size to unit coordinates
+    basegfx::B2DHomMatrix aTransform(
+        basegfx::utils::createScaleB2DHomMatrix(
+            1.0 / nSourceWidth,
+            1.0 / nSourceHeight));
+
+    // multiply with given transform which leads from unit coordinates inside
+    // aOutlineRange
+    aTransform = rTransformation * aTransform;
+
+    // subtract top-left of absolute VisibleRange
+    aTransform.translate(
+        -aVisibleRange.getMinX(),
+        -aVisibleRange.getMinY());
+
+    // scale to target pixels (if needed)
+    if(bNeedToReduce)
+    {
+        aTransform.scale(fReduceFactor, fReduceFactor);
+    }
+
+    // invert to get transformation from target pixel coordinates to source 
pixels
+    aTransform.invert();
+
+    // create bitmap using source, destination and linear back-transformation
+    return TransformBitmap(fWidth, fHeight, aTransform);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx
index eb918c2f2602..c5d63daafa20 100644
--- a/vcl/source/gdi/print.cxx
+++ b/vcl/source/gdi/print.cxx
@@ -171,7 +171,7 @@ void Printer::ImplPrintTransparent( const Bitmap& rBmp,
 
 bool Printer::DrawTransformBitmapExDirect(
     const basegfx::B2DHomMatrix& /*aFullTransform*/,
-    const BitmapEx& /*rBitmapEx*/,
+    const Bitmap& /*rBitmap*/,
     double /*fAlpha*/)
 {
     // printers can't draw bitmaps directly
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 584143b2b6e4..63f35c52f729 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -90,7 +90,6 @@ bool SalGraphics::drawTransformedBitmap(
     const basegfx::B2DPoint& /* rX */,
     const basegfx::B2DPoint& /* rY */,
     const SalBitmap& /* rSourceBitmap */,
-    const SalBitmap* /* pAlphaBitmap */,
     double /* fAlpha */)
 {
     // here direct support for transformed bitmaps can be implemented
@@ -841,7 +840,6 @@ bool SalGraphics::DrawTransformedBitmap(
     const basegfx::B2DPoint& rX,
     const basegfx::B2DPoint& rY,
     const SalBitmap& rSourceBitmap,
-    const SalBitmap* pAlphaBitmap,
     double fAlpha,
     const OutputDevice& rOutDev)
 {
@@ -859,11 +857,11 @@ bool SalGraphics::DrawTransformedBitmap(
             basegfx::B2DPoint aX = aTranslateToMirroredBounds * rX;
             basegfx::B2DPoint aY = aTranslateToMirroredBounds * rY;
 
-            return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, 
pAlphaBitmap, fAlpha);
+            return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, fAlpha);
         }
     }
 
-    return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap, 
fAlpha);
+    return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, fAlpha);
 }
 
 bool SalGraphics::HasFastDrawTransformedBitmap() const
diff --git a/vcl/source/outdev/bitmapex.cxx b/vcl/source/outdev/bitmapex.cxx
index 6b7ece22051d..ba355f2a8052 100644
--- a/vcl/source/outdev/bitmapex.cxx
+++ b/vcl/source/outdev/bitmapex.cxx
@@ -186,7 +186,7 @@ void OutputDevice::DrawDeviceBitmapEx( const Point& 
rDestPt, const Size& rDestSi
 
 bool OutputDevice::DrawTransformBitmapExDirect(
         const basegfx::B2DHomMatrix& aFullTransform,
-        const BitmapEx& rBitmapEx,
+        const Bitmap& rBitmap,
         double fAlpha)
 {
     assert(!is_double_buffered_window());
@@ -195,22 +195,13 @@ bool OutputDevice::DrawTransformBitmapExDirect(
     const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 
0.0));
     const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 
0.0));
     const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 
1.0));
-    SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetSalBitmap().get();
-    AlphaMask aAlphaBitmap;
-
-    if(rBitmapEx.IsAlpha())
-    {
-        aAlphaBitmap = rBitmapEx.GetAlphaMask();
-    }
-
-    SalBitmap* pSalAlphaBmp = 
aAlphaBitmap.GetBitmap().ImplGetSalBitmap().get();
+    SalBitmap* pSalSrcBmp = rBitmap.ImplGetSalBitmap().get();
 
     return mpGraphics->DrawTransformedBitmap(
         aNull,
         aTopX,
         aTopY,
         *pSalSrcBmp,
-        pSalAlphaBmp,
         fAlpha,
         *this);
 };
@@ -326,21 +317,13 @@ void OutputDevice::DrawTransformedBitmapEx(
     const basegfx::B2DHomMatrix& rTransformation,
     const Bitmap& rBitmap,
     double fAlpha)
-{
-    DrawTransformedBitmapEx(rTransformation, BitmapEx(rBitmap), fAlpha);
-}
-
-void OutputDevice::DrawTransformedBitmapEx(
-    const basegfx::B2DHomMatrix& rTransformation,
-    const BitmapEx& rBitmapEx,
-    double fAlpha)
 {
     assert(!is_double_buffered_window());
 
     if( ImplIsRecordLayout() )
         return;
 
-    if(rBitmapEx.IsEmpty())
+    if(rBitmap.IsEmpty())
         return;
 
     if( fAlpha == 0.0 )
@@ -378,7 +361,7 @@ void OutputDevice::DrawTransformedBitmapEx(
         : nullptr);
 #endif
 
-    BitmapEx bitmapEx = rBitmapEx;
+    Bitmap bitmap = rBitmap;
 
     const bool bInvert(RasterOp::Invert == meRasterOp);
     const bool bBitmapChangedColor(mnDrawMode & (DrawModeFlags::BlackBitmap | 
DrawModeFlags::WhiteBitmap | DrawModeFlags::GrayBitmap ));
@@ -393,7 +376,7 @@ void OutputDevice::DrawTransformedBitmapEx(
     {
         if(bTryDirectPaint)
         {
-            if(DrawTransformBitmapExDirect(aFullTransform, bitmapEx, fAlpha))
+            if(DrawTransformBitmapExDirect(aFullTransform, bitmap, fAlpha))
             {
                 // we are done
                 return;
@@ -401,15 +384,15 @@ void OutputDevice::DrawTransformedBitmapEx(
         }
         // Apply the alpha manually.
         sal_uInt8 nTransparency( static_cast<sal_uInt8>( ::basegfx::fround( 
255.0*(1.0 - fAlpha) + .5) ) );
-        AlphaMask aAlpha( bitmapEx.GetSizePixel(), &nTransparency );
-        if( bitmapEx.IsAlpha())
-            aAlpha.BlendWith( bitmapEx.GetAlphaMask());
-        bitmapEx = BitmapEx( bitmapEx.GetBitmap(), aAlpha );
+        AlphaMask aAlpha( bitmap.GetSizePixel(), &nTransparency );
+        if( bitmap.HasAlpha())
+            aAlpha.BlendWith( bitmap.CreateAlphaMask());
+        bitmap = Bitmap( bitmap.CreateColorBitmap(), aAlpha );
     }
 
     // If the backend's implementation is known to not need any optimizations 
here, pass to it directly.
     // With most backends it's more performant to try to simplify to 
DrawBitmapEx() first.
-    if(bTryDirectPaint && mpGraphics->HasFastDrawTransformedBitmap() && 
DrawTransformBitmapExDirect(aFullTransform, bitmapEx))
+    if(bTryDirectPaint && mpGraphics->HasFastDrawTransformedBitmap() && 
DrawTransformBitmapExDirect(aFullTransform, bitmap))
         return;
 
     // decompose matrix to check rotation and shear
@@ -437,7 +420,7 @@ void OutputDevice::DrawTransformedBitmapEx(
             EnableMapMode(false);
         }
 
-        DrawBitmapEx(aDestPt, aDestSize, Bitmap(bitmapEx));
+        DrawBitmapEx(aDestPt, aDestSize, bitmap);
         if (!bMetafile && comphelper::LibreOfficeKit::isActive() && 
GetMapMode().GetMapUnit() != MapUnit::MapPixel)
         {
             EnableMapMode();
@@ -447,7 +430,7 @@ void OutputDevice::DrawTransformedBitmapEx(
     }
 
     // Try the backend's implementation before resorting to the slower 
fallback here.
-    if(bTryDirectPaint && DrawTransformBitmapExDirect(aFullTransform, 
bitmapEx))
+    if(bTryDirectPaint && DrawTransformBitmapExDirect(aFullTransform, bitmap))
         return;
 
     // take the fallback when no rotate and shear, but mirror (else we would 
have done this above)
@@ -461,7 +444,7 @@ void OutputDevice::DrawTransformedBitmapEx(
             basegfx::fround<tools::Long>(aScale.getX() + aTranslate.getX()) - 
aDestPt.X(),
             basegfx::fround<tools::Long>(aScale.getY() + aTranslate.getY()) - 
aDestPt.Y());
 
-        DrawBitmapEx(aDestPt, aDestSize, Bitmap(bitmapEx));
+        DrawBitmapEx(aDestPt, aDestSize, bitmap);
         return;
     }
 
@@ -476,8 +459,8 @@ void OutputDevice::DrawTransformedBitmapEx(
     // by using a fixed minimum (allow at least, but no need to utilize) for 
good smoothing and an area
     // dependent of original size for good quality when e.g. rotated/sheared. 
Still, limit to a maximum
     // to avoid crashes/resource problems (ca. 1500x3000 here)
-    const Size& rOriginalSizePixel(bitmapEx.GetSizePixel());
-    const double fOrigArea(rOriginalSizePixel.Width() * 
rOriginalSizePixel.Height() * 0.5);
+    const Size aOriginalSizePixel(bitmap.GetSizePixel());
+    const double fOrigArea(aOriginalSizePixel.Width() * 
aOriginalSizePixel.Height() * 0.5);
     const double fOrigAreaScaled(fOrigArea * 1.44);
     double fMaximumArea(std::clamp(fOrigAreaScaled, 1000000.0, 4500000.0));
 
@@ -490,20 +473,20 @@ void OutputDevice::DrawTransformedBitmapEx(
     if(aVisibleRange.isEmpty())
         return;
 
-    BitmapEx aTransformed(bitmapEx);
+    Bitmap aTransformed(bitmap);
 
     // #122923# when the result needs an alpha channel due to being rotated or 
sheared
     // and thus uncovering areas, add these channels so that the own 
transformer (used
     // in getTransformed) also creates a transformed alpha channel
-    if(!aTransformed.IsAlpha() && (bSheared || bRotated))
+    if(!aTransformed.HasAlpha() && (bSheared || bRotated))
     {
         // parts will be uncovered, extend aTransformed with a mask bitmap
-        const Bitmap aContent(aTransformed.GetBitmap());
+        const Bitmap aContent(aTransformed.CreateColorBitmap());
 
         AlphaMask aMaskBmp(aContent.GetSizePixel());
         aMaskBmp.Erase(0);
 
-        aTransformed = BitmapEx(aContent, aMaskBmp);
+        aTransformed = Bitmap(aContent, aMaskBmp);
     }
 
     basegfx::B2DVector aFullScale, aFullTranslate;
@@ -511,9 +494,9 @@ void OutputDevice::DrawTransformedBitmapEx(
     aFullTransform.decompose(aFullScale, aFullTranslate, fFullRotate, 
fFullShearX);
 
     double fSourceRatio = 1.0;
-    if (rOriginalSizePixel.getHeight() != 0)
+    if (aOriginalSizePixel.getHeight() != 0)
     {
-        fSourceRatio = rOriginalSizePixel.getWidth() / 
rOriginalSizePixel.getHeight();
+        fSourceRatio = aOriginalSizePixel.getWidth() / 
aOriginalSizePixel.getHeight();
     }
     double fTargetRatio = 1.0;
     if (aFullScale.getY() != 0)
@@ -558,7 +541,7 @@ void OutputDevice::DrawTransformedBitmapEx(
         basegfx::fround<tools::Long>(aVisibleRange.getMaxX()) - aDestPt.X(),
         basegfx::fround<tools::Long>(aVisibleRange.getMaxY()) - aDestPt.Y());
 
-    DrawBitmapEx(aDestPt, aDestSize, Bitmap(aTransformed));
+    DrawBitmapEx(aDestPt, aDestSize, aTransformed);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx 
b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx
index c80caf4c23e1..28b346c2c2e4 100644
--- a/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx
+++ b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.cxx
@@ -204,10 +204,9 @@ bool 
X11CairoSalGraphicsImpl::drawPolyPolygonBezier(sal_uInt32, const sal_uInt32
 bool X11CairoSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& 
rNull,
                                                     const basegfx::B2DPoint& 
rX,
                                                     const basegfx::B2DPoint& 
rY,
-                                                    const SalBitmap& 
rSourceBitmap,
-                                                    const SalBitmap* 
pAlphaBitmap, double fAlpha)
+                                                    const SalBitmap& 
rSourceBitmap, double fAlpha)
 {
-    return mrCairoCommon.drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
pAlphaBitmap, fAlpha,
+    return mrCairoCommon.drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, 
fAlpha,
                                                getAntiAlias());
 }
 
diff --git a/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx 
b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx
index b95d2c90b684..e4b78121ae2d 100644
--- a/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx
+++ b/vcl/unx/generic/gdi/X11CairoSalGraphicsImpl.hxx
@@ -156,7 +156,7 @@ public:
     /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the 
coordinate system */
     bool drawTransformedBitmap(const basegfx::B2DPoint& rNull, const 
basegfx::B2DPoint& rX,
                                const basegfx::B2DPoint& rY, const SalBitmap& 
rSourceBitmap,
-                               const SalBitmap* pAlphaBitmap, double fAlpha) 
override;
+                               double fAlpha) override;
 
     bool supportsOperation(OutDevSupportType eType) const override;
 };
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index b1a412093815..440948cfbc87 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -2342,18 +2342,15 @@ bool WinSalGraphicsImpl::drawTransformedBitmap(
     const basegfx::B2DPoint& rX,
     const basegfx::B2DPoint& rY,
     const SalBitmap& rSourceBitmap,
-    const SalBitmap* pAlphaBitmap,
     double fAlpha)
 {
     assert(dynamic_cast<const WinSalBitmap*>(&rSourceBitmap));
-    assert(!pAlphaBitmap || dynamic_cast<const WinSalBitmap*>(pAlphaBitmap));
 
     if( fAlpha != 1.0 )
         return false;
 
     const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& 
>(rSourceBitmap);
-    const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* 
>(pAlphaBitmap);
-    std::shared_ptr< Gdiplus::Bitmap > 
aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha));
+    std::shared_ptr< Gdiplus::Bitmap > 
aARGB(rSalBitmap.ImplGetGdiPlusBitmap());
 
     if(!aARGB)
         return false;
diff --git a/vcl/win/gdi/gdiimpl.hxx b/vcl/win/gdi/gdiimpl.hxx
index 9eb69fe55974..976b6fd0ebba 100644
--- a/vcl/win/gdi/gdiimpl.hxx
+++ b/vcl/win/gdi/gdiimpl.hxx
@@ -192,7 +192,6 @@ public:
                 const basegfx::B2DPoint& rX,
                 const basegfx::B2DPoint& rY,
                 const SalBitmap& rSourceBitmap,
-                const SalBitmap* pAlphaBitmap,
                 double fAlpha) override;
 
     virtual bool hasFastDrawTransformedBitmap() const override;
diff --git a/vcl/win/gdi/salbmp.cxx b/vcl/win/gdi/salbmp.cxx
index a5b27e40f674..8c926d5d35fe 100644
--- a/vcl/win/gdi/salbmp.cxx
+++ b/vcl/win/gdi/salbmp.cxx
@@ -74,14 +74,11 @@ class SystemDependentData_GdiPlusBitmap : public 
basegfx::SystemDependentData
 {
 private:
     std::shared_ptr<Gdiplus::Bitmap>    mpGdiPlusBitmap;
-    const WinSalBitmap*                 mpAssociatedAlpha;
 
 public:
     SystemDependentData_GdiPlusBitmap(
-        const std::shared_ptr<Gdiplus::Bitmap>& rGdiPlusBitmap,
-        const WinSalBitmap* pAssociatedAlpha);
+        const std::shared_ptr<Gdiplus::Bitmap>& rGdiPlusBitmap);
 
-    const WinSalBitmap* getAssociatedAlpha() const { return mpAssociatedAlpha; 
}
     const std::shared_ptr<Gdiplus::Bitmap>& getGdiPlusBitmap() const { return 
mpGdiPlusBitmap; }
 
     virtual sal_Int64 estimateUsageInBytes() const override;
@@ -90,13 +87,11 @@ public:
 }
 
 SystemDependentData_GdiPlusBitmap::SystemDependentData_GdiPlusBitmap(
-    const std::shared_ptr<Gdiplus::Bitmap>& rGdiPlusBitmap,
-    const WinSalBitmap* pAssociatedAlpha)
+    const std::shared_ptr<Gdiplus::Bitmap>& rGdiPlusBitmap)
 :   basegfx::SystemDependentData(
         Application::GetSystemDependentDataManager(),
         basegfx::SDD_Type::SDDType_GdiPlusBitmap),
-    mpGdiPlusBitmap(rGdiPlusBitmap),
-    mpAssociatedAlpha(pAssociatedAlpha)
+    mpGdiPlusBitmap(rGdiPlusBitmap)
 {
 }
 
@@ -151,7 +146,7 @@ sal_Int64 
SystemDependentData_GdiPlusBitmap::estimateUsageInBytes() const
     return nRetval;
 }
 
-std::shared_ptr< Gdiplus::Bitmap > WinSalBitmap::ImplGetGdiPlusBitmap(const 
WinSalBitmap* pAlphaSource) const
+std::shared_ptr< Gdiplus::Bitmap > WinSalBitmap::ImplGetGdiPlusBitmap() const
 {
     std::shared_ptr< Gdiplus::Bitmap > aRetval;
 
@@ -159,20 +154,6 @@ std::shared_ptr< Gdiplus::Bitmap > 
WinSalBitmap::ImplGetGdiPlusBitmap(const WinS
     std::shared_ptr<SystemDependentData_GdiPlusBitmap> 
pSystemDependentData_GdiPlusBitmap(
         
getSystemDependentData<SystemDependentData_GdiPlusBitmap>(basegfx::SDD_Type::SDDType_GdiPlusBitmap));
 
-    if(pSystemDependentData_GdiPlusBitmap)
-    {
-        // check data validity
-        if(pSystemDependentData_GdiPlusBitmap->getAssociatedAlpha() != 
pAlphaSource
-            || 0 == maSize.Width()
-            || 0 == maSize.Height())
-        {
-            // #122350# if associated alpha with which the GDIPlus was 
constructed has changed
-            // it is necessary to remove it from buffer, reset reference to it 
and reconstruct
-            // data invalid, forget
-            pSystemDependentData_GdiPlusBitmap.reset();
-        }
-    }
-
     if(pSystemDependentData_GdiPlusBitmap)
     {
         // use from buffer
@@ -180,24 +161,9 @@ std::shared_ptr< Gdiplus::Bitmap > 
WinSalBitmap::ImplGetGdiPlusBitmap(const WinS
     }
     else if(!maSize.IsEmpty())
     {
-        // create and set data
-        const WinSalBitmap* pAssociatedAlpha(nullptr);
-
-        if(pAlphaSource)
-        {
-            aRetval = const_cast< WinSalBitmap* 
>(this)->ImplCreateGdiPlusBitmap(*pAlphaSource);
-            pAssociatedAlpha = pAlphaSource;
-        }
-        else
-        {
-            aRetval = const_cast< WinSalBitmap* 
>(this)->ImplCreateGdiPlusBitmap();
-            pAssociatedAlpha = nullptr;
-        }
-
         // add to buffering mechanism
         addOrReplaceSystemDependentData<SystemDependentData_GdiPlusBitmap>(
-            aRetval,
-            pAssociatedAlpha);
+            aRetval);
     }
 
     return aRetval;
diff --git a/vcl/win/gdi/salgdi_gdiplus.cxx b/vcl/win/gdi/salgdi_gdiplus.cxx
index 17fa6264247e..5f3e47b108d5 100644
--- a/vcl/win/gdi/salgdi_gdiplus.cxx
+++ b/vcl/win/gdi/salgdi_gdiplus.cxx
@@ -79,11 +79,10 @@ bool WinSalGraphics::drawTransformedBitmap(
     const basegfx::B2DPoint& rX,
     const basegfx::B2DPoint& rY,
     const SalBitmap& rSourceBitmap,
-    const SalBitmap* pAlphaBitmap,
     double fAlpha)
 {
     return mpImpl->drawTransformedBitmap(rNull, rX, rY,
-            rSourceBitmap, pAlphaBitmap, fAlpha);
+            rSourceBitmap, fAlpha);
 }
 
 bool WinSalGraphics::hasFastDrawTransformedBitmap() const

Reply via email to