diff options
Diffstat (limited to 'drawinglayer/source')
3 files changed, 44 insertions, 23 deletions
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx index 7f20d094b446..362293438dd8 100644 --- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx +++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx @@ -285,18 +285,17 @@ VDevBuffer& getVDevBuffer() return *aVDevBuffer.get(); } -impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange) +impBufferDevice::impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange, bool bCrop) : mrOutDev(rOutDev) , mpContent(nullptr) , mpAlpha(nullptr) { basegfx::B2DRange aRangePixel(rRange); aRangePixel.transform(mrOutDev.GetViewTransformation()); - const ::tools::Rectangle aRectPixel(floor(aRangePixel.getMinX()), floor(aRangePixel.getMinY()), - ceil(aRangePixel.getMaxX()), ceil(aRangePixel.getMaxY())); - const Point aEmptyPoint; - maDestPixel = ::tools::Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel()); - maDestPixel.Intersection(aRectPixel); + maDestPixel = tools::Rectangle(floor(aRangePixel.getMinX()), floor(aRangePixel.getMinY()), + ceil(aRangePixel.getMaxX()), ceil(aRangePixel.getMaxY())); + if (bCrop) + maDestPixel.Intersection({ {}, mrOutDev.GetOutputSizePixel() }); if (!isVisible()) return; diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx index 3b5d30415cc2..99585b05b141 100644 --- a/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx +++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx @@ -38,7 +38,7 @@ class impBufferDevice tools::Rectangle maDestPixel; public: - impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange); + impBufferDevice(OutputDevice& rOutDev, const basegfx::B2DRange& rRange, bool bCrop = true); ~impBufferDevice(); void paint(double fTrans = 0.0); diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 53e75ac37d55..9eb5a00410ac 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -1026,13 +1026,29 @@ AlphaMask ProcessAndBlurAlphaMask(const Bitmap& rMask, double fErodeDilateRadius return AlphaMask(mask.GetBitmap()); } + +drawinglayer::geometry::ViewInformation2D +expandRange(const drawinglayer::geometry::ViewInformation2D& rViewInfo, double nAmount) +{ + basegfx::B2DRange viewport(rViewInfo.getViewport()); + viewport.grow(nAmount); + return { rViewInfo.getObjectTransformation(), + rViewInfo.getViewTransformation(), + viewport, + rViewInfo.getVisualizedPage(), + rViewInfo.getViewTime(), + rViewInfo.getReducedDisplayQuality() }; +} } void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitive2D& rCandidate) { - basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D())); + const double nGlowRadius(rCandidate.getGlowRadius()); + // Avoid wrong effect on the cut-off side; so expand by radius + const auto aExpandedViewInfo(expandRange(getViewInformation2D(), nGlowRadius)); + basegfx::B2DRange aRange(rCandidate.getB2DRange(aExpandedViewInfo)); aRange.transform(maCurrentTransformation); - basegfx::B2DVector aGlowRadiusVector(rCandidate.getGlowRadius(), 0); + basegfx::B2DVector aGlowRadiusVector(nGlowRadius, 0); // Calculate the pixel size of glow radius in current transformation aGlowRadiusVector *= maCurrentTransformation; // Glow radius is the size of the halo from each side of the object. The halo is the @@ -1043,7 +1059,7 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv // Consider glow transparency (initial transparency near the object edge) const sal_uInt8 nAlpha = rCandidate.getGlowColor().GetAlpha(); - impBufferDevice aBufferDevice(*mpOutputDevice, aRange); + impBufferDevice aBufferDevice(*mpOutputDevice, aRange, false); if (aBufferDevice.isVisible()) { // remember last OutDev and set to content @@ -1055,9 +1071,9 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv process(rCandidate); // Limit the bitmap size to the visible area. - basegfx::B2DRange viewRange(getViewInformation2D().getDiscreteViewport()); basegfx::B2DRange bitmapRange(aRange); - bitmapRange.intersect(viewRange); + if (!aExpandedViewInfo.getDiscreteViewport().isEmpty()) + bitmapRange.intersect(aExpandedViewInfo.getDiscreteViewport()); if (!bitmapRange.isEmpty()) { const tools::Rectangle aRect( @@ -1094,19 +1110,19 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv void VclPixelProcessor2D::processSoftEdgePrimitive2D( const primitive2d::SoftEdgePrimitive2D& rCandidate) { - // TODO: don't limit the object at view range. This is needed to not blur objects at window - // borders, where they don't end. Ideally, process the full object once at maximal reasonable - // resolution, and store the resulting alpha mask in primitive's cache; then reuse it later, - // applying the transform. - basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D())); + const double nRadius(rCandidate.getRadius()); + // Avoid wrong effect on the cut-off side; so expand by diameter + const auto aExpandedViewInfo(expandRange(getViewInformation2D(), nRadius * 2)); + + basegfx::B2DRange aRange(rCandidate.getB2DRange(aExpandedViewInfo)); aRange.transform(maCurrentTransformation); - basegfx::B2DVector aRadiusVector(rCandidate.getRadius(), 0); + basegfx::B2DVector aRadiusVector(nRadius, 0); // Calculate the pixel size of soft edge radius in current transformation aRadiusVector *= maCurrentTransformation; // Blur radius is equal to soft edge radius const double fBlurRadius = aRadiusVector.getLength(); - impBufferDevice aBufferDevice(*mpOutputDevice, aRange); + impBufferDevice aBufferDevice(*mpOutputDevice, aRange, false); if (aBufferDevice.isVisible()) { // remember last OutDev and set to content @@ -1117,9 +1133,9 @@ void VclPixelProcessor2D::processSoftEdgePrimitive2D( process(rCandidate); // Limit the bitmap size to the visible area. - basegfx::B2DRange viewRange(getViewInformation2D().getDiscreteViewport()); basegfx::B2DRange bitmapRange(aRange); - bitmapRange.intersect(viewRange); + if (!aExpandedViewInfo.getDiscreteViewport().isEmpty()) + bitmapRange.intersect(aExpandedViewInfo.getDiscreteViewport()); if (!bitmapRange.isEmpty()) { const tools::Rectangle aRect( @@ -1268,7 +1284,9 @@ void VclPixelProcessor2D::processPatternFillPrimitive2D( { mpOutputDevice->Push(vcl::PushFlags::CLIPREGION); mpOutputDevice->IntersectClipRegion(vcl::Region(aMask)); - mpOutputDevice->DrawWallpaper(aMaskRect, Wallpaper(aTileImage)); + Wallpaper aWallpaper(aTileImage); + aWallpaper.SetColor(COL_TRANSPARENT); + mpOutputDevice->DrawWallpaper(aMaskRect, aWallpaper); mpOutputDevice->Pop(); return; } @@ -1291,7 +1309,11 @@ void VclPixelProcessor2D::processPatternFillPrimitive2D( mpOutputDevice->DrawRect(aMaskRect); } else - mpOutputDevice->DrawWallpaper(aMaskRect, Wallpaper(aTileImage)); + { + Wallpaper aWallpaper(aTileImage); + aWallpaper.SetColor(COL_TRANSPARENT); + mpOutputDevice->DrawWallpaper(aMaskRect, aWallpaper); + } // back to old OutDev mpOutputDevice = pLastOutputDevice; |