drawinglayer/source/processor2d/vclhelperbufferdevice.cxx | 65 +++----------- drawinglayer/source/processor2d/vclhelperbufferdevice.hxx | 4 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 6 - drawinglayer/source/processor2d/vclprocessor2d.cxx | 8 - include/vcl/outdev.hxx | 2 vcl/source/outdev/wallpaper.cxx | 13 ++ 6 files changed, 36 insertions(+), 62 deletions(-)
New commits: commit d5a8056981562bfd5d191a7ceb0131cb52d06749 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu Aug 13 18:12:37 2020 +0300 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Fri Aug 14 15:31:44 2020 +0200 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.kagan...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100712 Reviewed-by: Caolán McNamara <caol...@redhat.com> 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 c7ec6525fce1..2e7aa5c96bad 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -984,7 +984,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 @@ -993,7 +993,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); const tools::Rectangle aRect(static_cast<long>(std::floor(aRange.getMinX())), static_cast<long>(std::floor(aRange.getMinY())), @@ -1031,13 +1030,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); 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 6813eccd51ee..a8b8f755e8a4 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -956,7 +956,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 ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits