diff options
author | Tamas Bunth <tamas.bunth@collabora.co.uk> | 2020-01-21 19:04:13 +0100 |
---|---|---|
committer | Tamás Bunth <btomi96@gmail.com> | 2020-03-03 15:52:47 +0100 |
commit | f9fc420dceb1ece2c98767da16a21aaff771f140 (patch) | |
tree | 299b9c856a3567ee85af11b7b314d2d02a03420b /drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | |
parent | 224ab38f747dcafe711c10b54ad53c52bda9e41d (diff) |
tdf#101181 Implement glow effect on shapes
Glow effect is a color-blurred outline outside of the shape. In ooxml
document it is specified with the <a:glow> element.
The commit contains the following:
- Add support for importing and exporting <a:glow> from ooxml documents.
- Assign new properties to XShape which stores glow-related attributes.
- A new 2D primitive is introduced in module 'drawinglayer' which is
responsible for representing the glow primitive which is to be rendered.
+ A glow primitive is a clone of the original shape which has been
scaled up slightly and a new color has been assigned to it. The
radius of the glow effect and the color is defined in the <a:glow>
element being imported.
- A blur algorithm is introduced in module 'vcl', which is called during
rendering the primitive.
+ The blur algorithm works on a bitmap.
+ Since the algorithm is CPU-intensive, the result is cached in the
processor and it is recalculated only if needed.
- Add support for importing and exporting glow effect to ODF format. For
that, new attributes of element <style:graphic-properties> has been
added:
+ loext:glow, which can have the values "visible" or "hidden"
+ loext:glow-radius: which holds the radius of the glow effect in cm.
+ loext:glow-color: holds the color of the glow effect
- Tests have been added to assert properties after pptx import and
export.
Change-Id: I836aeb5e0f24e2c8d5725834c8c0f98083bc82e7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89125
Tested-by: Jenkins
Reviewed-by: Tamás Bunth <btomi96@gmail.com>
Diffstat (limited to 'drawinglayer/source/processor2d/vclpixelprocessor2d.cxx')
-rw-r--r-- | drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 2fa5a7d47a44..4bd490dcfe78 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -18,6 +18,8 @@ */ #include "vclpixelprocessor2d.hxx" +#include "vclhelperbufferdevice.hxx" +#include <vcl/BitmapFilterStackBlur.hxx> #include <vcl/outdev.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/Tools.hxx> @@ -48,6 +50,9 @@ #include <drawinglayer/primitive2d/epsprimitive2d.hxx> #include <drawinglayer/primitive2d/svggradientprimitive2d.hxx> +#include <vcl/dibtools.hxx> +#include <tools/stream.hxx> + using namespace com::sun::star; namespace drawinglayer::processor2d @@ -361,6 +366,47 @@ namespace drawinglayer::processor2d processBorderLinePrimitive2D(static_cast<const drawinglayer::primitive2d::BorderLinePrimitive2D&>(rCandidate)); break; } + case PRIMITIVE2D_ID_GLOWPRIMITIVE2D: + { + basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D())); + aRange.transform(maCurrentTransformation); + aRange.grow(10.0); + impBufferDevice aBufferDevice(*mpOutputDevice, aRange); + if(aBufferDevice.isVisible()) + { + // remember last OutDev and set to content + OutputDevice* pLastOutputDevice = mpOutputDevice; + mpOutputDevice = &aBufferDevice.getTransparence(); + // paint content to virtual device + mpOutputDevice->Erase(); + process(rCandidate); + + // obtain result as a bitmap + auto bitmap = mpOutputDevice->GetBitmapEx(Point(aRange.getMinX(), aRange.getMinY()), Size(aRange.getWidth(), aRange.getHeight())); + constexpr sal_Int32 nRadius = 5; + bitmap.Scale(Size(aRange.getWidth()-nRadius, aRange.getHeight()-nRadius)); + // use bitmap later as mask + auto mask = bitmap.GetBitmap(); + + mpOutputDevice = &aBufferDevice.getContent(); + process(rCandidate); + bitmap = mpOutputDevice->GetBitmapEx(Point(aRange.getMinX(), aRange.getMinY()), Size(aRange.getWidth(), aRange.getHeight())); + bitmap.Scale(Size(aRange.getWidth()-nRadius, aRange.getHeight()-nRadius)); + + // calculate blurry effect + BitmapFilterStackBlur glowFilter(nRadius); + BitmapFilter::Filter(bitmap, glowFilter); + // back to old OutDev + mpOutputDevice = pLastOutputDevice; + mpOutputDevice->DrawBitmapEx(Point(aRange.getMinX()-nRadius/2, aRange.getMinY()-nRadius/2), BitmapEx(bitmap.GetBitmap(), mask)); + + // paint result + //aBufferDevice.paint(); + } + else + SAL_WARN("drawinglayer", "Temporary buffered virtual device is not visible"); + break; + } default : { SAL_INFO("drawinglayer", "default case for " << drawinglayer::primitive2d::idToString(rCandidate.getPrimitive2DID())); |