vcl/Library_vcl.mk                    |    1 
 vcl/inc/bitmap/BlendFrameCache.hxx    |   40 ++++++++++
 vcl/inc/svdata.hxx                    |   23 -----
 vcl/source/app/svdata.cxx             |   11 --
 vcl/source/app/svmain.cxx             |    2 
 vcl/source/bitmap/BitmapEx.cxx        |  119 ++---------------------------
 vcl/source/bitmap/BlendFrameCache.cxx |  136 ++++++++++++++++++++++++++++++++++
 7 files changed, 193 insertions(+), 139 deletions(-)

New commits:
commit 9efbc448876d92d24697fa0eddd4580dcdbb9672
Author:     Christopher Sherlock <chris.sherloc...@gmail.com>
AuthorDate: Wed Dec 4 21:17:36 2024 +1100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri Dec 20 07:16:49 2024 +0100

    vcl: BlendFrameCache refactor
    
    - split off BlendFrameCache.hxx to own header
    - move functionality into constructor
    
    Much of the functionality in createAlphaBlendFrame() just updates the
    BlendFrameCache's bitmap frame. Really, this should be done when a
    BlendFrameCache is instantiated, so functionality has been moved out of
    createAlphaBlendFrame() and into the BlendFrameCache constructor.
    
    Change-Id: Ia53a6f1c058ccb5f0ee4314b7a6e0b02ad7db376
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177802
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 79ea2cc1974a..8ce46293c988 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -434,6 +434,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/bitmap/BitmapColorQuantizationFilter \
     vcl/source/bitmap/BitmapSimpleColorQuantizationFilter \
     vcl/source/bitmap/BitmapTools \
+    vcl/source/bitmap/BlendFrameCache \
     vcl/source/bitmap/Octree \
     vcl/source/bitmap/salbmp \
     vcl/source/image/Image \
diff --git a/vcl/inc/bitmap/BlendFrameCache.hxx 
b/vcl/inc/bitmap/BlendFrameCache.hxx
new file mode 100644
index 000000000000..61d4ff6de6aa
--- /dev/null
+++ b/vcl/inc/bitmap/BlendFrameCache.hxx
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/color.hxx>
+#include <tools/gen.hxx>
+
+#include <vcl/bitmapex.hxx>
+
+struct BlendFrameCache
+{
+    Size m_aLastSize;
+    sal_uInt8 m_nLastAlpha;
+    Color m_aLastColorTopLeft;
+    Color m_aLastColorTopRight;
+    Color m_aLastColorBottomRight;
+    Color m_aLastColorBottomLeft;
+    BitmapEx m_aLastResult;
+
+    BlendFrameCache(Size const& rSize, sal_uInt8 nAlpha, Color const& 
rColorTopLeft,
+                    Color const& rColorTopRight, Color const& 
rColorBottomRight,
+                    Color const& rColorBottomLeft);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index c332894e1fc8..86b07bce6caa 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -69,6 +69,7 @@ namespace vcl::font
     class DirectFontSubstitution;
     class PhysicalFontCollection;
 }
+struct BlendFrameCache;
 struct ImplHotKey;
 struct ImplEventHook;
 class Point;
@@ -355,27 +356,6 @@ struct ImplSVNWFData
     int mnListBoxEntryMargin = 0;
 };
 
-struct BlendFrameCache
-{
-    Size m_aLastSize;
-    sal_uInt8 m_nLastAlpha;
-    Color m_aLastColorTopLeft;
-    Color m_aLastColorTopRight;
-    Color m_aLastColorBottomRight;
-    Color m_aLastColorBottomLeft;
-    BitmapEx m_aLastResult;
-
-    BlendFrameCache()
-        : m_aLastSize(0, 0)
-        , m_nLastAlpha(0)
-        , m_aLastColorTopLeft(COL_BLACK)
-        , m_aLastColorTopRight(COL_BLACK)
-        , m_aLastColorBottomRight(COL_BLACK)
-        , m_aLastColorBottomLeft(COL_BLACK)
-    {
-    }
-};
-
 struct ImplSchedulerContext
 {
     ImplSchedulerData*      mpFirstSchedulerData[PRIO_COUNT] = { nullptr, }; 
///< list of all active tasks per priority
@@ -452,7 +432,6 @@ vcl::Window* ImplGetDefaultContextWindow();
 const std::locale& ImplGetResLocale();
 VCL_PLUGIN_PUBLIC OUString VclResId(TranslateId sContextAndId);
 DockingManager*     ImplGetDockingManager();
-BlendFrameCache*    ImplGetBlendFrameCache();
 void GenerateAutoMnemonicsOnHierarchy(const vcl::Window* pWindow);
 
 VCL_PLUGIN_PUBLIC ImplSVHelpData& ImplGetSVHelpData();
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index f767c2483925..2ff5e69abf48 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -38,6 +38,8 @@
 #include <vcl/virdev.hxx>
 #include <vcl/wrkwin.hxx>
 #include <vcl/uitest/logger.hxx>
+
+#include <bitmap/BlendFrameCache.hxx>
 #include <salframe.hxx>
 #include <scrwnd.hxx>
 #include <helpwin.hxx>
@@ -362,15 +364,6 @@ DockingManager* ImplGetDockingManager()
     return pSVData->mpDockingManager.get();
 }
 
-BlendFrameCache* ImplGetBlendFrameCache()
-{
-    ImplSVData* pSVData = ImplGetSVData();
-    if ( !pSVData->mpBlendFrameCache)
-        pSVData->mpBlendFrameCache.reset( new BlendFrameCache() );
-
-    return pSVData->mpBlendFrameCache.get();
-}
-
 void LocaleConfigurationListener::ConfigurationChanged( 
utl::ConfigurationBroadcaster*, ConfigurationHints nHint )
 {
     AllSettings::LocaleSettingsChanged( nHint );
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 9ef22da996e6..4c81138c117f 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -51,6 +51,8 @@
 #include <vcl/menu.hxx>
 #include <vcl/virdev.hxx>
 #include <vcl/print.hxx>
+
+#include <bitmap/BlendFrameCache.hxx>
 #include <debugevent.hxx>
 #include <scrwnd.hxx>
 #include <windowdev.hxx>
diff --git a/vcl/source/bitmap/BitmapEx.cxx b/vcl/source/bitmap/BitmapEx.cxx
index d20954b270dc..0d734eaa1831 100644
--- a/vcl/source/bitmap/BitmapEx.cxx
+++ b/vcl/source/bitmap/BitmapEx.cxx
@@ -40,6 +40,7 @@
 #include <svdata.hxx>
 #include <vcl/BitmapWriteAccess.hxx>
 #include <bitmap/BitmapMaskToAlphaFilter.hxx>
+#include <bitmap/BlendFrameCache.hxx>
 
 #include <o3tl/any.hxx>
 #include <tools/stream.hxx>
@@ -1056,7 +1057,14 @@ BitmapEx createAlphaBlendFrame(
     const Color& rColorBottomRight,
     const Color& rColorBottomLeft)
 {
-    BlendFrameCache* pBlendFrameCache = ImplGetBlendFrameCache();
+    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
@@ -1068,113 +1076,8 @@ BitmapEx createAlphaBlendFrame(
         return pBlendFrameCache->m_aLastResult;
     }
 
-    pBlendFrameCache->m_aLastSize = rSize;
-    pBlendFrameCache->m_nLastAlpha = nAlpha;
-    pBlendFrameCache->m_aLastColorTopLeft = rColorTopLeft;
-    pBlendFrameCache->m_aLastColorTopRight = rColorTopRight;
-    pBlendFrameCache->m_aLastColorBottomRight = rColorBottomRight;
-    pBlendFrameCache->m_aLastColorBottomLeft = rColorBottomLeft;
-    pBlendFrameCache->m_aLastResult.Clear();
-
-    const tools::Long nW(rSize.Width());
-    const tools::Long nH(rSize.Height());
-
-    if(nW > 1 && nH > 1)
-    {
-        sal_uInt8 aEraseTrans(0xff);
-        Bitmap aContent(rSize, vcl::PixelFormat::N24_BPP);
-        AlphaMask aAlpha(rSize, &aEraseTrans);
-
-        aContent.Erase(COL_BLACK);
-
-        BitmapScopedWriteAccess pContent(aContent);
-        BitmapScopedWriteAccess pAlpha(aAlpha);
-
-        if(pContent && pAlpha)
-        {
-            tools::Long x(0);
-            tools::Long y(0);
-            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));
-
-            // y == 0, top line left to right
-            for(x = 1; x < nW - 1; x++)
-            {
-                Color aMix(rColorTopLeft);
-
-                aMix.Merge(rColorTopRight, 255 - sal_uInt8((x * 255) / nW));
-                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));
-            }
-
-            // x == 0 and nW - 1, left and right line top-down
-            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));
-                pContent->SetPixelOnData(pScanContent, 0, aMixA);
-                pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
-
-                // #i123690# Caution! When nW is 1, x == nW is possible (!)
-                if(x < nW)
-                {
-                    Color aMixB(rColorTopRight);
-
-                    aMixB.Merge(rColorBottomRight, 255 - sal_uInt8((y * 255) / 
nH));
-                    pContent->SetPixelOnData(pScanContent, x, aMixB);
-                    pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
-                }
-            }
-
-            // #i123690# Caution! When nH is 1, y == nH is possible (!)
-            if(y < nH)
-            {
-                // x == 0, y == nH - 1, bottom-left corner
-                pContent->SetPixelOnData(pScanContent, 0, rColorBottomLeft);
-                pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
-
-                // y == nH - 1, bottom line left to right
-                for(x = 1; x < nW - 1; x++)
-                {
-                    Color aMix(rColorBottomLeft);
-
-                    aMix.Merge(rColorBottomRight, 255 - sal_uInt8(((x - 0)* 
255) / nW));
-                    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));
-                }
-            }
-
-            pContent.reset();
-            pAlpha.reset();
-
-            pBlendFrameCache->m_aLastResult = BitmapEx(aContent, aAlpha);
-        }
-    }
-
-    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,
diff --git a/vcl/source/bitmap/BlendFrameCache.cxx 
b/vcl/source/bitmap/BlendFrameCache.cxx
new file mode 100644
index 000000000000..190dbf3d9e44
--- /dev/null
+++ b/vcl/source/bitmap/BlendFrameCache.cxx
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/color.hxx>
+
+#include <vcl/BitmapColor.hxx>
+#include <vcl/BitmapWriteAccess.hxx>
+
+#include <bitmap/BlendFrameCache.hxx>
+
+BlendFrameCache::BlendFrameCache(Size const& rSize, sal_uInt8 nAlpha, Color 
const& rColorTopLeft,
+                                 Color const& rColorTopRight, Color const& 
rColorBottomRight,
+                                 Color const& rColorBottomLeft)
+    : m_aLastSize(rSize)
+    , m_nLastAlpha(nAlpha)
+    , m_aLastColorTopLeft(rColorTopLeft)
+    , m_aLastColorTopRight(rColorTopRight)
+    , m_aLastColorBottomRight(rColorBottomRight)
+    , m_aLastColorBottomLeft(rColorBottomLeft)
+{
+    const tools::Long nW(rSize.Width());
+    const tools::Long nH(rSize.Height());
+
+    if (nW > 1 && nH > 1)
+    {
+        sal_uInt8 aEraseTrans(0xff);
+        Bitmap aContent(rSize, vcl::PixelFormat::N24_BPP);
+        AlphaMask aAlpha(rSize, &aEraseTrans);
+
+        aContent.Erase(COL_BLACK);
+
+        BitmapScopedWriteAccess pContent(aContent);
+        BitmapScopedWriteAccess pAlpha(aAlpha);
+
+        if (pContent && pAlpha)
+        {
+            tools::Long x(0);
+            tools::Long y(0);
+            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));
+
+            // y == 0, top line left to right
+            for (x = 1; x < nW - 1; x++)
+            {
+                Color aMix(rColorTopLeft);
+
+                aMix.Merge(rColorTopRight, 255 - sal_uInt8((x * 255) / nW));
+                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));
+            }
+
+            // x == 0 and nW - 1, left and right line top-down
+            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));
+                pContent->SetPixelOnData(pScanContent, 0, aMixA);
+                pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
+
+                // #i123690# Caution! When nW is 1, x == nW is possible (!)
+                if (x < nW)
+                {
+                    Color aMixB(rColorTopRight);
+
+                    aMixB.Merge(rColorBottomRight, 255 - sal_uInt8((y * 255) / 
nH));
+                    pContent->SetPixelOnData(pScanContent, x, aMixB);
+                    pAlpha->SetPixelOnData(pScanAlpha, x, BitmapColor(nAlpha));
+                }
+            }
+
+            // #i123690# Caution! When nH is 1, y == nH is possible (!)
+            if (y < nH)
+            {
+                // x == 0, y == nH - 1, bottom-left corner
+                pContent->SetPixelOnData(pScanContent, 0, rColorBottomLeft);
+                pAlpha->SetPixelOnData(pScanAlpha, 0, BitmapColor(nAlpha));
+
+                // y == nH - 1, bottom line left to right
+                for (x = 1; x < nW - 1; x++)
+                {
+                    Color aMix(rColorBottomLeft);
+
+                    aMix.Merge(rColorBottomRight, 255 - sal_uInt8(((x - 0) * 
255) / nW));
+                    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));
+                }
+            }
+
+            pContent.reset();
+            pAlpha.reset();
+
+            m_aLastResult = BitmapEx(aContent, aAlpha);
+        }
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */

Reply via email to