summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2020-08-13 18:12:37 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2020-08-14 01:00:04 +0200
commitbf021c369f2306ee507da9bd3cc4cd10ac5d234c (patch)
treea3dc2552801cfe31cb524c6f375980eaa48e844b
parent56d5531373cf0588e02c254ea8ffa00221c8342b (diff)
tdf#135500: always use transparent and clear content vdev in impBufferDevice
This removes the only place that hadn't used transparent impBufferDevice yet - in VclProcessor2D::RenderMaskPrimitive2DPixel. Not clearing the vdev made it draw on whatever garbage was left there from previous paints when the buffer was taken from maFreeBuffers in VDevBuffer::alloc, so since this was also the only place left that didn't clear the buffer explicitly, this makes the clear unconditional in impBufferDevice ctor. Also this makes sure to clear proper rectangle in VDevBuffer::alloc, and to clear mpAlphaVDev in OutputDevice::Erase. Change-Id: I7c1c0cc510a92628f19020b3faf0c0cd81f5a599 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100674 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--drawinglayer/source/processor2d/vclhelperbufferdevice.cxx65
-rw-r--r--drawinglayer/source/processor2d/vclhelperbufferdevice.hxx4
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx9
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx8
-rw-r--r--include/vcl/outdev.hxx2
-rw-r--r--vcl/source/outdev/wallpaper.cxx13
6 files changed, 37 insertions, 64 deletions
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 647825959108..d2101cc9952f 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -68,8 +68,8 @@ public:
VDevBuffer();
virtual ~VDevBuffer() override;
- VclPtr<VirtualDevice> alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear,
- bool bMonoChrome, bool bTransparent);
+ VclPtr<VirtualDevice> alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bMonoChrome,
+ bool bTransparent);
void free(VirtualDevice& rDevice);
// Timer virtuals
@@ -103,7 +103,7 @@ VDevBuffer::~VDevBuffer()
}
}
-VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear,
+VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel,
bool bMonoChrome, bool bTransparent)
{
::osl::MutexGuard aGuard(m_aMutex);
@@ -192,15 +192,12 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
{
if (bOkay)
{
- if (bClear)
- {
- pRetval->Erase(
- ::tools::Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight()));
- }
+ pRetval->Erase(pRetval->PixelToLogic(
+ tools::Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight())));
}
else
{
- pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ pRetval->SetOutputSizePixel(rSizePixel, true);
}
}
}
@@ -212,7 +209,7 @@ VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSize
rOutDev, bMonoChrome ? DeviceFormat::BITMASK : DeviceFormat::DEFAULT,
bTransparent ? DeviceFormat::DEFAULT : DeviceFormat::NONE);
maDeviceTemplates[pRetval] = &rOutDev;
- pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ pRetval->SetOutputSizePixel(rSizePixel, true);
}
else
{
@@ -273,13 +270,11 @@ VDevBuffer& getVDevBuffer()
return *aVDevBuffer.get();
}
-impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange,
- bool bContentTransparent)
+impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange)
: mrOutDev(rOutDev)
, mpContent(nullptr)
, mpMask(nullptr)
, mpAlpha(nullptr)
- , mbContentTransparent(bContentTransparent)
{
basegfx::B2DRange aRangePixel(rRange);
aRangePixel.transform(mrOutDev.GetViewTransformation());
@@ -294,29 +289,13 @@ impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange&
if (!isVisible())
return;
-#ifdef IOS
- // Exact mechanism unknown, but for some reason SmartArt
- // rendering, especially shadows, is broken on iOS unless
- // we pass 'true' here. Are virtual devices always de
- // facto cleared when created on other platforms?
- mpContent
- = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false, bContentTransparent);
-#else
- mpContent
- = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false, bContentTransparent);
-#endif
+ mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, true);
// #i93485# assert when copying from window to VDev is used
SAL_WARN_IF(
mrOutDev.GetOutDevType() == OUTDEV_WINDOW, "drawinglayer",
"impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)");
- const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled());
- mrOutDev.EnableMapMode(false);
- mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(),
- maDestPixel.GetSize(), mrOutDev);
- mrOutDev.EnableMapMode(bWasEnabledSrc);
-
MapMode aNewMapMode(mrOutDev.GetMapMode());
const Point aLogicTopLeft(mrOutDev.PixelToLogic(maDestPixel.TopLeft()));
@@ -403,8 +382,7 @@ void impBufferDevice::paint(double fTrans)
#endif
BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
- if (mbContentTransparent)
- aAlphaMask.BlendWith(aContent.GetAlpha());
+ aAlphaMask.BlendWith(aContent.GetAlpha());
mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlphaMask));
}
else if (mpMask)
@@ -426,26 +404,17 @@ void impBufferDevice::paint(double fTrans)
}
#endif
- if (mbContentTransparent)
- {
- BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
- AlphaMask aAlpha(aContent.GetAlpha());
- aAlpha.BlendWith(aMask);
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlpha));
- }
- else
- {
- Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask));
- }
+ BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
+ AlphaMask aAlpha(aContent.GetAlpha());
+ aAlpha.BlendWith(aMask);
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlpha));
}
else if (0.0 != fTrans)
{
sal_uInt8 nMaskValue(static_cast<sal_uInt8>(basegfx::fround(fTrans * 255.0)));
AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
BitmapEx aContent(mpContent->GetBitmapEx(aEmptyPoint, aSizePixel));
- if (mbContentTransparent)
- aAlphaMask.BlendWith(aContent.GetAlpha());
+ aAlphaMask.BlendWith(aContent.GetAlpha());
mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent.GetBitmap(), aAlphaMask));
}
else
@@ -470,7 +439,7 @@ VirtualDevice& impBufferDevice::getMask()
"impBufferDevice: No content, check isVisible() before accessing (!)");
if (!mpMask)
{
- mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, true, false);
+ mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
mpMask->SetMapMode(mpContent->GetMapMode());
// do NOT copy AA flag for mask!
@@ -485,7 +454,7 @@ VirtualDevice& impBufferDevice::getTransparence()
"impBufferDevice: No content, check isVisible() before accessing (!)");
if (!mpAlpha)
{
- mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false, false);
+ mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false);
mpAlpha->SetMapMode(mpContent->GetMapMode());
// copy AA flag for new target; masking needs to be smooth
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
index c85e3c4a6048..90d351eac50f 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
@@ -37,11 +37,9 @@ class impBufferDevice
VclPtr<VirtualDevice> mpMask;
VclPtr<VirtualDevice> mpAlpha;
tools::Rectangle maDestPixel;
- bool mbContentTransparent;
public:
- impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange,
- bool bContentTransparent = false);
+ impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange);
~impBufferDevice();
void paint(double fTrans = 0.0);
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index cec0ed29eaf6..716c23028ba6 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -991,7 +991,7 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv
// Consider glow transparency (initial transparency near the object edge)
const sal_uInt8 nTransparency = rCandidate.getGlowColor().GetTransparency();
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
if (aBufferDevice.isVisible())
{
// remember last OutDev and set to content
@@ -1000,7 +1000,6 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv
// We don't need antialiased mask here, which would only make effect thicker
const auto aPrevAA = mpOutputDevice->GetAntialiasing();
mpOutputDevice->SetAntialiasing(AntialiasingFlags::NONE);
- mpOutputDevice->Erase();
process(rCandidate);
// Limit the bitmap size to the visible area.
@@ -1054,13 +1053,12 @@ void VclPixelProcessor2D::processSoftEdgePrimitive2D(
// Blur radius is equal to soft edge radius
const double fBlurRadius = aRadiusVector.getLength();
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
if (aBufferDevice.isVisible())
{
// remember last OutDev and set to content
OutputDevice* pLastOutputDevice = mpOutputDevice;
mpOutputDevice = &aBufferDevice.getContent();
- mpOutputDevice->Erase();
// Since the effect converts all children to bitmap, we can't disable antialiasing here,
// because it would result in poor quality in areas not affected by the effect
process(rCandidate);
@@ -1112,12 +1110,11 @@ void VclPixelProcessor2D::processShadowPrimitive2D(const primitive2d::ShadowPrim
aBlurRadiusVector *= maCurrentTransformation;
const double fBlurRadius = aBlurRadiusVector.getLength();
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
if (aBufferDevice.isVisible())
{
OutputDevice* pLastOutputDevice = mpOutputDevice;
mpOutputDevice = &aBufferDevice.getContent();
- mpOutputDevice->Erase();
process(rCandidate);
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 5a0a85f911ef..ffb649da3554 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -841,14 +841,13 @@ void VclProcessor2D::RenderUnifiedTransparencePrimitive2D(
// transparence is in visible range
basegfx::B2DRange aRange(rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
aRange.transform(maCurrentTransformation);
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
if (aBufferDevice.isVisible())
{
// remember last OutDev and set to content
OutputDevice* pLastOutputDevice = mpOutputDevice;
mpOutputDevice = &aBufferDevice.getContent();
- mpOutputDevice->Erase();
// paint content to it
process(rTransCandidate.getChildren());
@@ -871,7 +870,7 @@ void VclProcessor2D::RenderTransparencePrimitive2D(
basegfx::B2DRange aRange(rTransCandidate.getChildren().getB2DRange(getViewInformation2D()));
aRange.transform(maCurrentTransformation);
- impBufferDevice aBufferDevice(*mpOutputDevice, aRange, true);
+ impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
if (!aBufferDevice.isVisible())
return;
@@ -879,7 +878,6 @@ void VclProcessor2D::RenderTransparencePrimitive2D(
// remember last OutDev and set to content
OutputDevice* pLastOutputDevice = mpOutputDevice;
mpOutputDevice = &aBufferDevice.getContent();
- mpOutputDevice->Erase();
// paint content to it
process(rTransCandidate.getChildren());
@@ -891,8 +889,6 @@ void VclProcessor2D::RenderTransparencePrimitive2D(
basegfx::BColorModifierStack aLastBColorModifierStack(maBColorModifierStack);
maBColorModifierStack = basegfx::BColorModifierStack();
- mpOutputDevice->Erase();
-
// paint mask to it (always with transparence intensities, evtl. with AA)
process(rTransCandidate.getTransparence());
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index f5eeed9c715d..ce4c204d3d94 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -964,7 +964,7 @@ public:
void DrawWallpaper( const tools::Rectangle& rRect, const Wallpaper& rWallpaper );
void Erase();
- void Erase( const tools::Rectangle& rRect ) { DrawWallpaper( rRect, GetBackground() ); }
+ void Erase(const tools::Rectangle& rRect);
protected:
void DrawGradientWallpaper( long nX, long nY, long nWidth, long nHeight, const Wallpaper& rWallpaper );
diff --git a/vcl/source/outdev/wallpaper.cxx b/vcl/source/outdev/wallpaper.cxx
index ae3687d79f35..594fdbe05c9b 100644
--- a/vcl/source/outdev/wallpaper.cxx
+++ b/vcl/source/outdev/wallpaper.cxx
@@ -119,6 +119,19 @@ void OutputDevice::Erase()
mpAlphaVDev->Erase();
}
+void OutputDevice::Erase(const tools::Rectangle& rRect)
+{
+ const RasterOp eRasterOp = GetRasterOp();
+ if ( eRasterOp != RasterOp::OverPaint )
+ SetRasterOp( RasterOp::OverPaint );
+ DrawWallpaper(rRect, GetBackground());
+ if ( eRasterOp != RasterOp::OverPaint )
+ SetRasterOp( eRasterOp );
+
+ if (mpAlphaVDev)
+ mpAlphaVDev->Erase(rRect);
+}
+
void OutputDevice::DrawBitmapWallpaper( long nX, long nY,
long nWidth, long nHeight,
const Wallpaper& rWallpaper )