diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-08-02 15:26:06 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-08-02 18:22:28 +0200 |
commit | f76acf9bd97e65ba50303b6e5a25e5877996ebe1 (patch) | |
tree | fa753dff999f5f78b203cdd18fe8cb0295e13156 /vcl/source/bitmap | |
parent | 76f50549f4898313ef4a18ce32d1f0a625ce766d (diff) |
tdf#156525 Save as > HTML loses drawing object as invalid gif
regression from
commit 1c7cbd685633d44eac554629572f3401c450f855
Author: Noel Grandin <noel.grandin@collabora.co.uk>
Date: Sun May 7 16:56:21 2023 +0200
use AlphaMask for variables when calling GetAlphaMask
where after my change, the code is now calling
Bitmap::Replace(AlphaMask,...)
instead of
Bitmap::Replace(Bitmap,...)
and those two methods do quite different things.
However, we have to
(*) restore Bitmap::Replace(Bitmap,...) which was removed in
commit 8270eb5d5600cc84dbf5f0e339f90c4519ef88bb
Author: Noel Grandin <noel.grandin@collabora.co.uk>
Date: Fri May 19 13:35:31 2023 +0200
loplugin:unusedmethods
(*) restore BitmapWriteAccess::SetPaletteEntryCount which was removed in
commit 74cd0d0b281f8df75612bfb600df2eae62c4d21d
Author: Noel Grandin <noel.grandin@collabora.co.uk>
Date: Thu Jun 29 13:53:30 2023 +0200
loplugin:unusedmethods
(*) Invert the mask/alpha layer, since after
commit 81994cb2b8b32453a92bcb011830fcb884f22ff3
Author: Noel Grandin <noelgrandin@gmail.com>
Date: Fri Apr 16 20:33:10 2021 +0200
Convert internal vcl bitmap formats transparency->alpha (II)
we are dealing with real alpha, and not transparency.
Also add an assert in GIFWriter::WriteAccess, since it is a logic error
to get here and have the image in the wrong format.
Change-Id: I0e09b3ca82af0bd5b58d80e0a6eac4c7bdf7c48e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155254
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'vcl/source/bitmap')
-rw-r--r-- | vcl/source/bitmap/bitmappaint.cxx | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/vcl/source/bitmap/bitmappaint.cxx b/vcl/source/bitmap/bitmappaint.cxx index 487e6d1a6ad6..91a43b951748 100644 --- a/vcl/source/bitmap/bitmappaint.cxx +++ b/vcl/source/bitmap/bitmappaint.cxx @@ -884,6 +884,81 @@ vcl::Region Bitmap::CreateRegion(const Color& rColor, const tools::Rectangle& rR return aRegion; } +bool Bitmap::ReplaceMask(const AlphaMask& rMask, const Color& rReplaceColor) +{ + ScopedReadAccess pMaskAcc(const_cast<AlphaMask&>(rMask)); + BitmapScopedWriteAccess pAcc(*this); + + if (!pMaskAcc || !pAcc) + return false; + + const tools::Long nWidth = std::min(pMaskAcc->Width(), pAcc->Width()); + const tools::Long nHeight = std::min(pMaskAcc->Height(), pAcc->Height()); + const BitmapColor aMaskWhite(pMaskAcc->GetBestMatchingColor(COL_WHITE)); + BitmapColor aReplace; + + if (pAcc->HasPalette()) + { + const sal_uInt16 nActColors = pAcc->GetPaletteEntryCount(); + const sal_uInt16 nMaxColors = 1 << pAcc->GetBitCount(); + + // default to the nearest color + aReplace = pAcc->GetBestMatchingColor(rReplaceColor); + + // for paletted images without a matching palette entry + // look for an unused palette entry (NOTE: expensive!) + if (pAcc->GetPaletteColor(aReplace.GetIndex()) != BitmapColor(rReplaceColor)) + { + // if the palette has empty entries use the last one + if (nActColors < nMaxColors) + { + pAcc->SetPaletteEntryCount(nActColors + 1); + pAcc->SetPaletteColor(nActColors, rReplaceColor); + aReplace = BitmapColor(static_cast<sal_uInt8>(nActColors)); + } + else + { + std::unique_ptr<bool[]> pFlags(new bool[nMaxColors]); + + // Set all entries to false + std::fill(pFlags.get(), pFlags.get() + nMaxColors, false); + + for (tools::Long nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pAcc->GetScanline(nY); + for (tools::Long nX = 0; nX < nWidth; nX++) + pFlags[pAcc->GetIndexFromData(pScanline, nX)] = true; + } + + for (sal_uInt16 i = 0; i < nMaxColors; i++) + { + // Hurray, we do have an unused entry + if (!pFlags[i]) + { + pAcc->SetPaletteColor(i, rReplaceColor); + aReplace = BitmapColor(static_cast<sal_uInt8>(i)); + } + } + } + } + } + else + aReplace = rReplaceColor; + + for (tools::Long nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pAcc->GetScanline(nY); + Scanline pScanlineMask = pMaskAcc->GetScanline(nY); + for (tools::Long nX = 0; nX < nWidth; nX++) + { + if (pMaskAcc->GetPixelFromData(pScanlineMask, nX) == aMaskWhite) + pAcc->SetPixelOnData(pScanline, nX, aReplace); + } + } + + return true; +} + bool Bitmap::Replace(const AlphaMask& rAlpha, const Color& rMergeColor) { Bitmap aNewBmp(GetSizePixel(), vcl::PixelFormat::N24_BPP); |