diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2020-08-13 18:12:37 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2020-08-14 01:00:04 +0200 |
commit | bf021c369f2306ee507da9bd3cc4cd10ac5d234c (patch) | |
tree | a3dc2552801cfe31cb524c6f375980eaa48e844b | |
parent | 56d5531373cf0588e02c254ea8ffa00221c8342b (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.cxx | 65 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/vclhelperbufferdevice.hxx | 4 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 9 | ||||
-rw-r--r-- | drawinglayer/source/processor2d/vclprocessor2d.cxx | 8 | ||||
-rw-r--r-- | include/vcl/outdev.hxx | 2 | ||||
-rw-r--r-- | vcl/source/outdev/wallpaper.cxx | 13 |
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 ) |