diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-07-03 16:02:00 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2020-07-20 12:40:17 +0200 |
commit | 1db7decf3fb172542f5fce03ce7bf0cb310d1ffc (patch) | |
tree | 62fd07448601881abee1bde837aa2cd55460387f /drawinglayer | |
parent | 92146170f1a317e69201f2c801325325182476d2 (diff) |
limit bitmap size for glow/softedge effects to visible area (tdf#134237)
When zooming in the bitmap can become huge, requiring a lot
of processing, most of it not being used.
Change-Id: I0a4907f5cf23ab7316fed8568924fe76c744b81a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97872
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'drawinglayer')
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index b91bf57c360d..cec0ed29eaf6 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -1002,26 +1002,38 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv mpOutputDevice->SetAntialiasing(AntialiasingFlags::NONE); mpOutputDevice->Erase(); process(rCandidate); - const tools::Rectangle aRect(static_cast<long>(std::floor(aRange.getMinX())), - static_cast<long>(std::floor(aRange.getMinY())), - static_cast<long>(std::ceil(aRange.getMaxX())), - static_cast<long>(std::ceil(aRange.getMaxY()))); - BitmapEx bmpEx = mpOutputDevice->GetBitmapEx(aRect.TopLeft(), aRect.GetSize()); - mpOutputDevice->SetAntialiasing(aPrevAA); - - AlphaMask mask - = ProcessAndBlurAlphaMask(bmpEx.GetAlpha(), fBlurRadius, fBlurRadius, nTransparency); - - // The end result is the bitmap filled with glow color and blurred 8-bit alpha mask - const basegfx::BColor aGlowColor( - maBColorModifierStack.getModifiedColor(rCandidate.getGlowColor().getBColor())); - Bitmap bmp = bmpEx.GetBitmap(); - bmp.Erase(Color(aGlowColor)); - BitmapEx result(bmp, mask); - // back to old OutDev - mpOutputDevice = pLastOutputDevice; - mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result); + // Limit the bitmap size to the visible area. + basegfx::B2DRange viewRange(getViewInformation2D().getDiscreteViewport()); + basegfx::B2DRange bitmapRange(aRange); + bitmapRange.intersect(viewRange); + if (!bitmapRange.isEmpty()) + { + const tools::Rectangle aRect(static_cast<long>(std::floor(bitmapRange.getMinX())), + static_cast<long>(std::floor(bitmapRange.getMinY())), + static_cast<long>(std::ceil(bitmapRange.getMaxX())), + static_cast<long>(std::ceil(bitmapRange.getMaxY()))); + BitmapEx bmpEx = mpOutputDevice->GetBitmapEx(aRect.TopLeft(), aRect.GetSize()); + mpOutputDevice->SetAntialiasing(aPrevAA); + + AlphaMask mask = ProcessAndBlurAlphaMask(bmpEx.GetAlpha(), fBlurRadius, fBlurRadius, + nTransparency); + + // The end result is the bitmap filled with glow color and blurred 8-bit alpha mask + const basegfx::BColor aGlowColor( + maBColorModifierStack.getModifiedColor(rCandidate.getGlowColor().getBColor())); + Bitmap bmp = bmpEx.GetBitmap(); + bmp.Erase(Color(aGlowColor)); + BitmapEx result(bmp, mask); + + // back to old OutDev + mpOutputDevice = pLastOutputDevice; + mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result); + } + else + { + mpOutputDevice = pLastOutputDevice; + } } else SAL_WARN("drawinglayer", "Temporary buffered virtual device is not visible"); @@ -1053,23 +1065,34 @@ void VclPixelProcessor2D::processSoftEdgePrimitive2D( // because it would result in poor quality in areas not affected by the effect process(rCandidate); - const tools::Rectangle aRect(static_cast<long>(std::floor(aRange.getMinX())), - static_cast<long>(std::floor(aRange.getMinY())), - static_cast<long>(std::ceil(aRange.getMaxX())), - static_cast<long>(std::ceil(aRange.getMaxY()))); - BitmapEx bitmap = mpOutputDevice->GetBitmapEx(aRect.TopLeft(), aRect.GetSize()); + // Limit the bitmap size to the visible area. + basegfx::B2DRange viewRange(getViewInformation2D().getDiscreteViewport()); + basegfx::B2DRange bitmapRange(aRange); + bitmapRange.intersect(viewRange); + if (!bitmapRange.isEmpty()) + { + const tools::Rectangle aRect(static_cast<long>(std::floor(bitmapRange.getMinX())), + static_cast<long>(std::floor(bitmapRange.getMinY())), + static_cast<long>(std::ceil(bitmapRange.getMaxX())), + static_cast<long>(std::ceil(bitmapRange.getMaxY()))); + BitmapEx bitmap = mpOutputDevice->GetBitmapEx(aRect.TopLeft(), aRect.GetSize()); - AlphaMask aMask = bitmap.GetAlpha(); - AlphaMask blurMask = ProcessAndBlurAlphaMask(aMask, -fBlurRadius, fBlurRadius, 0); + AlphaMask aMask = bitmap.GetAlpha(); + AlphaMask blurMask = ProcessAndBlurAlphaMask(aMask, -fBlurRadius, fBlurRadius, 0); - aMask.BlendWith(blurMask); + aMask.BlendWith(blurMask); - // The end result is the original bitmap with blurred 8-bit alpha mask - BitmapEx result(bitmap.GetBitmap(), aMask); + // The end result is the original bitmap with blurred 8-bit alpha mask + BitmapEx result(bitmap.GetBitmap(), aMask); - // back to old OutDev - mpOutputDevice = pLastOutputDevice; - mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result); + // back to old OutDev + mpOutputDevice = pLastOutputDevice; + mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result); + } + else + { + mpOutputDevice = pLastOutputDevice; + } } else SAL_WARN("drawinglayer", "Temporary buffered virtual device is not visible"); |