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>
This commit is contained in:
Luboš Luňák
2020-07-03 16:02:00 +02:00
parent 92146170f1
commit 1db7decf3f

View File

@@ -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);
// 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);
// 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);
AlphaMask mask = ProcessAndBlurAlphaMask(bmpEx.GetAlpha(), fBlurRadius, fBlurRadius,
nTransparency);
// back to old OutDev
mpOutputDevice = pLastOutputDevice;
mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result);
// 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");