include/vcl/bitmap.hxx                |   39 +++++++++++++++++++++++
 include/vcl/bitmapex.hxx              |   40 ------------------------
 svtools/source/control/valueset.cxx   |    4 +-
 vcl/inc/bitmap/BlendFrameCache.hxx    |    4 +-
 vcl/source/app/svmain.cxx             |    2 -
 vcl/source/bitmap/BitmapEx.cxx        |   56 ----------------------------------
 vcl/source/bitmap/BlendFrameCache.cxx |   44 ++++++++++++--------------
 vcl/source/bitmap/bitmap.cxx          |   56 ++++++++++++++++++++++++++++++++++
 8 files changed, 121 insertions(+), 124 deletions(-)

New commits:
commit 93907ff360ec3a26b1a9415210703bc9856cde32
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Thu Aug 28 13:36:21 2025 +0200
Commit:     Noel Grandin <noelgran...@gmail.com>
CommitDate: Thu Aug 28 16:04:47 2025 +0200

    BitmapEx->Bitmap in createAlphaBlendFrame
    
    now that Bitmap can handle transparency
    
    Change-Id: I443463f9fdfec6637349eaa3d515a519f9a73ac9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190326
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index d6ef3bbe5058..5fd2e04b1e44 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -714,6 +714,45 @@ inline sal_Int64 Bitmap::GetSizeBytes() const
     return aSizeInBytes;
 }
 
+/** Create a blend frame as Bitmap using an alpha value
+
+    @param nAlpha
+    The blend value defines how strong the frame will be blended with the
+    existing content, 255 == full coverage, 0 == no frame will be drawn
+
+    @param aColorTopLeft, aColorBottomRight
+    The colors defining the frame. These colors are linearly interpolated from
+    aColorTopLeft and aColorBottomRight using the width and height of the area
+
+    @param rSize
+    The size of the frame in pixels
+    */
+Bitmap VCL_DLLPUBLIC createAlphaBlendFrame(
+    const Size& rSize,
+    sal_uInt8 nAlpha,
+    const Color& rColorTopLeft,
+    const Color& rColorBottomRight);
+
+/** Create a blend frame as Bitmap using an alpha value
+
+    @param nAlpha
+    The blend value defines how strong the frame will be blended with the
+    existing content, 255 == full coverage, 0 == no frame will be drawn
+
+    @param aColorTopLeft, aColorBottomRight, aColorTopRight, aColorBottomLeft
+    The colors defining the frame.
+
+    @param rSize
+    The size of the frame in pixels
+    */
+Bitmap createAlphaBlendFrame(
+    const Size& rSize,
+    sal_uInt8 nAlpha,
+    const Color& rColorTopLeft,
+    const Color& rColorTopRight,
+    const Color& rColorBottomRight,
+    const Color& rColorBottomLeft);
+
 #endif // INCLUDED_VCL_BITMAP_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx
index cf3055d2d607..35bb0248313a 100644
--- a/include/vcl/bitmapex.hxx
+++ b/include/vcl/bitmapex.hxx
@@ -464,46 +464,6 @@ private:
     Size                maBitmapSize;
 };
 
-
-/** Create a blend frame as BitmapEx using an alpha value
-
-    @param nAlpha
-    The blend value defines how strong the frame will be blended with the
-    existing content, 255 == full coverage, 0 == no frame will be drawn
-
-    @param aColorTopLeft, aColorBottomRight
-    The colors defining the frame. These colors are linearly interpolated from
-    aColorTopLeft and aColorBottomRight using the width and height of the area
-
-    @param rSize
-    The size of the frame in pixels
-    */
-BitmapEx VCL_DLLPUBLIC createAlphaBlendFrame(
-    const Size& rSize,
-    sal_uInt8 nAlpha,
-    const Color& rColorTopLeft,
-    const Color& rColorBottomRight);
-
-/** Create a blend frame as BitmapEx using an alpha value
-
-    @param nAlpha
-    The blend value defines how strong the frame will be blended with the
-    existing content, 255 == full coverage, 0 == no frame will be drawn
-
-    @param aColorTopLeft, aColorBottomRight, aColorTopRight, aColorBottomLeft
-    The colors defining the frame.
-
-    @param rSize
-    The size of the frame in pixels
-    */
-BitmapEx createAlphaBlendFrame(
-    const Size& rSize,
-    sal_uInt8 nAlpha,
-    const Color& rColorTopLeft,
-    const Color& rColorTopRight,
-    const Color& rColorBottomRight,
-    const Color& rColorBottomLeft);
-
 #endif // INCLUDED_VCL_BITMAPEX_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/control/valueset.cxx 
b/svtools/source/control/valueset.cxx
index 7e9604b75169..99240f5d4bee 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -23,7 +23,7 @@
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <tools/debug.hxx>
-#include <vcl/bitmapex.hxx>
+#include <vcl/bitmap.hxx>
 #include <vcl/canvastools.hxx>
 #include <vcl/decoview.hxx>
 #include <vcl/event.hxx>
@@ -1500,7 +1500,7 @@ void ValueSet::ImplFormatItem(vcl::RenderContext const & 
rRenderContext, ValueSe
         const Color& rTopLeft(rStyleSettings.GetEdgeBlendingTopLeftColor());
         const Color& 
rBottomRight(rStyleSettings.GetEdgeBlendingBottomRightColor());
         const sal_uInt8 nAlpha(255 - ((nEdgeBlendingPercent * 255) / 100));
-        const BitmapEx aBlendFrame(createAlphaBlendFrame(aRect.GetSize(), 
nAlpha, rTopLeft, rBottomRight));
+        const Bitmap aBlendFrame(createAlphaBlendFrame(aRect.GetSize(), 
nAlpha, rTopLeft, rBottomRight));
 
         if (!aBlendFrame.IsEmpty())
         {
diff --git a/vcl/inc/bitmap/BlendFrameCache.hxx 
b/vcl/inc/bitmap/BlendFrameCache.hxx
index 61d4ff6de6aa..5c03ff94b819 100644
--- a/vcl/inc/bitmap/BlendFrameCache.hxx
+++ b/vcl/inc/bitmap/BlendFrameCache.hxx
@@ -20,7 +20,7 @@
 #include <tools/color.hxx>
 #include <tools/gen.hxx>
 
-#include <vcl/bitmapex.hxx>
+#include <vcl/bitmap.hxx>
 
 struct BlendFrameCache
 {
@@ -30,7 +30,7 @@ struct BlendFrameCache
     Color m_aLastColorTopRight;
     Color m_aLastColorBottomRight;
     Color m_aLastColorBottomLeft;
-    BitmapEx m_aLastResult;
+    Bitmap m_aLastResult;
 
     BlendFrameCache(Size const& rSize, sal_uInt8 nAlpha, Color const& 
rColorTopLeft,
                     Color const& rColorTopRight, Color const& 
rColorBottomRight,
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 56c30312f3e3..58eec341a555 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -427,7 +427,7 @@ void DeInitVCL()
 
     // lp#1560328: clear cache before disposing rest of VCL
     if(pSVData->mpBlendFrameCache)
-        pSVData->mpBlendFrameCache->m_aLastResult.Clear();
+        pSVData->mpBlendFrameCache->m_aLastResult = Bitmap();
     pSVData->mbDeInit = true;
 
     // Some events may need to access objects destroyed in ImplDeleteOnDeInit, 
so process them first
diff --git a/vcl/source/bitmap/BitmapEx.cxx b/vcl/source/bitmap/BitmapEx.cxx
index c920b643685d..34573ffc8cf2 100644
--- a/vcl/source/bitmap/BitmapEx.cxx
+++ b/vcl/source/bitmap/BitmapEx.cxx
@@ -41,7 +41,6 @@
 #include <svdata.hxx>
 #include <vcl/BitmapWriteAccess.hxx>
 #include <bitmap/BitmapMaskToAlphaFilter.hxx>
-#include <bitmap/BlendFrameCache.hxx>
 
 #include <tools/stream.hxx>
 #include <vcl/filter/PngImageWriter.hxx>
@@ -967,61 +966,6 @@ BitmapEx BitmapEx::ModifyBitmapEx(const 
basegfx::BColorModifierStack& rBColorMod
     return BitmapEx(aChangedBitmap);
 }
 
-BitmapEx createAlphaBlendFrame(
-    const Size& rSize,
-    sal_uInt8 nAlpha,
-    const Color& rColorTopLeft,
-    const Color& rColorBottomRight)
-{
-    const sal_uInt32 nW(rSize.Width());
-    const sal_uInt32 nH(rSize.Height());
-
-    if(nW || nH)
-    {
-        Color aColTopRight(rColorTopLeft);
-        Color aColBottomLeft(rColorTopLeft);
-        const sal_uInt32 nDE(nW + nH);
-
-        aColTopRight.Merge(rColorBottomRight, 255 - sal_uInt8((nW * 255) / 
nDE));
-        aColBottomLeft.Merge(rColorBottomRight, 255 - sal_uInt8((nH * 255) / 
nDE));
-
-        return createAlphaBlendFrame(rSize, nAlpha, rColorTopLeft, 
aColTopRight, rColorBottomRight, aColBottomLeft);
-    }
-
-    return BitmapEx();
-}
-
-BitmapEx createAlphaBlendFrame(
-    const Size& rSize,
-    sal_uInt8 nAlpha,
-    const Color& rColorTopLeft,
-    const Color& rColorTopRight,
-    const Color& rColorBottomRight,
-    const Color& rColorBottomLeft)
-{
-    ImplSVData* pSVData = ImplGetSVData();
-    if (!pSVData->mpBlendFrameCache)
-    {
-        pSVData->mpBlendFrameCache.reset(new BlendFrameCache(rSize, nAlpha, 
rColorTopLeft, rColorTopRight, rColorBottomRight, rColorBottomLeft));
-        return pSVData->mpBlendFrameCache->m_aLastResult;
-    }
-
-    BlendFrameCache* pBlendFrameCache = pSVData->mpBlendFrameCache.get();
-
-    if(pBlendFrameCache->m_aLastSize == rSize
-        && pBlendFrameCache->m_nLastAlpha == nAlpha
-        && pBlendFrameCache->m_aLastColorTopLeft == rColorTopLeft
-        && pBlendFrameCache->m_aLastColorTopRight == rColorTopRight
-        && pBlendFrameCache->m_aLastColorBottomRight == rColorBottomRight
-        && pBlendFrameCache->m_aLastColorBottomLeft == rColorBottomLeft)
-    {
-        return pBlendFrameCache->m_aLastResult;
-    }
-
-    pSVData->mpBlendFrameCache.reset(new BlendFrameCache(rSize, nAlpha, 
rColorTopLeft, rColorTopRight, rColorBottomRight, rColorBottomLeft));
-    return pSVData->mpBlendFrameCache->m_aLastResult;
-}
-
 void BitmapEx::Replace(const Color& rSearchColor,
                            const Color& rReplaceColor,
                            sal_uInt8 nTolerance)
diff --git a/vcl/source/bitmap/BlendFrameCache.cxx 
b/vcl/source/bitmap/BlendFrameCache.cxx
index 92d982d5e4d8..38bd35897c12 100644
--- a/vcl/source/bitmap/BlendFrameCache.cxx
+++ b/vcl/source/bitmap/BlendFrameCache.cxx
@@ -37,25 +37,21 @@ BlendFrameCache::BlendFrameCache(Size const& rSize, 
sal_uInt8 nAlpha, Color cons
     if (rSize.Width() <= 1 || rSize.Height() <= 1)
         return;
 
-    sal_uInt8 aEraseTrans(0xff);
-    Bitmap aContent(rSize, vcl::PixelFormat::N24_BPP);
-    AlphaMask aAlpha(rSize, &aEraseTrans);
-
-    aContent.Erase(COL_BLACK);
+    Bitmap aContent(rSize, vcl::PixelFormat::N32_BPP);
+    aContent.Erase(COL_TRANSPARENT);
 
     {
         BitmapScopedWriteAccess pContent(aContent);
-        BitmapScopedWriteAccess pAlpha(aAlpha);
-
-        if (!pContent || !pAlpha)
+        assert(pContent);
+        if (!pContent)
             return;
 
         Scanline pScanContent = pContent->GetScanline(0);
-        Scanline pScanAlpha = pContent->GetScanline(0);
 
         // x == 0, y == 0, top-left corner
-        pContent->SetPixelOnData(pScanContent, 0, rColorTopLeft);
-        pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
+        Color aCol(rColorTopLeft);
+        aCol.SetAlpha(nAlpha);
+        pContent->SetPixelOnData(pScanContent, 0, aCol);
 
         tools::Long x;
         const tools::Long nW(rSize.Width());
@@ -66,16 +62,17 @@ BlendFrameCache::BlendFrameCache(Size const& rSize, 
sal_uInt8 nAlpha, Color cons
             Color aMix(rColorTopLeft);
 
             aMix.Merge(rColorTopRight, 255 - sal_uInt8((x * 255) / nW));
+            aMix.SetAlpha(nAlpha);
             pContent->SetPixelOnData(pScanContent, x, aMix);
-            pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
         }
 
         // x == nW - 1, y == 0, top-right corner
         // #i123690# Caution! When nW is 1, x == nW is possible (!)
         if (x < nW)
         {
-            pContent->SetPixelOnData(pScanContent, x, rColorTopRight);
-            pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
+            aCol = rColorTopRight;
+            aCol.SetAlpha(nAlpha);
+            pContent->SetPixelOnData(pScanContent, x, aCol);
         }
 
         tools::Long y;
@@ -85,12 +82,11 @@ BlendFrameCache::BlendFrameCache(Size const& rSize, 
sal_uInt8 nAlpha, Color cons
         for (y = 1; y < nH - 1; y++)
         {
             pScanContent = pContent->GetScanline(y);
-            pScanAlpha = pContent->GetScanline(y);
             Color aMixA(rColorTopLeft);
 
             aMixA.Merge(rColorBottomLeft, 255 - sal_uInt8((y * 255) / nH));
+            aMixA.SetAlpha(nAlpha);
             pContent->SetPixelOnData(pScanContent, 0, aMixA);
-            pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
 
             // #i123690# Caution! When nW is 1, x == nW is possible (!)
             if (x < nW)
@@ -98,8 +94,8 @@ BlendFrameCache::BlendFrameCache(Size const& rSize, sal_uInt8 
nAlpha, Color cons
                 Color aMixB(rColorTopRight);
 
                 aMixB.Merge(rColorBottomRight, 255 - sal_uInt8((y * 255) / 
nH));
+                aMixB.SetAlpha(nAlpha);
                 pContent->SetPixelOnData(pScanContent, x, aMixB);
-                pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
             }
         }
 
@@ -107,8 +103,9 @@ BlendFrameCache::BlendFrameCache(Size const& rSize, 
sal_uInt8 nAlpha, Color cons
         if (y < nH)
         {
             // x == 0, y == nH - 1, bottom-left corner
-            pContent->SetPixelOnData(pScanContent, 0, rColorBottomLeft);
-            pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
+            aCol = rColorBottomLeft;
+            aCol.SetAlpha(nAlpha);
+            pContent->SetPixelOnData(pScanContent, 0, aCol);
 
             // y == nH - 1, bottom line left to right
             for (x = 1; x < nW - 1; x++)
@@ -116,21 +113,22 @@ BlendFrameCache::BlendFrameCache(Size const& rSize, 
sal_uInt8 nAlpha, Color cons
                 Color aMix(rColorBottomLeft);
 
                 aMix.Merge(rColorBottomRight, 255 - sal_uInt8(((x - 0) * 255) 
/ nW));
+                aMix.SetAlpha(nAlpha);
                 pContent->SetPixelOnData(pScanContent, x, aMix);
-                pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
             }
 
             // x == nW - 1, y == nH - 1, bottom-right corner
             // #i123690# Caution! When nW is 1, x == nW is possible (!)
             if (x < nW)
             {
-                pContent->SetPixelOnData(pScanContent, x, rColorBottomRight);
-                pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
+                aCol = rColorBottomRight;
+                aCol.SetAlpha(nAlpha);
+                pContent->SetPixelOnData(pScanContent, x, aCol);
             }
         }
     }
 
-    m_aLastResult = BitmapEx(aContent, aAlpha);
+    m_aLastResult = aContent;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/source/bitmap/bitmap.cxx b/vcl/source/bitmap/bitmap.cxx
index 9051b5ed4a78..9e252731200e 100644
--- a/vcl/source/bitmap/bitmap.cxx
+++ b/vcl/source/bitmap/bitmap.cxx
@@ -46,6 +46,7 @@
 #include <vcl/BitmapWriteAccess.hxx>
 #include <bitmap/impoctree.hxx>
 #include <bitmap/Octree.hxx>
+#include <bitmap/BlendFrameCache.hxx>
 #include <com/sun/star/beans/XFastPropertySet.hpp>
 #include <o3tl/any.hxx>
 
@@ -2456,4 +2457,59 @@ void  Bitmap::GetColorModel(css::uno::Sequence< 
sal_Int32 >& rRGBPalette,
     rnBitCount = pReadAccess->GetBitCount();
 }
 
+Bitmap createAlphaBlendFrame(
+    const Size& rSize,
+    sal_uInt8 nAlpha,
+    const Color& rColorTopLeft,
+    const Color& rColorBottomRight)
+{
+    const sal_uInt32 nW(rSize.Width());
+    const sal_uInt32 nH(rSize.Height());
+
+    if(nW || nH)
+    {
+        Color aColTopRight(rColorTopLeft);
+        Color aColBottomLeft(rColorTopLeft);
+        const sal_uInt32 nDE(nW + nH);
+
+        aColTopRight.Merge(rColorBottomRight, 255 - sal_uInt8((nW * 255) / 
nDE));
+        aColBottomLeft.Merge(rColorBottomRight, 255 - sal_uInt8((nH * 255) / 
nDE));
+
+        return createAlphaBlendFrame(rSize, nAlpha, rColorTopLeft, 
aColTopRight, rColorBottomRight, aColBottomLeft);
+    }
+
+    return Bitmap();
+}
+
+Bitmap createAlphaBlendFrame(
+    const Size& rSize,
+    sal_uInt8 nAlpha,
+    const Color& rColorTopLeft,
+    const Color& rColorTopRight,
+    const Color& rColorBottomRight,
+    const Color& rColorBottomLeft)
+{
+    ImplSVData* pSVData = ImplGetSVData();
+    if (!pSVData->mpBlendFrameCache)
+    {
+        pSVData->mpBlendFrameCache.reset(new BlendFrameCache(rSize, nAlpha, 
rColorTopLeft, rColorTopRight, rColorBottomRight, rColorBottomLeft));
+        return pSVData->mpBlendFrameCache->m_aLastResult;
+    }
+
+    BlendFrameCache* pBlendFrameCache = pSVData->mpBlendFrameCache.get();
+
+    if(pBlendFrameCache->m_aLastSize == rSize
+        && pBlendFrameCache->m_nLastAlpha == nAlpha
+        && pBlendFrameCache->m_aLastColorTopLeft == rColorTopLeft
+        && pBlendFrameCache->m_aLastColorTopRight == rColorTopRight
+        && pBlendFrameCache->m_aLastColorBottomRight == rColorBottomRight
+        && pBlendFrameCache->m_aLastColorBottomLeft == rColorBottomLeft)
+    {
+        return pBlendFrameCache->m_aLastResult;
+    }
+
+    pSVData->mpBlendFrameCache.reset(new BlendFrameCache(rSize, nAlpha, 
rColorTopLeft, rColorTopRight, rColorBottomRight, rColorBottomLeft));
+    return pSVData->mpBlendFrameCache->m_aLastResult;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to