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:
@@ -1002,26 +1002,38 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv
|
|||||||
mpOutputDevice->SetAntialiasing(AntialiasingFlags::NONE);
|
mpOutputDevice->SetAntialiasing(AntialiasingFlags::NONE);
|
||||||
mpOutputDevice->Erase();
|
mpOutputDevice->Erase();
|
||||||
process(rCandidate);
|
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
|
// Limit the bitmap size to the visible area.
|
||||||
= ProcessAndBlurAlphaMask(bmpEx.GetAlpha(), fBlurRadius, fBlurRadius, nTransparency);
|
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
|
AlphaMask mask = ProcessAndBlurAlphaMask(bmpEx.GetAlpha(), fBlurRadius, fBlurRadius,
|
||||||
const basegfx::BColor aGlowColor(
|
nTransparency);
|
||||||
maBColorModifierStack.getModifiedColor(rCandidate.getGlowColor().getBColor()));
|
|
||||||
Bitmap bmp = bmpEx.GetBitmap();
|
|
||||||
bmp.Erase(Color(aGlowColor));
|
|
||||||
BitmapEx result(bmp, mask);
|
|
||||||
|
|
||||||
// back to old OutDev
|
// The end result is the bitmap filled with glow color and blurred 8-bit alpha mask
|
||||||
mpOutputDevice = pLastOutputDevice;
|
const basegfx::BColor aGlowColor(
|
||||||
mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result);
|
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
|
else
|
||||||
SAL_WARN("drawinglayer", "Temporary buffered virtual device is not visible");
|
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
|
// because it would result in poor quality in areas not affected by the effect
|
||||||
process(rCandidate);
|
process(rCandidate);
|
||||||
|
|
||||||
const tools::Rectangle aRect(static_cast<long>(std::floor(aRange.getMinX())),
|
// Limit the bitmap size to the visible area.
|
||||||
static_cast<long>(std::floor(aRange.getMinY())),
|
basegfx::B2DRange viewRange(getViewInformation2D().getDiscreteViewport());
|
||||||
static_cast<long>(std::ceil(aRange.getMaxX())),
|
basegfx::B2DRange bitmapRange(aRange);
|
||||||
static_cast<long>(std::ceil(aRange.getMaxY())));
|
bitmapRange.intersect(viewRange);
|
||||||
BitmapEx bitmap = mpOutputDevice->GetBitmapEx(aRect.TopLeft(), aRect.GetSize());
|
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 aMask = bitmap.GetAlpha();
|
||||||
AlphaMask blurMask = ProcessAndBlurAlphaMask(aMask, -fBlurRadius, fBlurRadius, 0);
|
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
|
// The end result is the original bitmap with blurred 8-bit alpha mask
|
||||||
BitmapEx result(bitmap.GetBitmap(), aMask);
|
BitmapEx result(bitmap.GetBitmap(), aMask);
|
||||||
|
|
||||||
// back to old OutDev
|
// back to old OutDev
|
||||||
mpOutputDevice = pLastOutputDevice;
|
mpOutputDevice = pLastOutputDevice;
|
||||||
mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result);
|
mpOutputDevice->DrawBitmapEx(aRect.TopLeft(), result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpOutputDevice = pLastOutputDevice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SAL_WARN("drawinglayer", "Temporary buffered virtual device is not visible");
|
SAL_WARN("drawinglayer", "Temporary buffered virtual device is not visible");
|
||||||
|
Reference in New Issue
Block a user