include/vcl/bitmap.hxx            |   15 ++
 vcl/source/bitmap/bitmappaint.cxx |  253 ++++++++++++++++++++------------------
 2 files changed, 150 insertions(+), 118 deletions(-)

New commits:
commit 5244e7cab70a3c1f567e2e3cda41bd753e5cb530
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Mon Jan 2 19:21:34 2023 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon Jan 2 20:23:10 2023 +0000

    split OutputDevice::CreateMask method
    
    to make it easier to understand, very little of the code is shared
    between the nTol == 0 and the nTol != 0 cases.
    
    Also flatten the code structure a little.
    
    Change-Id: I601b9046a6678a5dcf2176dbfe565a9a4e7299d4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144962
    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 123b48fcd752..a732e77f3a97 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -343,6 +343,19 @@ public:
      */
     bool                    Rotate( Degree10 nAngle10, const Color& rFillColor 
);
 
+    /** Create on-off mask from bitmap
+
+        This method creates a bitmask from the bitmap, where every
+        pixel that equals rTransColor is set transparent, the rest
+        opaque.
+
+        @param rTransColor
+        Color value where the bitmask should be transparent
+
+        @return the resulting bitmask.
+     */
+    Bitmap                  CreateMask( const Color& rTransColor ) const;
+
     /** Create on-off mask from bitmap
 
         This method creates a bitmask from the bitmap, where every
@@ -359,7 +372,7 @@ public:
 
         @return the resulting bitmask.
      */
-    Bitmap                  CreateMask( const Color& rTransColor, sal_uInt8 
nTol = 0 ) const;
+    Bitmap                  CreateMask( const Color& rTransColor, sal_uInt8 
nTol ) const;
 
     /** Create region of similar colors in a given rectangle
 
diff --git a/vcl/source/bitmap/bitmappaint.cxx 
b/vcl/source/bitmap/bitmappaint.cxx
index c0f6715238e7..cdece0f438ed 100644
--- a/vcl/source/bitmap/bitmappaint.cxx
+++ b/vcl/source/bitmap/bitmappaint.cxx
@@ -433,18 +433,19 @@ bool Bitmap::Rotate(Degree10 nAngle10, const Color& 
rFillColor)
     return bRet;
 };
 
-Bitmap Bitmap::CreateMask(const Color& rTransColor, sal_uInt8 nTol) const
+Bitmap Bitmap::CreateMask(const Color& rTransColor) const
 {
     ScopedReadAccess pReadAcc(const_cast<Bitmap&>(*this));
+    if (!pReadAcc)
+        return Bitmap();
 
     // Historically LO used 1bpp masks, but 8bpp masks are much faster,
     // better supported by hardware, and the memory savings are not worth
     // it anymore.
     // TODO: Possibly remove the 1bpp code later.
 
-    if (!nTol && pReadAcc
-        && (pReadAcc->GetScanlineFormat() == ScanlineFormat::N1BitLsbPal
-            || pReadAcc->GetScanlineFormat() == ScanlineFormat::N1BitMsbPal)
+    if ((pReadAcc->GetScanlineFormat() == ScanlineFormat::N1BitLsbPal
+         || pReadAcc->GetScanlineFormat() == ScanlineFormat::N1BitMsbPal)
         && pReadAcc->GetBestMatchingColor(COL_WHITE) == 
pReadAcc->GetBestMatchingColor(rTransColor))
     {
         // if we're a 1 bit pixel already, and the transcolor matches the 
color that would replace it
@@ -455,146 +456,164 @@ Bitmap Bitmap::CreateMask(const Color& rTransColor, 
sal_uInt8 nTol) const
     auto ePixelFormat = vcl::PixelFormat::N8_BPP;
     Bitmap aNewBmp(GetSizePixel(), ePixelFormat, &Bitmap::GetGreyPalette(256));
     BitmapScopedWriteAccess pWriteAcc(aNewBmp);
-    bool bRet = false;
+    if (!pWriteAcc)
+        return Bitmap();
 
-    if (pWriteAcc && pReadAcc)
-    {
-        const tools::Long nWidth = pReadAcc->Width();
-        const tools::Long nHeight = pReadAcc->Height();
-        const BitmapColor aBlack(pWriteAcc->GetBestMatchingColor(COL_BLACK));
-        const BitmapColor aWhite(pWriteAcc->GetBestMatchingColor(COL_WHITE));
+    const tools::Long nWidth = pReadAcc->Width();
+    const tools::Long nHeight = pReadAcc->Height();
+    const BitmapColor aBlack(pWriteAcc->GetBestMatchingColor(COL_BLACK));
+    const BitmapColor aWhite(pWriteAcc->GetBestMatchingColor(COL_WHITE));
+
+    const BitmapColor aTest(pReadAcc->GetBestMatchingColor(rTransColor));
 
-        if (!nTol)
+    if (pWriteAcc->GetScanlineFormat() == pReadAcc->GetScanlineFormat() && 
aWhite.GetIndex() == 1
+        && (pReadAcc->GetScanlineFormat() == ScanlineFormat::N1BitLsbPal
+            || pReadAcc->GetScanlineFormat() == ScanlineFormat::N1BitMsbPal))
+    {
+        for (tools::Long nY = 0; nY < nHeight; ++nY)
         {
-            const BitmapColor 
aTest(pReadAcc->GetBestMatchingColor(rTransColor));
+            Scanline pSrc = pReadAcc->GetScanline(nY);
+            Scanline pDst = pWriteAcc->GetScanline(nY);
+            assert(pWriteAcc->GetScanlineSize() == 
pReadAcc->GetScanlineSize());
+            const tools::Long nScanlineSize = pWriteAcc->GetScanlineSize();
+            for (tools::Long nX = 0; nX < nScanlineSize; ++nX)
+                pDst[nX] = ~pSrc[nX];
+        }
+    }
+    else if (pReadAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal)
+    {
+        // optimized for 8Bit source palette
+        const sal_uInt8 cTest = aTest.GetIndex();
 
-            if (pWriteAcc->GetScanlineFormat() == pReadAcc->GetScanlineFormat()
-                && aWhite.GetIndex() == 1
-                && (pReadAcc->GetScanlineFormat() == 
ScanlineFormat::N1BitLsbPal
-                    || pReadAcc->GetScanlineFormat() == 
ScanlineFormat::N1BitMsbPal))
+        for (tools::Long nY = 0; nY < nHeight; ++nY)
+        {
+            Scanline pSrc = pReadAcc->GetScanline(nY);
+            Scanline pDst = pWriteAcc->GetScanline(nY);
+            for (tools::Long nX = 0; nX < nWidth; ++nX)
             {
-                for (tools::Long nY = 0; nY < nHeight; ++nY)
-                {
-                    Scanline pSrc = pReadAcc->GetScanline(nY);
-                    Scanline pDst = pWriteAcc->GetScanline(nY);
-                    assert(pWriteAcc->GetScanlineSize() == 
pReadAcc->GetScanlineSize());
-                    const tools::Long nScanlineSize = 
pWriteAcc->GetScanlineSize();
-                    for (tools::Long nX = 0; nX < nScanlineSize; ++nX)
-                        pDst[nX] = ~pSrc[nX];
-                }
+                if (cTest == pSrc[nX])
+                    pDst[nX] = aWhite.GetIndex();
+                else
+                    pDst[nX] = aBlack.GetIndex();
+            }
+        }
+    }
+    else
+    {
+        // not optimized
+        for (tools::Long nY = 0; nY < nHeight; ++nY)
+        {
+            Scanline pScanline = pWriteAcc->GetScanline(nY);
+            Scanline pScanlineRead = pReadAcc->GetScanline(nY);
+            for (tools::Long nX = 0; nX < nWidth; ++nX)
+            {
+                if (aTest == pReadAcc->GetPixelFromData(pScanlineRead, nX))
+                    pWriteAcc->SetPixelOnData(pScanline, nX, aWhite);
+                else
+                    pWriteAcc->SetPixelOnData(pScanline, nX, aBlack);
             }
-            else if (pReadAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal)
+        }
+    }
+
+    pWriteAcc.reset();
+    pReadAcc.reset();
+
+    aNewBmp.maPrefSize = maPrefSize;
+    aNewBmp.maPrefMapMode = maPrefMapMode;
+
+    return aNewBmp;
+}
+
+Bitmap Bitmap::CreateMask(const Color& rTransColor, sal_uInt8 nTol) const
+{
+    if (nTol == 0)
+        return CreateMask(rTransColor);
+
+    ScopedReadAccess pReadAcc(const_cast<Bitmap&>(*this));
+    if (!pReadAcc)
+        return Bitmap();
+
+    // Historically LO used 1bpp masks, but 8bpp masks are much faster,
+    // better supported by hardware, and the memory savings are not worth
+    // it anymore.
+    // TODO: Possibly remove the 1bpp code later.
+
+    auto ePixelFormat = vcl::PixelFormat::N8_BPP;
+    Bitmap aNewBmp(GetSizePixel(), ePixelFormat, &Bitmap::GetGreyPalette(256));
+    BitmapScopedWriteAccess pWriteAcc(aNewBmp);
+    if (!pWriteAcc)
+        return Bitmap();
+
+    const tools::Long nWidth = pReadAcc->Width();
+    const tools::Long nHeight = pReadAcc->Height();
+    const BitmapColor aBlack(pWriteAcc->GetBestMatchingColor(COL_BLACK));
+    const BitmapColor aWhite(pWriteAcc->GetBestMatchingColor(COL_WHITE));
+
+    BitmapColor aCol;
+    tools::Long nR, nG, nB;
+    const tools::Long nMinR = MinMax<tools::Long>(rTransColor.GetRed() - nTol, 
0, 255);
+    const tools::Long nMaxR = MinMax<tools::Long>(rTransColor.GetRed() + nTol, 
0, 255);
+    const tools::Long nMinG = MinMax<tools::Long>(rTransColor.GetGreen() - 
nTol, 0, 255);
+    const tools::Long nMaxG = MinMax<tools::Long>(rTransColor.GetGreen() + 
nTol, 0, 255);
+    const tools::Long nMinB = MinMax<tools::Long>(rTransColor.GetBlue() - 
nTol, 0, 255);
+    const tools::Long nMaxB = MinMax<tools::Long>(rTransColor.GetBlue() + 
nTol, 0, 255);
+
+    if (pReadAcc->HasPalette())
+    {
+        for (tools::Long nY = 0; nY < nHeight; nY++)
+        {
+            Scanline pScanline = pWriteAcc->GetScanline(nY);
+            Scanline pScanlineRead = pReadAcc->GetScanline(nY);
+            for (tools::Long nX = 0; nX < nWidth; nX++)
             {
-                // optimized for 8Bit source palette
-                const sal_uInt8 cTest = aTest.GetIndex();
+                aCol = 
pReadAcc->GetPaletteColor(pReadAcc->GetIndexFromData(pScanlineRead, nX));
+                nR = aCol.GetRed();
+                nG = aCol.GetGreen();
+                nB = aCol.GetBlue();
 
-                for (tools::Long nY = 0; nY < nHeight; ++nY)
+                if (nMinR <= nR && nMaxR >= nR && nMinG <= nG && nMaxG >= nG 
&& nMinB <= nB
+                    && nMaxB >= nB)
                 {
-                    Scanline pSrc = pReadAcc->GetScanline(nY);
-                    Scanline pDst = pWriteAcc->GetScanline(nY);
-                    for (tools::Long nX = 0; nX < nWidth; ++nX)
-                    {
-                        if (cTest == pSrc[nX])
-                            pDst[nX] = aWhite.GetIndex();
-                        else
-                            pDst[nX] = aBlack.GetIndex();
-                    }
+                    pWriteAcc->SetPixelOnData(pScanline, nX, aWhite);
                 }
-            }
-            else
-            {
-                // not optimized
-                for (tools::Long nY = 0; nY < nHeight; ++nY)
+                else
                 {
-                    Scanline pScanline = pWriteAcc->GetScanline(nY);
-                    Scanline pScanlineRead = pReadAcc->GetScanline(nY);
-                    for (tools::Long nX = 0; nX < nWidth; ++nX)
-                    {
-                        if (aTest == pReadAcc->GetPixelFromData(pScanlineRead, 
nX))
-                            pWriteAcc->SetPixelOnData(pScanline, nX, aWhite);
-                        else
-                            pWriteAcc->SetPixelOnData(pScanline, nX, aBlack);
-                    }
+                    pWriteAcc->SetPixelOnData(pScanline, nX, aBlack);
                 }
             }
         }
-        else
+    }
+    else
+    {
+        for (tools::Long nY = 0; nY < nHeight; nY++)
         {
-            BitmapColor aCol;
-            tools::Long nR, nG, nB;
-            const tools::Long nMinR = MinMax<tools::Long>(rTransColor.GetRed() 
- nTol, 0, 255);
-            const tools::Long nMaxR = MinMax<tools::Long>(rTransColor.GetRed() 
+ nTol, 0, 255);
-            const tools::Long nMinG = 
MinMax<tools::Long>(rTransColor.GetGreen() - nTol, 0, 255);
-            const tools::Long nMaxG = 
MinMax<tools::Long>(rTransColor.GetGreen() + nTol, 0, 255);
-            const tools::Long nMinB = 
MinMax<tools::Long>(rTransColor.GetBlue() - nTol, 0, 255);
-            const tools::Long nMaxB = 
MinMax<tools::Long>(rTransColor.GetBlue() + nTol, 0, 255);
-
-            if (pReadAcc->HasPalette())
+            Scanline pScanline = pWriteAcc->GetScanline(nY);
+            Scanline pScanlineRead = pReadAcc->GetScanline(nY);
+            for (tools::Long nX = 0; nX < nWidth; nX++)
             {
-                for (tools::Long nY = 0; nY < nHeight; nY++)
+                aCol = pReadAcc->GetPixelFromData(pScanlineRead, nX);
+                nR = aCol.GetRed();
+                nG = aCol.GetGreen();
+                nB = aCol.GetBlue();
+
+                if (nMinR <= nR && nMaxR >= nR && nMinG <= nG && nMaxG >= nG 
&& nMinB <= nB
+                    && nMaxB >= nB)
                 {
-                    Scanline pScanline = pWriteAcc->GetScanline(nY);
-                    Scanline pScanlineRead = pReadAcc->GetScanline(nY);
-                    for (tools::Long nX = 0; nX < nWidth; nX++)
-                    {
-                        aCol = pReadAcc->GetPaletteColor(
-                            pReadAcc->GetIndexFromData(pScanlineRead, nX));
-                        nR = aCol.GetRed();
-                        nG = aCol.GetGreen();
-                        nB = aCol.GetBlue();
-
-                        if (nMinR <= nR && nMaxR >= nR && nMinG <= nG && nMaxG 
>= nG && nMinB <= nB
-                            && nMaxB >= nB)
-                        {
-                            pWriteAcc->SetPixelOnData(pScanline, nX, aWhite);
-                        }
-                        else
-                        {
-                            pWriteAcc->SetPixelOnData(pScanline, nX, aBlack);
-                        }
-                    }
+                    pWriteAcc->SetPixelOnData(pScanline, nX, aWhite);
                 }
-            }
-            else
-            {
-                for (tools::Long nY = 0; nY < nHeight; nY++)
+                else
                 {
-                    Scanline pScanline = pWriteAcc->GetScanline(nY);
-                    Scanline pScanlineRead = pReadAcc->GetScanline(nY);
-                    for (tools::Long nX = 0; nX < nWidth; nX++)
-                    {
-                        aCol = pReadAcc->GetPixelFromData(pScanlineRead, nX);
-                        nR = aCol.GetRed();
-                        nG = aCol.GetGreen();
-                        nB = aCol.GetBlue();
-
-                        if (nMinR <= nR && nMaxR >= nR && nMinG <= nG && nMaxG 
>= nG && nMinB <= nB
-                            && nMaxB >= nB)
-                        {
-                            pWriteAcc->SetPixelOnData(pScanline, nX, aWhite);
-                        }
-                        else
-                        {
-                            pWriteAcc->SetPixelOnData(pScanline, nX, aBlack);
-                        }
-                    }
+                    pWriteAcc->SetPixelOnData(pScanline, nX, aBlack);
                 }
             }
         }
-
-        bRet = true;
     }
 
     pWriteAcc.reset();
     pReadAcc.reset();
 
-    if (bRet)
-    {
-        aNewBmp.maPrefSize = maPrefSize;
-        aNewBmp.maPrefMapMode = maPrefMapMode;
-    }
-    else
-        aNewBmp = Bitmap();
+    aNewBmp.maPrefSize = maPrefSize;
+    aNewBmp.maPrefMapMode = maPrefMapMode;
 
     return aNewBmp;
 }

Reply via email to