summaryrefslogtreecommitdiff
path: root/include/drawinglayer
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2020-05-01 01:05:24 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2020-05-07 21:57:37 +0200
commit08ebcff89f56bec3b0f9b346504748e4eb1687af (patch)
treed511115b648fd5f2340fd88eacc4ad9971ad7348 /include/drawinglayer
parenta98bdbae459ad7341bf7f484c402e77e4062cd16 (diff)
tdf#101181: improve glow effect
The shadow of objects must not be scaled: this displaces any internal areas that need blur, e.g. holes. Instead, it needs to dilate the shadow using kernel with radius equal to blur radius: this allows the borders of dilated objects to be in the middle of the blur area. The following blur makes those new margin points to have 50% intensity, and full glow intensity at the point of old object margins. This also removed artifacts when moving objects with glow effect caused by mismatch between scaling and D2D range calculation. The D2D range therefore is not calculated by scaling, but using grow. Blur filter's "extend bitmap by blur radius" option got obsoleted and removed. There's no need to blur the glow color (24-bit RGB). Instead, glow bitmap must be filled by glow color, and have an alpha mask that is blurred accordingly. This makes the glow properly transparent, and also reduces the blur complexity which now only needs to process 8 bits of alpha channel. The object shadow is created using basegfx::BColorModifier_replace inserted into the 2d decomposition of the effect, as before. To make sure that any non-fully-transparent pixel will become black pixel in the shadow, black color is used, and the result is further processed in VclPixelProcessor2D::processGlowPrimitive2D with monochrome filter using threshold 255. Glow transparency attribute is taken into account: the initial value at the margins of the objects. Color replacement filter is used to replace the object shadow with the attribute value before blur pass. Correct blur radius is used, calculated from glow effect radius, instead of hardcoded value of 5 pixels. This makes the glow to fade gradually along the full width of the effect, instead of only fading in narrow outer border previously. Since blur filter is only implemented for radius up to 254 pixels, and since downsampling the shadow before blur increases performance without noticeable quality loss, the image is downsampled before filtering. It should be noted that the glow effect is almost identical to soft shadow effect, likely with the only difference of using dilation in the former, but not in the latter. The code might be reused later to implement soft shadow as well. Change-Id: I728c532f9df7ccf85f353c23c6c7d8352d7b2086 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93235 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'include/drawinglayer')
-rw-r--r--include/drawinglayer/attribute/sdrglowattribute.hxx15
-rw-r--r--include/drawinglayer/primitive2d/glowprimitive2d.hxx16
2 files changed, 14 insertions, 17 deletions
diff --git a/include/drawinglayer/attribute/sdrglowattribute.hxx b/include/drawinglayer/attribute/sdrglowattribute.hxx
index f5120c1a2044..b17560bd76af 100644
--- a/include/drawinglayer/attribute/sdrglowattribute.hxx
+++ b/include/drawinglayer/attribute/sdrglowattribute.hxx
@@ -15,8 +15,7 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/color/bcolor.hxx>
#include <basegfx/range/b2drange.hxx>
-
-#include <optional>
+#include <tools/color.hxx>
namespace drawinglayer
{
@@ -26,11 +25,10 @@ class DRAWINGLAYER_DLLPUBLIC SdrGlowAttribute
{
private:
sal_Int32 m_nRadius = 0;
- mutable std::optional<basegfx::B2DHomMatrix> m_oTransfCache;
- basegfx::BColor m_color;
+ Color m_color; // Includes alpha!
public:
- SdrGlowAttribute(sal_Int32 nRadius, const basegfx::BColor& rColor);
+ SdrGlowAttribute(sal_Int32 nRadius, const Color& rColor);
SdrGlowAttribute();
SdrGlowAttribute(const SdrGlowAttribute&);
SdrGlowAttribute(SdrGlowAttribute&&);
@@ -41,10 +39,9 @@ public:
SdrGlowAttribute& operator=(SdrGlowAttribute&&);
// data access
- const basegfx::B2DHomMatrix& GetTransfMatrix(basegfx::B2DRange nCenter) const;
- const basegfx::BColor& getColor() const { return m_color; };
- sal_Int32 getRadius() const { return m_nRadius; };
- bool isDefault() const { return m_nRadius == 0; };
+ const Color& getColor() const { return m_color; }
+ sal_Int32 getRadius() const { return m_nRadius; }
+ bool isDefault() const { return m_nRadius == 0; }
};
} // end of namespace attribute
} // end of namespace drawinglayer
diff --git a/include/drawinglayer/primitive2d/glowprimitive2d.hxx b/include/drawinglayer/primitive2d/glowprimitive2d.hxx
index 0c77a9a94a6c..1aacdf0dde68 100644
--- a/include/drawinglayer/primitive2d/glowprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/glowprimitive2d.hxx
@@ -25,6 +25,7 @@
#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/color/bcolor.hxx>
+#include <tools/color.hxx>
namespace drawinglayer
{
@@ -33,20 +34,19 @@ namespace primitive2d
class DRAWINGLAYER_DLLPUBLIC GlowPrimitive2D final : public GroupPrimitive2D
{
private:
- /// the Glow transformation, normally just an offset
- basegfx::B2DHomMatrix maGlowTransform;
+ /// the Glow color to which all geometry is to be forced; includes alpha
+ Color maGlowColor;
- /// the Glow color to which all geometry is to be forced
- basegfx::BColor maGlowColor;
+ /// the Glow size, in logical units (100ths of mm)
+ double mfGlowRadius;
public:
/// constructor
- GlowPrimitive2D(const basegfx::B2DHomMatrix& rGlowTransform, const basegfx::BColor& rGlowColor,
- const Primitive2DContainer& rChildren);
+ GlowPrimitive2D(const Color& rGlowColor, double fRadius, const Primitive2DContainer& rChildren);
/// data read access
- const basegfx::B2DHomMatrix& getGlowTransform() const { return maGlowTransform; }
- const basegfx::BColor& getGlowColor() const { return maGlowColor; }
+ const Color& getGlowColor() const { return maGlowColor; }
+ double getGlowRadius() const { return mfGlowRadius; }
/// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;