drawinglayer/Library_drawinglayer.mk                               |    2 
 drawinglayer/source/attribute/sdrglowattribute.cxx                 |   80 +
 drawinglayer/source/primitive2d/Tools.cxx                          |    2 
 drawinglayer/source/primitive2d/glowprimitive2d.cxx                |   87 +
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx            |   46 
 include/drawinglayer/attribute/sdrglowattribute.hxx                |   54 
 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx |    1 
 include/drawinglayer/primitive2d/glowprimitive2d.hxx               |   71 +
 include/oox/export/drawingml.hxx                                   |    2 
 include/svx/sdglowmetricitem.hxx                                   |   37 
 include/svx/strings.hrc                                            |    3 
 include/svx/svddef.hxx                                             |    9 
 include/svx/unoshprp.hxx                                           |    5 
 include/vcl/BitmapFilterStackBlur.hxx                              |   34 
 include/xmloff/xmltoken.hxx                                        |    3 
 oox/source/drawingml/effectproperties.cxx                          |    7 
 oox/source/drawingml/effectproperties.hxx                          |   10 
 oox/source/drawingml/effectpropertiescontext.cxx                   |   13 
 oox/source/drawingml/shape.cxx                                     |   10 
 oox/source/export/drawingml.cxx                                    |   67 -
 oox/source/token/properties.txt                                    |    2 
 sd/qa/unit/data/pptx/shape-glow-effect.pptx                        |binary
 sd/qa/unit/export-tests-ooxml2.cxx                                 |   18 
 sd/qa/unit/import-tests.cxx                                        |   19 
 svx/inc/sdr/attribute/sdrlinefillshadowtextattribute.hxx           |    3 
 svx/inc/sdr/attribute/sdrlineshadowtextattribute.hxx               |    4 
 svx/inc/sdr/attribute/sdrshadowtextattribute.hxx                   |    8 
 svx/inc/sdr/primitive2d/sdrattributecreator.hxx                    |    4 
 svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx                  |    6 
 svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx        |    5 
 svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx            |    5 
 svx/source/sdr/attribute/sdrshadowtextattribute.cxx                |   15 
 svx/source/sdr/primitive2d/sdrattributecreator.cxx                 |   28 
 svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx           |    8 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx               |   21 
 svx/source/sdr/properties/customshapeproperties.cxx                |    3 
 svx/source/svdraw/svdattr.cxx                                      |    8 
 svx/source/unodraw/unoprov.cxx                                     |   11 
 sw/qa/extras/ooxmlexport/ooxmlexport7.cxx                          |   53 
 vcl/CppunitTest_vcl_bitmap_test.mk                                 |    1 
 vcl/Library_vcl.mk                                                 |    1 
 vcl/qa/cppunit/BitmapFilterTest.cxx                                |  159 ++
 vcl/source/bitmap/BitmapFilterStackBlur.cxx                        |  554 
++++++++++
 vcl/source/outdev/bitmap.cxx                                       |    4 
 xmloff/inc/xmlsdtypes.hxx                                          |    1 
 xmloff/source/core/xmltoken.cxx                                    |    3 
 xmloff/source/draw/sdpropls.cxx                                    |   10 
 xmloff/source/token/tokens.txt                                     |    3 
 48 files changed, 1409 insertions(+), 91 deletions(-)

New commits:
commit f9fc420dceb1ece2c98767da16a21aaff771f140
Author:     Tamas Bunth <tamas.bu...@collabora.co.uk>
AuthorDate: Tue Jan 21 19:04:13 2020 +0100
Commit:     Tamás Bunth <btom...@gmail.com>
CommitDate: Tue Mar 3 15:52:47 2020 +0100

    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 <btom...@gmail.com>

diff --git a/drawinglayer/Library_drawinglayer.mk 
b/drawinglayer/Library_drawinglayer.mk
index aba0ce9b6e08..0f93f8407b98 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -58,6 +58,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
     drawinglayer/source/attribute/sdrallattribute3d \
     drawinglayer/source/attribute/sdrfillattribute \
     drawinglayer/source/attribute/sdrfillgraphicattribute \
+    drawinglayer/source/attribute/sdrglowattribute \
     drawinglayer/source/attribute/sdrlightattribute3d \
     drawinglayer/source/attribute/sdrlightingattribute3d \
     drawinglayer/source/attribute/sdrlineattribute \
@@ -82,6 +83,7 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
     drawinglayer/source/primitive2d/fillgraphicprimitive2d \
     drawinglayer/source/primitive2d/fillgradientprimitive2d \
     drawinglayer/source/primitive2d/fillhatchprimitive2d \
+    drawinglayer/source/primitive2d/glowprimitive2d \
     drawinglayer/source/primitive2d/graphicprimitivehelper2d \
     drawinglayer/source/primitive2d/graphicprimitive2d \
     drawinglayer/source/primitive2d/gridprimitive2d \
diff --git a/drawinglayer/source/attribute/sdrglowattribute.cxx 
b/drawinglayer/source/attribute/sdrglowattribute.cxx
new file mode 100644
index 000000000000..bc42b170a8e9
--- /dev/null
+++ b/drawinglayer/source/attribute/sdrglowattribute.cxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <rtl/instance.hxx>
+
+#include <utility>
+
+#include <sal/log.hxx>
+
+namespace drawinglayer
+{
+namespace attribute
+{
+SdrGlowAttribute::SdrGlowAttribute(sal_Int32 nRadius, const basegfx::BColor& 
rColor)
+    : m_nRadius(nRadius)
+    , m_color(rColor)
+{
+}
+
+SdrGlowAttribute::SdrGlowAttribute()
+    : m_nRadius(0)
+{
+}
+
+SdrGlowAttribute::SdrGlowAttribute(const SdrGlowAttribute&) = default;
+
+SdrGlowAttribute::SdrGlowAttribute(SdrGlowAttribute&&) = default;
+
+SdrGlowAttribute::~SdrGlowAttribute() = default;
+
+SdrGlowAttribute& SdrGlowAttribute::operator=(const SdrGlowAttribute&) = 
default;
+
+SdrGlowAttribute& SdrGlowAttribute::operator=(SdrGlowAttribute&&) = default;
+
+bool SdrGlowAttribute::operator==(const SdrGlowAttribute& rCandidate) const
+{
+    if (rCandidate.isDefault() != isDefault())
+        return false;
+    return m_nRadius == rCandidate.m_nRadius && m_color == rCandidate.m_color;
+}
+
+const basegfx::B2DHomMatrix& 
SdrGlowAttribute::GetTransfMatrix(basegfx::B2DRange nRange) const
+{
+    if (!m_oTransfCache)
+    {
+        double dRadius100mm = static_cast<double>(m_nRadius) / 360.0;
+        // Apply a scaling with the center point of the shape as origin.
+        // 1) translate shape to the origin
+        basegfx::B2DHomMatrix matrix = 
basegfx::utils::createCoordinateSystemTransform(
+            nRange.getCenter(), basegfx::B2DVector(-1, 0), 
basegfx::B2DVector(0, -1));
+
+        basegfx::B2DHomMatrix inverse(matrix);
+        inverse.invert();
+
+        // 2) Scale up
+        double scale_x = (nRange.getWidth() + dRadius100mm) / 
nRange.getWidth();
+        double scale_y = (nRange.getHeight() + dRadius100mm) / 
nRange.getHeight();
+        matrix *= basegfx::utils::createScaleB2DHomMatrix(scale_x, scale_y);
+
+        // 3) Translate shape back to its place
+        matrix *= inverse;
+        m_oTransfCache = std::move(matrix);
+    }
+    return *m_oTransfCache;
+}
+
+} // end of namespace attribute
+} // end of namespace drawinglayer
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/primitive2d/Tools.cxx 
b/drawinglayer/source/primitive2d/Tools.cxx
index e9ff7a55394d..2a8b8239a569 100644
--- a/drawinglayer/source/primitive2d/Tools.cxx
+++ b/drawinglayer/source/primitive2d/Tools.cxx
@@ -228,6 +228,8 @@ OUString idToString(sal_uInt32 nId)
             return "POLYPOLYGONSELECTION";
         case PRIMITIVE2D_ID_PAGEHIERARCHYPRIMITIVE2D:
             return "PAGEHIERARCHY";
+        case PRIMITIVE2D_ID_GLOWPRIMITIVE2D:
+            return "GLOWPRIMITIVE";
         default:
             return OUString::number((nId >> 16) & 0xFF) + "|" + 
OUString::number(nId & 0xFF);
     }
diff --git a/drawinglayer/source/primitive2d/glowprimitive2d.cxx 
b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
new file mode 100644
index 000000000000..1fc035bf5279
--- /dev/null
+++ b/drawinglayer/source/primitive2d/glowprimitive2d.cxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <drawinglayer/primitive2d/glowprimitive2d.hxx>
+#include <basegfx/color/bcolormodifier.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+#include <sal/log.hxx>
+#include <memory>
+
+using namespace com::sun::star;
+
+namespace drawinglayer::primitive2d
+{
+GlowPrimitive2D::GlowPrimitive2D(const basegfx::B2DHomMatrix& rGlowTransform,
+                                 const basegfx::BColor& rGlowColor,
+                                 const Primitive2DContainer& rChildren)
+    : GroupPrimitive2D(rChildren)
+    , maGlowTransform(rGlowTransform)
+    , maGlowColor(rGlowColor)
+{
+}
+
+bool GlowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+{
+    if (BasePrimitive2D::operator==(rPrimitive))
+    {
+        const GlowPrimitive2D& rCompare = static_cast<const 
GlowPrimitive2D&>(rPrimitive);
+
+        return (getGlowTransform() == rCompare.getGlowTransform()
+                && getGlowColor() == rCompare.getGlowColor());
+    }
+
+    return false;
+}
+
+basegfx::B2DRange
+GlowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& 
rViewInformation) const
+{
+    basegfx::B2DRange aRetval(getChildren().getB2DRange(rViewInformation));
+    aRetval.transform(getGlowTransform());
+    return aRetval;
+}
+
+void GlowPrimitive2D::get2DDecomposition(
+    Primitive2DDecompositionVisitor& rVisitor,
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+    if (!getChildren().empty())
+    {
+        // create a modifiedColorPrimitive containing the Glow color and the 
content
+        basegfx::BColorModifierSharedPtr aBColorModifier
+            = 
std::make_shared<basegfx::BColorModifier_replace>(getGlowColor());
+
+        const Primitive2DReference xRefA(
+            new ModifiedColorPrimitive2D(getChildren(), aBColorModifier));
+        const Primitive2DContainer aSequenceB{ xRefA };
+
+        // build transformed primitiveVector with Glow offset and add to target
+        rVisitor.append(new TransformPrimitive2D(getGlowTransform(), 
aSequenceB));
+    }
+}
+
+// provide unique ID
+ImplPrimitive2DIDBlock(GlowPrimitive2D, PRIMITIVE2D_ID_GLOWPRIMITIVE2D)
+
+} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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()));
diff --git a/include/drawinglayer/attribute/sdrglowattribute.hxx 
b/include/drawinglayer/attribute/sdrglowattribute.hxx
new file mode 100644
index 000000000000..f5120c1a2044
--- /dev/null
+++ b/include/drawinglayer/attribute/sdrglowattribute.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRGLOWATTRIBUTE_HXX
+#define INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRGLOWATTRIBUTE_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+#include <optional>
+
+namespace drawinglayer
+{
+namespace attribute
+{
+class DRAWINGLAYER_DLLPUBLIC SdrGlowAttribute
+{
+private:
+    sal_Int32 m_nRadius = 0;
+    mutable std::optional<basegfx::B2DHomMatrix> m_oTransfCache;
+    basegfx::BColor m_color;
+
+public:
+    SdrGlowAttribute(sal_Int32 nRadius, const basegfx::BColor& rColor);
+    SdrGlowAttribute();
+    SdrGlowAttribute(const SdrGlowAttribute&);
+    SdrGlowAttribute(SdrGlowAttribute&&);
+    ~SdrGlowAttribute();
+    bool operator==(const SdrGlowAttribute& rCandidate) const;
+
+    SdrGlowAttribute& operator=(const SdrGlowAttribute&);
+    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; };
+};
+} // end of namespace attribute
+} // end of namespace drawinglayer
+
+#endif //INCLUDED_DRAWINGLAYER_ATTRIBUTE_SDRGLOWATTRIBUTE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx 
b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
index 1cc379d3e521..0c9aa3c0b4ba 100644
--- a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
+++ b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
@@ -102,6 +102,7 @@
 #define PRIMITIVE2D_ID_OBJECTINFOPRIMITIVE2D                
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 68)
 #define PRIMITIVE2D_ID_POLYPOLYGONSELECTIONPRIMITIVE2D      
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 69)
 #define PRIMITIVE2D_ID_PAGEHIERARCHYPRIMITIVE2D             
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 70)
+#define PRIMITIVE2D_ID_GLOWPRIMITIVE2D                      
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 71)
 // When you add a new primitive, please update the 
drawinglayer::primitive2d::idToString() function
 // in drawinglayer/source/primitive2d/baseprimitive2d.cxx.
 
diff --git a/include/drawinglayer/primitive2d/glowprimitive2d.hxx 
b/include/drawinglayer/primitive2d/glowprimitive2d.hxx
new file mode 100644
index 000000000000..0c77a9a94a6c
--- /dev/null
+++ b/include/drawinglayer/primitive2d/glowprimitive2d.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GLOWPRIMITIVE2D_HXX
+#define INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GLOWPRIMITIVE2D_HXX
+
+#include <drawinglayer/drawinglayerdllapi.h>
+
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/color/bcolor.hxx>
+
+namespace drawinglayer
+{
+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
+    basegfx::BColor maGlowColor;
+
+public:
+    /// constructor
+    GlowPrimitive2D(const basegfx::B2DHomMatrix& rGlowTransform, const 
basegfx::BColor& rGlowColor,
+                    const Primitive2DContainer& rChildren);
+
+    /// data read access
+    const basegfx::B2DHomMatrix& getGlowTransform() const { return 
maGlowTransform; }
+    const basegfx::BColor& getGlowColor() const { return maGlowColor; }
+
+    /// compare operator
+    virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
+
+    /// get range
+    virtual basegfx::B2DRange
+    getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 
override;
+
+    ///  create decomposition
+    virtual void
+    get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor,
+                       const geometry::ViewInformation2D& rViewInformation) 
const override;
+
+    /// provide unique ID
+    virtual sal_uInt32 getPrimitive2DID() const override;
+};
+} // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+#endif //INCLUDED_DRAWINGLAYER_PRIMITIVE2D_GLOWPRIMITIVE2D_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index a3da6a3cb442..ce5c6e9668e2 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -167,6 +167,8 @@ protected:
 
     static bool EqualGradients( css::awt::Gradient aGradient1, 
css::awt::Gradient aGradient2 );
 
+    void WriteGlowEffect(const css::uno::Reference<css::beans::XPropertySet>& 
rXPropSet);
+
 public:
     DrawingML( ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* 
pFB, DocumentType eDocumentType = DOCUMENT_PPTX, DMLTextExport* pTextExport = 
nullptr )
         : meDocumentType( eDocumentType ), mpTextExport(pTextExport), mpFS( 
pFS ), mpFB( pFB ), mbIsBackgroundDark( false ) {}
diff --git a/include/svx/sdglowmetricitem.hxx b/include/svx/sdglowmetricitem.hxx
new file mode 100644
index 000000000000..4a78cdedc19c
--- /dev/null
+++ b/include/svx/sdglowmetricitem.hxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_SVX_SDGLOWMETRICITEM_HXX
+#define INCLUDED_SVX_SDGLOWMETRICITEM_HXX
+
+#include <svx/svddef.hxx>
+#include <svl/poolitem.hxx>
+#include <svx/svxdllapi.h>
+
+#include <com/sun/star/table/GlowFormat.hpp>
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
+
+class SVX_DLLPUBLIC SdrGlowItem : public SfxPoolItem
+{
+private:
+    css::uno::Reference<css::table::GlowFormat> m_xGlow;
+
+public:
+    SdrGlowItem();
+    virtual bool GetPresentation(SfxItemPresentation ePres, MapUnit 
eCoreMetric,
+                                 MapUnit ePresMetric, OUString& rText,
+                                 const IntlWrapper&) const override;
+    virtual bool operator==(const SfxPoolItem&) const override;
+    virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) 
const override;
+    virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) 
override;
+    virtual SdrGlowItem* Clone(SfxItemPool* pPool = nullptr) const override;
+
+    drawinglayer::attribute::SdrGlowAttribute GetGlowAttr() const;
+};
+
+#endif
diff --git a/include/svx/strings.hrc b/include/svx/strings.hrc
index 0c4d78465364..b208d88605a4 100644
--- a/include/svx/strings.hrc
+++ b/include/svx/strings.hrc
@@ -512,6 +512,9 @@
 #define SIP_SA_GRAFINVERT                                   
NC_("SIP_SA_GRAFINVERT", "Invert")
 #define SIP_SA_GRAFMODE                                     
NC_("SIP_SA_GRAFMODE", "Image mode")
 #define SIP_SA_GRAFCROP                                     
NC_("SIP_SA_GRAFCROP", "Crop")
+#define SIP_SA_GLOW                                         NC_("SIP_SA_GRAD", 
"Glow effect")
+#define SIP_SA_GLOW_RAD                                     
NC_("SIP_SA_GLOW_RAD", "Radius of glow effect")
+#define SIP_SA_GLOW_COLOR                                   
NC_("SIP_SA_GLOW_COLOR", "Color of glow effect")
 #define STR_ObjNameSingulMEDIA                              
NC_("STR_ObjNameSingulMEDIA", "Media object")
 #define STR_ObjNamePluralMEDIA                              
NC_("STR_ObjNamePluralMEDIA", "Media objects")
 // drawing layer table strings
diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx
index a8696559c4fd..10713f61188b 100644
--- a/include/svx/svddef.hxx
+++ b/include/svx/svddef.hxx
@@ -401,10 +401,15 @@ class SdrTextHorzAdjustItem;
 #define SDRATTR_TABLE_BORDER_TLBR               
TypedWhichId<SvxLineItem>(SDRATTR_TABLE_FIRST+2)
 #define SDRATTR_TABLE_BORDER_BLTR               
TypedWhichId<SvxLineItem>(SDRATTR_TABLE_FIRST+3)
 #define SDRATTR_TABLE_TEXT_ROTATION             
TypedWhichId<SvxTextRotateItem>(SDRATTR_TABLE_FIRST+4)
-
 #define SDRATTR_TABLE_LAST                      (SDRATTR_TABLE_TEXT_ROTATION)
 
-#define SDRATTR_END                             SDRATTR_TABLE_LAST      /* 
1357 */ /* 1333 V4+++*/ /* 1243 V4+++*/  /*1213*/ /*1085*/ /*1040*/ /*Pool V2: 
1123,V1: 1065 */
+#define SDRATTR_GLOW_FIRST                      (SDRATTR_TABLE_LAST+1)
+#define SDRATTR_GLOW                            
TypedWhichId<SdrOnOffItem>(SDRATTR_GLOW_FIRST+0)
+#define SDRATTR_GLOW_RAD                        
TypedWhichId<SdrMetricItem>(SDRATTR_GLOW_FIRST+1)
+#define SDRATTR_GLOW_COLOR                      
TypedWhichId<XColorItem>(SDRATTR_GLOW_FIRST+2)
+#define SDRATTR_GLOW_LAST                       (SDRATTR_GLOW_COLOR)
+
+#define SDRATTR_END                             SDRATTR_GLOW_LAST      /* 1357 
*/ /* 1333 V4+++*/ /* 1243 V4+++*/  /*1213*/ /*1085*/ /*1040*/ /*Pool V2: 
1123,V1: 1065 */
 
 #endif // INCLUDED_SVX_SVDDEF_HXX
 
diff --git a/include/svx/unoshprp.hxx b/include/svx/unoshprp.hxx
index 0861844be16d..fd70a04035fe 100644
--- a/include/svx/unoshprp.hxx
+++ b/include/svx/unoshprp.hxx
@@ -209,6 +209,11 @@
     { OUString("FontWorkHideForm"),         XATTR_FORMTXTHIDEFORM,      
cppu::UnoType<bool>::get(),                        0,  0}, \
     { OUString("FontWorkShadowTransparence"),XATTR_FORMTXTSHDWTRANSP,   
::cppu::UnoType<sal_Int16>::get(),            0,  0},
 
+#define GLOW_PROPERTIES \
+    { OUString("GlowEffect"),                     SDRATTR_GLOW,             
cppu::UnoType<bool>::get(),           0,      0}, \
+    { OUString{"GlowEffectRad"},                  SDRATTR_GLOW_RAD,         
::cppu::UnoType<sal_Int32>::get(),    0,      0, 
PropertyMoreFlags::METRIC_ITEM}, \
+    { OUString{"GlowEffectColor"},                SDRATTR_GLOW_COLOR,       
::cppu::UnoType<sal_Int32>::get(),    0,      0},
+
 #define SHADOW_PROPERTIES \
     { OUString(UNO_NAME_SHADOW),            SDRATTR_SHADOW,             
cppu::UnoType<bool>::get(),    0,      0}, \
     { OUString(UNO_NAME_SHADOWCOLOR),       SDRATTR_SHADOWCOLOR,        
::cppu::UnoType<sal_Int32>::get(),    0,      0}, \
diff --git a/include/vcl/BitmapFilterStackBlur.hxx 
b/include/vcl/BitmapFilterStackBlur.hxx
new file mode 100644
index 000000000000..425420ded3c2
--- /dev/null
+++ b/include/vcl/BitmapFilterStackBlur.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef INCLUDED_VCL_BITMAPFILTERSTACKBLUR_HXX
+#define INCLUDED_VCL_BITMAPFILTERSTACKBLUR_HXX
+
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/BitmapFilter.hxx>
+
+class VCL_DLLPUBLIC BitmapFilterStackBlur : public BitmapFilter
+{
+    sal_Int32 mnRadius;
+    bool mbExtend;
+
+public:
+    BitmapFilterStackBlur(sal_Int32 nRadius, bool bExtend = true);
+    virtual ~BitmapFilterStackBlur();
+
+    virtual BitmapEx execute(BitmapEx const& rBitmap) const override;
+
+    Bitmap filter(Bitmap const& rBitmap) const;
+};
+
+#endif // INCLUDED_VCL_BITMAPFILTERSTACKBLUR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 7289d72e5e61..ba4a588d85eb 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -925,6 +925,9 @@ namespace xmloff { namespace token {
         XML_GCD,
         XML_GENERATOR,
         XML_GEQ,
+        XML_GLOW,
+        XML_GLOW_RADIUS,
+        XML_GLOW_COLOR,
         XML_GOURAUD,
         XML_GRADIENT,
         XML_GRADIENT_ANGLE,
diff --git a/oox/source/drawingml/effectproperties.cxx 
b/oox/source/drawingml/effectproperties.cxx
index 2ca45bae05a8..e4e9eaddcb32 100644
--- a/oox/source/drawingml/effectproperties.cxx
+++ b/oox/source/drawingml/effectproperties.cxx
@@ -18,6 +18,12 @@
 
 namespace oox::drawingml {
 
+void EffectGlowProperties ::assignUsed(const EffectGlowProperties& 
rSourceProps)
+{
+    moGlowRad.assignIfUsed( rSourceProps.moGlowRad );
+    moGlowColor.assignIfUsed( rSourceProps.moGlowColor );
+}
+
 void EffectShadowProperties::assignUsed(const EffectShadowProperties& 
rSourceProps)
 {
     moShadowDist.assignIfUsed( rSourceProps.moShadowDist );
@@ -28,6 +34,7 @@ void EffectShadowProperties::assignUsed(const 
EffectShadowProperties& rSourcePro
 void EffectProperties::assignUsed( const EffectProperties& rSourceProps )
 {
     maShadow.assignUsed(rSourceProps.maShadow);
+    maGlow.assignUsed(rSourceProps.maGlow);
     if (!rSourceProps.m_Effects.empty())
     {
         m_Effects.clear();
diff --git a/oox/source/drawingml/effectproperties.hxx 
b/oox/source/drawingml/effectproperties.hxx
index 146214cc9191..c4f39ac8803b 100644
--- a/oox/source/drawingml/effectproperties.hxx
+++ b/oox/source/drawingml/effectproperties.hxx
@@ -20,6 +20,15 @@
 namespace oox {
 namespace drawingml {
 
+struct EffectGlowProperties
+{
+    OptValue< sal_Int64 > moGlowRad; // size of glow effect
+    Color moGlowColor;
+    // TODO saturation and luminance missing
+
+    void assignUsed( const EffectGlowProperties& rSourceProps );
+};
+
 struct EffectShadowProperties
 {
     OptValue< sal_Int64 > moShadowDist;
@@ -42,6 +51,7 @@ struct Effect
 struct EffectProperties
 {
     EffectShadowProperties maShadow;
+    EffectGlowProperties maGlow;
 
     /** Stores all effect properties, including those not supported by core 
yet */
     std::vector<std::unique_ptr<Effect>> m_Effects;
diff --git a/oox/source/drawingml/effectpropertiescontext.cxx 
b/oox/source/drawingml/effectpropertiescontext.cxx
index 7941920ed370..6424e99d8458 100644
--- a/oox/source/drawingml/effectpropertiescontext.cxx
+++ b/oox/source/drawingml/effectpropertiescontext.cxx
@@ -15,6 +15,8 @@
 #include <oox/token/namespaces.hxx>
 #include <oox/token/tokens.hxx>
 
+#include <sal/log.hxx>
+
 using namespace ::oox::core;
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::xml::sax;
@@ -97,13 +99,18 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( 
sal_Int32 nElement,
         }
         break;
         case A_TOKEN( glow ):
+        {
+            mrEffectProperties.maGlow.moGlowRad = rAttribs.getInteger( 
XML_rad, 0 );
+            // undo push_back to effects
+            mrEffectProperties.m_Effects.pop_back();
+            return new ColorContext(*this, 
mrEffectProperties.maGlow.moGlowColor);
+
+        }
         case A_TOKEN( softEdge ):
         case A_TOKEN( reflection ):
         case A_TOKEN( blur ):
         {
-            if( nElement == A_TOKEN( glow ) )
-                mrEffectProperties.m_Effects[nPos]->msName = "glow";
-            else if( nElement == A_TOKEN( softEdge ) )
+            if( nElement == A_TOKEN( softEdge ) )
                 mrEffectProperties.m_Effects[nPos]->msName = "softEdge";
             else if( nElement == A_TOKEN( reflection ) )
                 mrEffectProperties.m_Effects[nPos]->msName = "reflection";
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 0cf633369959..1c307ff38371 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1215,6 +1215,7 @@ Reference< XShape > const & Shape::createAndInsert(
                     aFormat.ShadowWidth = *oShadowDistance;
                     aShapeProps.setProperty(PROP_ShadowFormat, aFormat);
                 }
+
             }
             else if (mbTextBox)
             {
@@ -1464,6 +1465,15 @@ Reference< XShape > const & Shape::createAndInsert(
                 aPropertySet.setAnyProperty(PROP_CharColor, 
uno::makeAny(nCharColor));
             }
         }
+
+        // Set glow effect properties
+        if ( aEffectProperties.maGlow.moGlowRad.has() )
+        {
+            uno::Reference<beans::XPropertySet> propertySet (mxShape, 
uno::UNO_QUERY);
+            propertySet->setPropertyValue("GlowEffect", makeAny(true));
+            propertySet->setPropertyValue("GlowEffectRad", 
makeAny(static_cast<sal_Int32>(aEffectProperties.maGlow.moGlowRad.get())));
+            propertySet->setPropertyValue("GlowEffectColor", 
makeAny(aEffectProperties.maGlow.moGlowColor.getColor(rGraphicHelper)));
+        }
     }
 
     if( mxShape.is() )
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index b4c37d514ece..d80b6a3bea7e 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -3719,29 +3719,38 @@ void DrawingML::WriteShapeEffects( const Reference< 
XPropertySet >& rXPropSet )
         bool bHasShadow = false;
         if( GetProperty( rXPropSet, "Shadow" ) )
             mAny >>= bHasShadow;
-        if( bHasShadow )
+        bool bHasGlow = false;
+        if( GetProperty( rXPropSet, "GlowEffect") )
+            mAny >>= bHasGlow;
+        //rXPropSet->getPropertyValue("GlowEffect") >>= bHasGlow;
+
+        if( bHasShadow || bHasGlow )
         {
-            Sequence< PropertyValue > aShadowGrabBag( 3 );
-            Sequence< PropertyValue > aShadowAttribsGrabBag( 2 );
+            mpFS->startElementNS(XML_a, XML_effectLst);
+            if( bHasShadow )
+            {
+                Sequence< PropertyValue > aShadowGrabBag( 3 );
+                Sequence< PropertyValue > aShadowAttribsGrabBag( 2 );
 
-            double dX = +0.0, dY = +0.0;
-            rXPropSet->getPropertyValue( "ShadowXDistance" ) >>= dX;
-            rXPropSet->getPropertyValue( "ShadowYDistance" ) >>= dY;
+                double dX = +0.0, dY = +0.0;
+                rXPropSet->getPropertyValue( "ShadowXDistance" ) >>= dX;
+                rXPropSet->getPropertyValue( "ShadowYDistance" ) >>= dY;
 
-            aShadowAttribsGrabBag[0].Name = "dist";
-            aShadowAttribsGrabBag[0].Value <<= lcl_CalculateDist(dX, dY);
-            aShadowAttribsGrabBag[1].Name = "dir";
-            aShadowAttribsGrabBag[1].Value <<= lcl_CalculateDir(dX, dY);
+                aShadowAttribsGrabBag[0].Name = "dist";
+                aShadowAttribsGrabBag[0].Value <<= lcl_CalculateDist(dX, dY);
+                aShadowAttribsGrabBag[1].Name = "dir";
+                aShadowAttribsGrabBag[1].Value <<= lcl_CalculateDir(dX, dY);
 
-            aShadowGrabBag[0].Name = "Attribs";
-            aShadowGrabBag[0].Value <<= aShadowAttribsGrabBag;
-            aShadowGrabBag[1].Name = "RgbClr";
-            aShadowGrabBag[1].Value = rXPropSet->getPropertyValue( 
"ShadowColor" );
-            aShadowGrabBag[2].Name = "RgbClrTransparency";
-            aShadowGrabBag[2].Value = rXPropSet->getPropertyValue( 
"ShadowTransparence" );
+                aShadowGrabBag[0].Name = "Attribs";
+                aShadowGrabBag[0].Value <<= aShadowAttribsGrabBag;
+                aShadowGrabBag[1].Name = "RgbClr";
+                aShadowGrabBag[1].Value = rXPropSet->getPropertyValue( 
"ShadowColor" );
+                aShadowGrabBag[2].Name = "RgbClrTransparency";
+                aShadowGrabBag[2].Value = rXPropSet->getPropertyValue( 
"ShadowTransparence" );
 
-            mpFS->startElementNS(XML_a, XML_effectLst);
-            WriteShapeEffect( "outerShdw", aShadowGrabBag );
+                WriteShapeEffect( "outerShdw", aShadowGrabBag );
+            }
+            WriteGlowEffect(rXPropSet);
             mpFS->endElementNS(XML_a, XML_effectLst);
         }
     }
@@ -3796,10 +3805,32 @@ void DrawingML::WriteShapeEffects( const Reference< 
XPropertySet >& rXPropSet )
                 WriteShapeEffect( rEffect.Name, aEffectProps );
             }
         }
+        WriteGlowEffect(rXPropSet);
+
         mpFS->endElementNS(XML_a, XML_effectLst);
     }
 }
 
+void DrawingML::WriteGlowEffect(const Reference< XPropertySet >& rXPropSet)
+{
+    bool hasGlow = false;
+    rXPropSet->getPropertyValue("GlowEffect") >>= hasGlow;
+    if(!hasGlow)
+        return;
+
+    Sequence< PropertyValue > aGlowAttribs(1);
+    aGlowAttribs[0].Name = "rad";
+    aGlowAttribs[0].Value = rXPropSet->getPropertyValue("GlowEffectRad");
+    Sequence< PropertyValue > aGlowProps(2);
+    aGlowProps[0].Name = "Attribs";
+    aGlowProps[0].Value <<= aGlowAttribs;
+    aGlowProps[1].Name = "RgbClr";
+    aGlowProps[1].Value = rXPropSet->getPropertyValue("GlowEffectColor");
+    // TODO other stuff like saturation or luminance
+
+    WriteShapeEffect("glow", aGlowProps);
+}
+
 void DrawingML::WriteShape3DEffects( const Reference< XPropertySet >& xPropSet 
)
 {
     // check existence of the grab bag
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index 4fc0c5b47c57..4624573d579b 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -207,6 +207,8 @@ Function
 GapwidthSequence
 GenerateVbaEvents
 Geometry3D
+GlowEffect
+GlowEffectRad
 GradientName
 HatchName
 Graphic
diff --git a/sd/qa/unit/data/pptx/shape-glow-effect.pptx 
b/sd/qa/unit/data/pptx/shape-glow-effect.pptx
new file mode 100755
index 000000000000..6a33aa58ffaa
Binary files /dev/null and b/sd/qa/unit/data/pptx/shape-glow-effect.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx 
b/sd/qa/unit/export-tests-ooxml2.cxx
index 2a1802f138ab..2befeb024d9b 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -182,6 +182,7 @@ public:
     void testTdf127372();
     void testTdf127379();
     void testTdf98603();
+    void testShapeGlowEffect();
 
     CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
 
@@ -282,6 +283,7 @@ public:
     CPPUNIT_TEST(testTdf127372);
     CPPUNIT_TEST(testTdf127379);
     CPPUNIT_TEST(testTdf98603);
+    CPPUNIT_TEST(testShapeGlowEffect);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2633,6 +2635,22 @@ void SdOOXMLExportTest2::testTdf98603()
     CPPUNIT_ASSERT_EQUAL(OUString("IL"), aLocale.Country);
 }
 
+void SdOOXMLExportTest2::testShapeGlowEffect()
+{
+    ::sd::DrawDocShellRef xDocShRef = loadURL( 
m_directories.getURLFromSrc("sd/qa/unit/data/pptx/shape-glow-effect.pptx"), 
PPTX);
+    xDocShRef = saveAndReload( xDocShRef.get(), PPTX );
+    uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, 
xDocShRef));
+    bool bHasGlow = false;
+    xShape->getPropertyValue("GlowEffect") >>= bHasGlow;
+    CPPUNIT_ASSERT(bHasGlow);
+    sal_Int64 nRadius = -1;
+    xShape->getPropertyValue("GlowEffectRad") >>= nRadius;
+    CPPUNIT_ASSERT_EQUAL(sal_Int64(139700l), nRadius);
+    Color nColor;
+    xShape->getPropertyValue("GlowEffectColor") >>= nColor;
+    CPPUNIT_ASSERT_EQUAL(Color(0xFFC000), nColor);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 9dfdb35c4fb4..85b7f5fa0cdf 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -209,6 +209,7 @@ public:
     void testTdf116266();
     void testTdf126324();
     void testTdf128684();
+    void testShapeGlowEffectPPTXImpoer();
 
     bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, 
std::vector<sal_uInt8>& rExpected);
     void testPatternImport();
@@ -332,6 +333,7 @@ public:
     CPPUNIT_TEST(testTdf106638);
     CPPUNIT_TEST(testTdf128684);
     CPPUNIT_TEST(testTdf113198);
+    CPPUNIT_TEST(testShapeGlowEffectPPTXImpoer);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -3145,6 +3147,23 @@ void SdImportTest::testTdf113198()
     CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, 
static_cast<style::ParagraphAdjust>(nParaAdjust));
 }
 
+void SdImportTest::testShapeGlowEffectPPTXImpoer()
+{
+    sd::DrawDocShellRef xDocShRef
+        = 
loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/shape-glow-effect.pptx"),
 PPTX);
+
+    uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, 
xDocShRef));
+    bool bHasGlow = false;
+    xShape->getPropertyValue("GlowEffect") >>= bHasGlow;
+    CPPUNIT_ASSERT(bHasGlow);
+    sal_Int64 nRadius = -1;
+    xShape->getPropertyValue("GlowEffectRad") >>= nRadius;
+    CPPUNIT_ASSERT_EQUAL(sal_Int64(139700l), nRadius);
+    Color nColor;
+    xShape->getPropertyValue("GlowEffectColor") >>= nColor;
+    CPPUNIT_ASSERT_EQUAL(Color(0xFFC000), nColor);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svx/inc/sdr/attribute/sdrlinefillshadowtextattribute.hxx 
b/svx/inc/sdr/attribute/sdrlinefillshadowtextattribute.hxx
index 519800e7dd02..f9d7969e519a 100644
--- a/svx/inc/sdr/attribute/sdrlinefillshadowtextattribute.hxx
+++ b/svx/inc/sdr/attribute/sdrlinefillshadowtextattribute.hxx
@@ -41,7 +41,8 @@ namespace drawinglayer
                 const SdrLineStartEndAttribute& rLineStartEnd,
                 const SdrShadowAttribute& rShadow,
                 const FillGradientAttribute& rFillFloatTransGradient,
-                const SdrTextAttribute& rTextAttribute);
+                const SdrTextAttribute& rTextAttribute,
+                const SdrGlowAttribute& rGlow);
             SdrLineFillShadowTextAttribute();
             SdrLineFillShadowTextAttribute(const 
SdrLineFillShadowTextAttribute& rCandidate);
             SdrLineFillShadowTextAttribute& operator=(const 
SdrLineFillShadowTextAttribute& rCandidate);
diff --git a/svx/inc/sdr/attribute/sdrlineshadowtextattribute.hxx 
b/svx/inc/sdr/attribute/sdrlineshadowtextattribute.hxx
index af7df7982422..840b20e44cc9 100644
--- a/svx/inc/sdr/attribute/sdrlineshadowtextattribute.hxx
+++ b/svx/inc/sdr/attribute/sdrlineshadowtextattribute.hxx
@@ -20,6 +20,7 @@
 #pragma once
 
 #include <sdr/attribute/sdrshadowtextattribute.hxx>
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
 #include <drawinglayer/attribute/sdrlineattribute.hxx>
 #include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
 
@@ -39,7 +40,8 @@ namespace drawinglayer
                 const SdrLineAttribute& rLine,
                 const SdrLineStartEndAttribute& rLineStartEnd,
                 const SdrShadowAttribute& rShadow,
-                const SdrTextAttribute& rTextAttribute);
+                const SdrTextAttribute& rTextAttribute,
+                const SdrGlowAttribute& rGlow);
             SdrLineShadowTextAttribute();
             SdrLineShadowTextAttribute(const SdrLineShadowTextAttribute& 
rCandidate);
             SdrLineShadowTextAttribute& operator=(const 
SdrLineShadowTextAttribute& rCandidate);
diff --git a/svx/inc/sdr/attribute/sdrshadowtextattribute.hxx 
b/svx/inc/sdr/attribute/sdrshadowtextattribute.hxx
index c58437b70928..bbcd7e95a501 100644
--- a/svx/inc/sdr/attribute/sdrshadowtextattribute.hxx
+++ b/svx/inc/sdr/attribute/sdrshadowtextattribute.hxx
@@ -21,6 +21,7 @@
 
 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
 #include <sdr/attribute/sdrtextattribute.hxx>
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
 
 
 namespace drawinglayer
@@ -33,10 +34,14 @@ namespace drawinglayer
             SdrShadowAttribute          maShadow;                   // shadow 
attributes (if used)
             SdrTextAttribute            maTextAttribute;            // text 
and text attributes (if used)
 
+            // glow effect
+            SdrGlowAttribute            maGlow;
+
         public:
             SdrShadowTextAttribute(
                 const SdrShadowAttribute& rShadow,
-                const SdrTextAttribute& rTextAttribute);
+                const SdrTextAttribute& rTextAttribute,
+                const SdrGlowAttribute& rGlow);
             SdrShadowTextAttribute();
             SdrShadowTextAttribute(const SdrShadowTextAttribute& rCandidate);
             SdrShadowTextAttribute& operator=(const SdrShadowTextAttribute& 
rCandidate);
@@ -50,6 +55,7 @@ namespace drawinglayer
             // data access
             const SdrShadowAttribute& getShadow() const { return maShadow; }
             const SdrTextAttribute& getText() const { return maTextAttribute; }
+            const SdrGlowAttribute& getGlow() const { return maGlow; }
         };
     } // end of namespace attribute
 } // end of namespace drawinglayer
diff --git a/svx/inc/sdr/primitive2d/sdrattributecreator.hxx 
b/svx/inc/sdr/primitive2d/sdrattributecreator.hxx
index 1d9e17d60d2a..da0242eed3a5 100644
--- a/svx/inc/sdr/primitive2d/sdrattributecreator.hxx
+++ b/svx/inc/sdr/primitive2d/sdrattributecreator.hxx
@@ -31,6 +31,7 @@ namespace drawinglayer { namespace attribute {
     class SdrLineAttribute;
     class SdrLineStartEndAttribute;
     class SdrShadowAttribute;
+    class SdrGlowAttribute;
     class SdrFillAttribute;
     class SdrTextAttribute;
     class FillGradientAttribute;
@@ -67,6 +68,9 @@ namespace drawinglayer
         attribute::SdrFillAttribute SVXCORE_DLLPUBLIC 
createNewSdrFillAttribute(
             const SfxItemSet& rSet);
 
+        attribute::SdrGlowAttribute createNewSdrGlowAttribute(
+            const SfxItemSet& rSet);
+
         // #i101508# Support handing over given text-to-border distances
         attribute::SdrTextAttribute createNewSdrTextAttribute(
             const SfxItemSet& rSet,
diff --git a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx 
b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx
index f55edda1b7c1..6a2cf1993305 100644
--- a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx
+++ b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx
@@ -20,6 +20,8 @@
 #pragma once
 
 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
+
 #include <svx/svxdllapi.h>
 
 // predefines
@@ -71,6 +73,10 @@ namespace drawinglayer
             const Primitive2DContainer& rContent,
             const attribute::SdrShadowAttribute& rShadow);
 
+        Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedGlowPrimitive(
+            const Primitive2DContainer& rContent,
+            const attribute::SdrGlowAttribute& rGlow);
+
     } // end of namespace primitive2d
 } // end of namespace drawinglayer
 
diff --git a/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx 
b/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx
index 6ab08fcba99f..9ecbf331961e 100644
--- a/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx
+++ b/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx
@@ -29,8 +29,9 @@ namespace drawinglayer::attribute
             const SdrLineStartEndAttribute& rLineStartEnd,
             const SdrShadowAttribute& rShadow,
             const FillGradientAttribute& rFillFloatTransGradient,
-            const SdrTextAttribute& rTextAttribute)
-        :   SdrLineShadowTextAttribute(rLine, rLineStartEnd, rShadow, 
rTextAttribute),
+            const SdrTextAttribute& rTextAttribute,
+            const SdrGlowAttribute& rGlow)
+        :   SdrLineShadowTextAttribute(rLine, rLineStartEnd, rShadow, 
rTextAttribute, rGlow),
             maFill(rFill),
             maFillFloatTransGradient(rFillFloatTransGradient)
         {
diff --git a/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx 
b/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx
index bc15ad8473e4..667a996d1379 100644
--- a/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx
+++ b/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx
@@ -27,8 +27,9 @@ namespace drawinglayer::attribute
             const SdrLineAttribute& rLine,
             const SdrLineStartEndAttribute& rLineStartEnd,
             const SdrShadowAttribute& rShadow,
-            const SdrTextAttribute& rTextAttribute)
-        :   SdrShadowTextAttribute(rShadow, rTextAttribute),
+            const SdrTextAttribute& rTextAttribute,
+            const SdrGlowAttribute& rGlow)
+        :   SdrShadowTextAttribute(rShadow, rTextAttribute, rGlow),
             maLine(rLine),
             maLineStartEnd(rLineStartEnd)
         {
diff --git a/svx/source/sdr/attribute/sdrshadowtextattribute.cxx 
b/svx/source/sdr/attribute/sdrshadowtextattribute.cxx
index 8d08b770a7a0..705981a62c16 100644
--- a/svx/source/sdr/attribute/sdrshadowtextattribute.cxx
+++ b/svx/source/sdr/attribute/sdrshadowtextattribute.cxx
@@ -25,9 +25,11 @@ namespace drawinglayer::attribute
 {
         SdrShadowTextAttribute::SdrShadowTextAttribute(
             const SdrShadowAttribute& rShadow,
-            const SdrTextAttribute& rTextAttribute)
+            const SdrTextAttribute& rTextAttribute,
+            const SdrGlowAttribute& rGlow)
         :   maShadow(rShadow),
-            maTextAttribute(rTextAttribute)
+            maTextAttribute(rTextAttribute),
+            maGlow(rGlow)
         {
         }
 
@@ -39,7 +41,8 @@ namespace drawinglayer::attribute
 
         SdrShadowTextAttribute::SdrShadowTextAttribute(const 
SdrShadowTextAttribute& rCandidate)
         :   maShadow(rCandidate.getShadow()),
-            maTextAttribute(rCandidate.getText())
+            maTextAttribute(rCandidate.getText()),
+            maGlow(rCandidate.maGlow)
         {
         }
 
@@ -47,6 +50,7 @@ namespace drawinglayer::attribute
         {
             maShadow = rCandidate.getShadow();
             maTextAttribute = rCandidate.getText();
+            maGlow = rCandidate.maGlow;
 
             return *this;
         }
@@ -54,13 +58,14 @@ namespace drawinglayer::attribute
         bool SdrShadowTextAttribute::isDefault() const
         {
             return (getShadow().isDefault()
-                && getText().isDefault());
+                && getText().isDefault() && maGlow.isDefault());
         }
 
         bool SdrShadowTextAttribute::operator==(const SdrShadowTextAttribute& 
rCandidate) const
         {
             return (getShadow() == rCandidate.getShadow()
-                && getText() == rCandidate.getText());
+                && getText() == rCandidate.getText()
+                && maGlow.isDefault());
         }
 
 } // end of namespace
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx 
b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 7afbada0c1be..18f5aae3e884 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -75,12 +75,15 @@
 #include <sdr/attribute/sdrlineshadowtextattribute.hxx>
 #include <sdr/attribute/sdrformtextattribute.hxx>
 #include <sdr/attribute/sdrlinefillshadowtextattribute.hxx>
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
 #include <drawinglayer/attribute/sdrsceneattribute3d.hxx>
 #include <drawinglayer/attribute/sdrlightingattribute3d.hxx>
 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
 #include <sdr/attribute/sdrfilltextattribute.hxx>
 #include <com/sun/star/drawing/LineCap.hpp>
 
+#include <sal/log.hxx>
+
 using namespace com::sun::star;
 
 namespace drawinglayer
@@ -332,6 +335,18 @@ namespace drawinglayer::primitive2d
             return attribute::SdrLineStartEndAttribute();
         }
 
+        attribute::SdrGlowAttribute createNewSdrGlowAttribute( const 
SfxItemSet& rSet)
+        {
+            const bool bGlow(rSet.Get(SDRATTR_GLOW).GetValue());
+            if(!bGlow)
+                return attribute::SdrGlowAttribute();
+            sal_Int32 nRadius = rSet.Get(SDRATTR_GLOW_RAD).GetValue();
+            const Color aColor(rSet.Get(SDRATTR_GLOW_COLOR).GetColorValue());
+
+            attribute::SdrGlowAttribute glowAttr{ nRadius, aColor.getBColor() 
};
+            return glowAttr;
+        }
+
         attribute::SdrShadowAttribute createNewSdrShadowAttribute(const 
SfxItemSet& rSet)
         {
             const bool bShadow(rSet.Get(SDRATTR_SHADOW).GetValue());
@@ -724,8 +739,9 @@ namespace drawinglayer::primitive2d
 
             // try shadow
             const attribute::SdrShadowAttribute 
aShadow(createNewSdrShadowAttribute(rSet));
+            const attribute::SdrGlowAttribute 
aGlow(createNewSdrGlowAttribute(rSet));
 
-            return attribute::SdrShadowTextAttribute(aShadow, aText);
+            return attribute::SdrShadowTextAttribute(aShadow, aText, aGlow);
         }
 
         attribute::SdrLineShadowTextAttribute 
createNewSdrLineShadowTextAttribute(
@@ -735,6 +751,7 @@ namespace drawinglayer::primitive2d
             attribute::SdrLineAttribute aLine;
             attribute::SdrLineStartEndAttribute aLineStartEnd;
             attribute::SdrTextAttribute aText;
+            attribute::SdrGlowAttribute aGlow;
             bool bFontworkHideContour(false);
 
             // look for text first
@@ -768,8 +785,9 @@ namespace drawinglayer::primitive2d
             {
                 // try shadow
                 const attribute::SdrShadowAttribute 
aShadow(createNewSdrShadowAttribute(rSet));
+                aGlow = createNewSdrGlowAttribute(rSet);
 
-                return attribute::SdrLineShadowTextAttribute(aLine, 
aLineStartEnd, aShadow, aText);
+                return attribute::SdrLineShadowTextAttribute(aLine, 
aLineStartEnd, aShadow, aText, aGlow);
             }
 
             return attribute::SdrLineShadowTextAttribute();
@@ -786,6 +804,7 @@ namespace drawinglayer::primitive2d
             attribute::SdrShadowAttribute aShadow;
             attribute::FillGradientAttribute aFillFloatTransGradient;
             attribute::SdrTextAttribute aText;
+            attribute::SdrGlowAttribute aGlow;
             bool bFontworkHideContour(false);
 
             // look for text first
@@ -831,8 +850,11 @@ namespace drawinglayer::primitive2d
                 // try shadow
                 aShadow = createNewSdrShadowAttribute(rSet);
 
+                // glow
+                aGlow = createNewSdrGlowAttribute(rSet);
+
                 return attribute::SdrLineFillShadowTextAttribute(
-                    aLine, aFill, aLineStartEnd, aShadow, 
aFillFloatTransGradient, aText);
+                    aLine, aFill, aLineStartEnd, aShadow, 
aFillFloatTransGradient, aText, aGlow);
             }
 
             return attribute::SdrLineFillShadowTextAttribute();
diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx 
b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx
index 7d32c753151f..804a653c86b2 100644
--- a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx
@@ -25,6 +25,8 @@
 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
 #include <drawinglayer/attribute/sdrlineattribute.hxx>
 
+#include <sal/log.hxx>
+
 
 using namespace com::sun::star;
 
@@ -69,6 +71,12 @@ namespace drawinglayer::primitive2d
                 }
             }
 
+            if(!aRetval.empty() && !getSdrSTAttribute().getGlow().isDefault())
+            {
+                    // glow
+                    aRetval = createEmbeddedGlowPrimitive(aRetval, 
getSdrSTAttribute().getGlow());
+            }
+
             rContainer.insert(rContainer.end(), aRetval.begin(), 
aRetval.end());
         }
 
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx 
b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 9aaf398030f5..e89b2a537b21 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -31,6 +31,7 @@
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
 #include <sdr/attribute/sdrtextattribute.hxx>
+#include <drawinglayer/primitive2d/glowprimitive2d.hxx>
 #include <sdr/primitive2d/sdrtextprimitive2d.hxx>
 #include <svx/svdotext.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
@@ -43,6 +44,7 @@
 #include <drawinglayer/attribute/sdrlineattribute.hxx>
 #include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
+#include <drawinglayer/attribute/sdrglowattribute.hxx>
 
 
 using namespace com::sun::star;
@@ -514,6 +516,25 @@ namespace drawinglayer::primitive2d
                 return rContent;
             }
         }
+
+        Primitive2DContainer createEmbeddedGlowPrimitive(
+            const Primitive2DContainer& rContent,
+            const attribute::SdrGlowAttribute& rGlow)
+        {
+            if(rContent.empty())
+                return rContent;
+            Primitive2DContainer aRetval(2);
+            const uno::Sequence< beans::PropertyValue > xViewParameters;
+            geometry::ViewInformation2D aViewInformation2D(xViewParameters);
+            aRetval[0] = Primitive2DReference(
+                new GlowPrimitive2D(
+                    
rGlow.GetTransfMatrix(rContent.getB2DRange(aViewInformation2D)),
+                    rGlow.getColor(),
+                    rContent));
+            aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent));
+            return aRetval;
+        }
+
 } // end of namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/properties/customshapeproperties.cxx 
b/svx/source/sdr/properties/customshapeproperties.cxx
index cb9425754e39..f9da077101ee 100644
--- a/svx/source/sdr/properties/customshapeproperties.cxx
+++ b/svx/source/sdr/properties/customshapeproperties.cxx
@@ -28,6 +28,8 @@
 #include <svl/whiter.hxx>
 #include <svl/hint.hxx>
 
+#include <sal/log.hxx>
+
 
 namespace sdr::properties
 {
@@ -71,6 +73,7 @@ namespace sdr::properties
                     // Graphic attributes, 3D properties, CustomShape
                     // properties:
                     SDRATTR_GRAF_FIRST, SDRATTR_CUSTOMSHAPE_LAST,
+                    SDRATTR_GLOW_FIRST, SDRATTR_GLOW_LAST,
                     // Range from SdrTextObj:
                     EE_ITEMS_START, EE_ITEMS_END>{});
         }
diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx
index e1d56b706b25..af8d7f7d45b9 100644
--- a/svx/source/svdraw/svdattr.cxx
+++ b/svx/source/svdraw/svdattr.cxx
@@ -326,6 +326,10 @@ SdrItemPool::SdrItemPool(
     rPoolDefaults[ SDRATTR_TABLE_BORDER_BLTR - SDRATTR_START ] = new 
SvxLineItem( SDRATTR_TABLE_BORDER_BLTR );
     rPoolDefaults[ SDRATTR_TABLE_TEXT_ROTATION - SDRATTR_START ] = new 
SvxTextRotateItem(0, SDRATTR_TABLE_TEXT_ROTATION);
 
+    rPoolDefaults[ SDRATTR_GLOW - SDRATTR_START ] = new 
SdrOnOffItem(SDRATTR_GLOW, false);
+    rPoolDefaults[ SDRATTR_GLOW_RAD - SDRATTR_START ] = new 
SdrMetricItem(SDRATTR_GLOW_RAD, 0);
+    rPoolDefaults[ SDRATTR_GLOW_COLOR - SDRATTR_START ] = new 
XColorItem(SDRATTR_GLOW_COLOR, aNullCol);
+
     // set own ItemInfos
     mpLocalItemInfos[SDRATTR_SHADOW-SDRATTR_START]._nSID=SID_ATTR_FILL_SHADOW;
     
mpLocalItemInfos[SDRATTR_SHADOWCOLOR-SDRATTR_START]._nSID=SID_ATTR_SHADOW_COLOR;
@@ -446,6 +450,10 @@ OUString SdrItemPool::GetItemName(sal_uInt16 nWhich)
         case SDRATTR_SHADOW3D          : pResId = SIP_SA_SHADOW3D;break;
         case SDRATTR_SHADOWPERSP       : pResId = SIP_SA_SHADOWPERSP;break;
 
+        case SDRATTR_GLOW              : pResId = SIP_SA_GLOW;break;
+        case SDRATTR_GLOW_RAD          : pResId = SIP_SA_GLOW_RAD;break;
+        case SDRATTR_GLOW_COLOR        : pResId = SIP_SA_GLOW_COLOR;break;
+
         case SDRATTR_CAPTIONTYPE      : pResId = SIP_SA_CAPTIONTYPE;break;
         case SDRATTR_CAPTIONFIXEDANGLE: pResId = 
SIP_SA_CAPTIONFIXEDANGLE;break;
         case SDRATTR_CAPTIONANGLE     : pResId = SIP_SA_CAPTIONANGLE;break;
diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx
index 639b8c798d39..67406c63ba40 100644
--- a/svx/source/unodraw/unoprov.cxx
+++ b/svx/source/unodraw/unoprov.cxx
@@ -68,6 +68,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxShapePropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -91,6 +92,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxTextShapePropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES_NO_SHEAR
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -115,6 +117,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxConnectorPropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -139,6 +142,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxDimensioningPropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -163,6 +167,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxCirclePropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -189,6 +194,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxPolyPolygonPropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -218,6 +224,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxGraphicObjectPropertyMap()
         MISC_OBJ_PROPERTIES
 
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         // #FontWork#
@@ -368,6 +375,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxAllPropertyMap()
 {
     static SfxItemPropertyMapEntry const aAllPropertyMap_Impl[] =
     {
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         LINE_PROPERTIES
         LINE_PROPERTIES_START_END
@@ -430,6 +438,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxOle2PropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         FONTWORK_PROPERTIES
@@ -681,6 +690,7 @@ static SfxItemPropertyMapEntry const * 
ImplGetSvxCustomShapePropertyMap()
         SHAPE_DESCRIPTOR_PROPERTIES
         MISC_OBJ_PROPERTIES
         LINKTARGET_PROPERTIES
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         TEXT_PROPERTIES
         {OUString("UserDefinedAttributes"),     SDRATTR_XMLATTRIBUTES,      
cppu::UnoType<css::container::XNameContainer>::get(),        0,     0},
@@ -759,6 +769,7 @@ static comphelper::PropertyMapEntry const * 
ImplGetSvxDrawingDefaultsPropertyMap
 {
     static comphelper::PropertyMapEntry const 
aSvxDrawingDefaultsPropertyMap_Impl[] =
     {
+        GLOW_PROPERTIES
         SHADOW_PROPERTIES
         LINE_PROPERTIES_DEFAULTS
         FILL_PROPERTIES_BMP
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
index 344b493dae4b..721f1292e8d5 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx
@@ -215,20 +215,6 @@ 
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testShapeEffectPreservation, "shape-effect-p
             
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:softEdge/*",
             0 ); // should not be present
 
-    // 5th shape with glow effect, scheme color
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow",
-            "rad", "101600");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow/a:schemeClr",
-            "val", "accent2");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow/a:schemeClr/a:satMod",
-            "val", "175000");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow/a:schemeClr/a:alpha",
-            "val", "40000");
-
     // 6th shape with reflection
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[7]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
             
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:reflection",
@@ -246,34 +232,6 @@ 
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testShapeEffectPreservation, "shape-effect-p
             
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:reflection/*",
             0 ); // should not be present
 
-    // 7th shape with several effects: glow, inner shadow and reflection
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow",
-            "rad", "63500");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow/a:schemeClr",
-            "val", "accent2");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:glow/a:schemeClr/*",
-            2);
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:innerShdw",
-            "blurRad", "63500");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:innerShdw",
-            "dir", "2700000");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:innerShdw/a:srgbClr",
-            "val", "000000");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:innerShdw/a:srgbClr/a:alpha",
-            "val", "50000");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:reflection",
-            "blurRad", "6350");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[8]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:reflection",
-            "stA", "52000");
 }
 
 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testShape3DEffectPreservation, 
"shape-3d-effect-preservation.docx")
@@ -389,17 +347,6 @@ 
DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testPictureEffectPreservation, "picture-effe
 {
     xmlDocPtr pXmlDoc = parseExport("word/document.xml");
 
-    // first picture: glow effect with theme color and transformations, 3d 
rotation and extrusion
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:effectLst/a:glow",
-            "rad", "228600");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:effectLst/a:glow/a:schemeClr",
-            "val", "accent1");
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
-            
"wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:effectLst/a:glow/a:schemeClr/*",
-            2);
-
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
             
"wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:scene3d/a:camera",
             "prst", "isometricRightUp");
diff --git a/vcl/CppunitTest_vcl_bitmap_test.mk 
b/vcl/CppunitTest_vcl_bitmap_test.mk
index 9ebef12dcfb2..dca63852a8af 100644
--- a/vcl/CppunitTest_vcl_bitmap_test.mk
+++ b/vcl/CppunitTest_vcl_bitmap_test.mk
@@ -15,6 +15,7 @@ $(eval $(call 
gb_CppunitTest_add_exception_objects,vcl_bitmap_test, \
     vcl/qa/cppunit/bitmapcolor \
     vcl/qa/cppunit/ScanlineToolsTest \
     vcl/qa/cppunit/BitmapScaleTest \
+    vcl/qa/cppunit/BitmapFilterTest \
 ))
 
 $(eval $(call gb_CppunitTest_use_externals,vcl_bitmap_test,\
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 79f2002c8c9d..70c23d0d1a71 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -367,6 +367,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/image/ImageRepository \
     vcl/source/image/ImplImage \
     vcl/source/image/ImplImageTree \
+    vcl/source/bitmap/BitmapFilterStackBlur \
     vcl/source/helper/canvasbitmap \
     vcl/source/helper/canvastools \
     vcl/source/helper/commandinfoprovider \
diff --git a/vcl/qa/cppunit/BitmapFilterTest.cxx 
b/vcl/qa/cppunit/BitmapFilterTest.cxx
new file mode 100644
index 000000000000..732c0c2dfb0b
--- /dev/null
+++ b/vcl/qa/cppunit/BitmapFilterTest.cxx
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapaccess.hxx>
+#include <bitmapwriteaccess.hxx>
+
+#include <tools/stream.hxx>
+#include <vcl/graphicfilter.hxx>
+
+#include <vcl/BitmapFilterStackBlur.hxx>
+#include <BitmapSymmetryCheck.hxx>
+
+#include <chrono>
+
+namespace
+{
+constexpr bool constWriteResultBitmap(false);
+constexpr bool constEnablePerformanceTest(false);
+
+class BitmapFilterTest : public CppUnit::TestFixture
+{
+    void testBlurCorrectness();
+    void testPerformance();
+
+    CPPUNIT_TEST_SUITE(BitmapFilterTest);
+    CPPUNIT_TEST(testBlurCorrectness);
+    CPPUNIT_TEST(testPerformance);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+void BitmapFilterTest::testBlurCorrectness()
+{
+    // Setup test bitmap
+    Size aSize(41, 31);
+    Bitmap aBitmap24Bit(aSize, 24);
+
+    ScanlineFormat scanlineFormat = ScanlineFormat::NONE;
+    sal_uInt16 nBPP = aBitmap24Bit.GetBitCount();
+
+    {
+        long aMargin1 = 1;
+        long aMargin2 = 3;
+        BitmapScopedWriteAccess aWriteAccess(aBitmap24Bit);
+        scanlineFormat = aWriteAccess->GetScanlineFormat();
+        aWriteAccess->Erase(COL_WHITE);
+        aWriteAccess->SetLineColor(COL_BLACK);
+
+        tools::Rectangle aRectangle1(aMargin1, aMargin1, aSize.Width() - 1 - 
aMargin1,
+                                     aSize.Height() - 1 - aMargin1);
+
+        tools::Rectangle aRectangle2(aMargin2, aMargin2, aSize.Width() - 1 - 
aMargin2,
+                                     aSize.Height() - 1 - aMargin2);
+
+        tools::Rectangle aRectangle3(aSize.Width() / 2, aSize.Height() / 2, 
aSize.Width() / 2,
+                                     aSize.Height() / 2);
+
+        aWriteAccess->DrawRect(aRectangle1);
+        aWriteAccess->DrawRect(aRectangle2);
+        aWriteAccess->DrawRect(aRectangle3);
+    }
+
+    if (constWriteResultBitmap)
+    {
+        SvFileStream aStream("~/blurBefore.png", StreamMode::WRITE | 
StreamMode::TRUNC);
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBitmap24Bit, aStream);
+    }
+
+    // Perform blur
+    BitmapFilterStackBlur aBlurFilter(2);
+    aBitmap24Bit = aBlurFilter.filter(aBitmap24Bit);
+
+    // Check the result
+
+    if (constWriteResultBitmap)
+    {
+        SvFileStream aStream("~/blurAfter.png", StreamMode::WRITE | 
StreamMode::TRUNC);
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBitmap24Bit, aStream);
+    }
+
+    // Check blurred bitmap parameters
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(45), 
aBitmap24Bit.GetSizePixel().Width());
+    CPPUNIT_ASSERT_EQUAL(static_cast<long>(35), 
aBitmap24Bit.GetSizePixel().Height());
+
+    CPPUNIT_ASSERT_EQUAL(nBPP, aBitmap24Bit.GetBitCount());
+
+    // Check that the bitmap is horizontally and vertically symmetrical
+    CPPUNIT_ASSERT(BitmapSymmetryCheck::check(aBitmap24Bit));
+
+    {
+        Bitmap::ScopedReadAccess aReadAccess(aBitmap24Bit);
+        CPPUNIT_ASSERT_EQUAL(scanlineFormat, aReadAccess->GetScanlineFormat());
+    }
+}
+
+void BitmapFilterTest::testPerformance()
+{
+    if (!constEnablePerformanceTest)
+        return;
+
+    Size aSize(4000, 3000); // A rather common picture size
+
+    // Prepare bitmap
+    Bitmap aBigBitmap(aSize, 24);
+    {
+        long aMargin = 500;
+        BitmapScopedWriteAccess aWriteAccess(aBigBitmap);
+        aWriteAccess->Erase(COL_WHITE);
+        aWriteAccess->SetLineColor(COL_BLACK);
+        aWriteAccess->SetFillColor(COL_BLACK);
+        tools::Rectangle aRectangle(aMargin, aMargin, aSize.Width() - 1 - 
aMargin,
+                                    aSize.Height() - 1 - aMargin);
+
+        aWriteAccess->DrawRect(aRectangle);
+    }
+
+    int nIterations = 10;
+    auto start = std::chrono::high_resolution_clock::now();
+    for (int i = 0; i < nIterations; i++)
+    {
+        BitmapFilterStackBlur aBlurFilter(250, false); // don't extend the 
image
+        aBlurFilter.filter(aBigBitmap);
+    }
+    auto end = std::chrono::high_resolution_clock::now();
+    auto elapsed = (end - start) / nIterations;
+
+    if (constWriteResultBitmap)
+    {
+        std::unique_ptr<SvFileStream> pStream(
+            new SvFileStream("~/BlurBigPerformance.png", StreamMode::WRITE | 
StreamMode::TRUNC));
+        GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+        rFilter.compressAsPNG(aBigBitmap, *pStream);
+
+        pStream.reset(new SvFileStream("~/BlurBigPerformance.txt", 
StreamMode::WRITE));
+        pStream->WriteOString("Blur average time: ");
+        pStream->WriteOString(OString::number(
+            
std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count()));
+        pStream->WriteOString("\n");
+    }
+}
+
+} // namespace
+
+CPPUNIT_TEST_SUITE_REGISTRATION(BitmapFilterTest);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/bitmap/BitmapFilterStackBlur.cxx 
b/vcl/source/bitmap/BitmapFilterStackBlur.cxx
new file mode 100644
index 000000000000..d88480787b8b
--- /dev/null
+++ b/vcl/source/bitmap/BitmapFilterStackBlur.cxx
@@ -0,0 +1,554 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <vcl/BitmapFilterStackBlur.hxx>
+#include <vcl/bitmapaccess.hxx>
+#include <bitmapwriteaccess.hxx>
+
+namespace
+{
+static const sal_Int16 constMultiplyTable[255]
+    = { 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 
292, 512, 454,
+        405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 
512, 482, 454,
+        428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 
437, 420, 404,
+        388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 497, 
482, 468, 454,
+        441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 320, 312, 
305, 298, 291,
+        284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 446, 437, 428, 
420, 412, 404,
+        396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 329, 323, 318, 312, 
307, 302, 297,
+        292, 287, 282, 278, 273, 269, 265, 261, 512, 505, 497, 489, 482, 475, 
468, 461, 454,
+        447, 441, 435, 428, 422, 417, 411, 405, 399, 394, 389, 383, 378, 373, 
368, 364, 359,
+        354, 350, 345, 341, 337, 332, 328, 324, 320, 316, 312, 309, 305, 301, 
298, 294, 291,
+        287, 284, 281, 278, 274, 271, 268, 265, 262, 259, 257, 507, 501, 496, 
491, 485, 480,
+        475, 470, 465, 460, 456, 451, 446, 442, 437, 433, 428, 424, 420, 416, 
412, 408, 404,
+        400, 396, 392, 388, 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 
350, 347, 344,
+        341, 338, 335, 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 
302, 299, 297,
+        294, 292, 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 
263, 261, 259 };
+
+static const sal_Int16 constShiftTable[255]
+    = { 9,  11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 
17, 17, 17, 17, 17,
+        18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 
19, 19, 19, 19, 19,
+        19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 
20, 20, 21, 21, 21,
+        21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 21, 21,
+        21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 
22, 22, 22, 22, 22,
+        22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 
23, 23, 23, 23, 23,
+        23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
23, 23, 23, 23, 23,
+        23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
23, 23, 23, 23, 23,
+        23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24,
+        24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24,
+        24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
24, 24, 24, 24, 24,
+        24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 };
+
+class BlurSharedData
+{
+public:
+    long mnRadius;
+    long mnComponentWidth;
+    long mnColorChannels;
+    long mnDiv;
+    std::vector<sal_uInt8> maStackBuffer;
+    std::vector<long> maPositionTable;
+    std::vector<long> maWeightTable;
+
+    std::vector<long> mnSumVector;
+    std::vector<long> mnInSumVector;
+    std::vector<long> mnOutSumVector;
+
+    BlurSharedData(long aRadius, long nComponentWidth, long nColorChannels)
+        : mnRadius(aRadius)
+        , mnComponentWidth(nComponentWidth)
+        , mnColorChannels(nColorChannels)
+        , mnDiv(aRadius + aRadius + 1)
+        , maStackBuffer(mnDiv * mnComponentWidth)
+        , maPositionTable(mnDiv)
+        , maWeightTable(mnDiv)
+        , mnSumVector(mnColorChannels)
+        , mnInSumVector(mnColorChannels)
+        , mnOutSumVector(mnColorChannels)
+    {
+    }
+
+    void calculateWeightAndPositions(long nLastIndex)
+    {
+        for (long i = 0; i < mnDiv; i++)
+        {
+            maPositionTable[i] = std::min(nLastIndex, std::max(0L, i - 
mnRadius));
+            maWeightTable[i] = mnRadius + 1 - std::abs(i - mnRadius);
+        }
+    }
+
+    long getMultiplyValue() { return 
static_cast<long>(constMultiplyTable[mnRadius]); }
+
+    long getShiftValue() { return 
static_cast<long>(constShiftTable[mnRadius]); }
+};
+
+struct SumFunction24
+{
+    static inline void add(long*& pValue1, long nConstant)
+    {
+        pValue1[0] += nConstant;
+        pValue1[1] += nConstant;
+        pValue1[2] += nConstant;
+    }
+
+    static inline void set(long*& pValue1, long nConstant)
+    {
+        pValue1[0] = nConstant;
+        pValue1[1] = nConstant;
+        pValue1[2] = nConstant;
+    }
+
+    static inline void add(long*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] += pValue2[0];
+        pValue1[1] += pValue2[1];
+        pValue1[2] += pValue2[2];
+    }
+
+    static inline void add(long*& pValue1, long*& pValue2)
+    {
+        pValue1[0] += pValue2[0];
+        pValue1[1] += pValue2[1];
+        pValue1[2] += pValue2[2];
+    }
+
+    static inline void sub(long*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] -= pValue2[0];
+        pValue1[1] -= pValue2[1];
+        pValue1[2] -= pValue2[2];
+    }
+
+    static inline void sub(long*& pValue1, long*& pValue2)
+    {
+        pValue1[0] -= pValue2[0];
+        pValue1[1] -= pValue2[1];
+        pValue1[2] -= pValue2[2];
+    }
+
+    static inline void assignPtr(sal_uInt8*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] = pValue2[0];
+        pValue1[1] = pValue2[1];
+        pValue1[2] = pValue2[2];
+    }
+
+    static inline void assignMulAndShr(sal_uInt8*& result, long*& sum, long 
multiply, long shift)
+    {
+        result[0] = (multiply * sum[0]) >> shift;
+        result[1] = (multiply * sum[1]) >> shift;
+        result[2] = (multiply * sum[2]) >> shift;
+    }
+};
+
+struct SumFunction8
+{
+    static inline void add(long*& pValue1, long nConstant) { pValue1[0] += 
nConstant; }
+
+    static inline void set(long*& pValue1, long nConstant) { pValue1[0] = 
nConstant; }
+
+    static inline void add(long*& pValue1, sal_uInt8*& pValue2) { pValue1[0] 
+= pValue2[0]; }
+
+    static inline void add(long*& pValue1, long*& pValue2) { pValue1[0] += 
pValue2[0]; }
+
+    static inline void sub(long*& pValue1, sal_uInt8*& pValue2) { pValue1[0] 
-= pValue2[0]; }
+
+    static inline void sub(long*& pValue1, long*& pValue2) { pValue1[0] -= 
pValue2[0]; }
+
+    static inline void assignPtr(sal_uInt8*& pValue1, sal_uInt8*& pValue2)
+    {
+        pValue1[0] = pValue2[0];
+    }
+
+    static inline void assignMulAndShr(sal_uInt8*& result, long*& sum, long 
multiply, long shift)
+    {
+        result[0] = (multiply * sum[0]) >> shift;
+    }
+};
+
+template <typename SumFunction>
+void stackBlurHorizontal(BitmapReadAccess* pReadAccess, BitmapWriteAccess* 
pWriteAccess,
+                         BlurSharedData& rShared)
+{
+    long nWidth = pReadAccess->Width();
+    long nHeight = pReadAccess->Height();
+
+    sal_uInt8* pStack = rShared.maStackBuffer.data();
+    sal_uInt8* pStackPtr;
+
+    long nLastIndexX = nWidth - 1;
+
+    long nMultiplyValue = rShared.getMultiplyValue();
+    long nShiftValue = rShared.getShiftValue();
+
+    long nRadius = rShared.mnRadius;
+    long nComponentWidth = rShared.mnComponentWidth;
+    long nDiv = rShared.mnDiv;
+
+    Scanline pSourcePointer;
+    Scanline pDestinationPointer;
+
+    long nXPosition;
+    long nStackIndex;
+    long nStackIndexStart;
+    long nWeight;
+
+    long* nSum = rShared.mnSumVector.data();
+    long* nInSum = rShared.mnInSumVector.data();
+    long* nOutSum = rShared.mnOutSumVector.data();
+
+    rShared.calculateWeightAndPositions(nLastIndexX);
+    long* pPositionPointer = rShared.maPositionTable.data();
+    long* pWeightPointer = rShared.maWeightTable.data();
+
+    for (long y = 0; y < nHeight; y++)
+    {
+        SumFunction::set(nSum, 0L);
+        SumFunction::set(nInSum, 0L);
+        SumFunction::set(nOutSum, 0L);
+
+        for (long i = 0; i < nDiv; i++)
+        {
+            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]);
+
+            pStackPtr = &pStack[nComponentWidth * i];
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            nWeight = pWeightPointer[i];
+
+            SumFunction::add(nSum, pSourcePointer[0] * nWeight);
+
+            if (i - nRadius > 0)
+            {
+                SumFunction::add(nInSum, pSourcePointer);
+            }
+            else
+            {
+                SumFunction::add(nOutSum, pSourcePointer);
+            }
+        }
+
+        nStackIndex = nRadius;
+        nXPosition = std::min(nRadius, nLastIndexX);
+
+        pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth * 
nXPosition;
+
+        for (long x = 0; x < nWidth; x++)
+        {
+            pDestinationPointer = pWriteAccess->GetScanline(y) + 
nComponentWidth * x;
+
+            SumFunction::assignMulAndShr(pDestinationPointer, nSum, 
nMultiplyValue, nShiftValue);
+
+            SumFunction::sub(nSum, nOutSum);
+
+            nStackIndexStart = nStackIndex + nDiv - nRadius;
+            if (nStackIndexStart >= nDiv)
+            {
+                nStackIndexStart -= nDiv;
+            }
+            pStackPtr = &pStack[nComponentWidth * nStackIndexStart];
+
+            SumFunction::sub(nOutSum, pStackPtr);
+
+            if (nXPosition < nLastIndexX)
+            {
+                nXPosition++;
+                pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth 
* nXPosition;
+            }
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            SumFunction::add(nInSum, pSourcePointer);
+
+            SumFunction::add(nSum, nInSum);
+
+            nStackIndex++;
+            if (nStackIndex >= nDiv)
+            {
+                nStackIndex = 0;
+            }
+
+            pStackPtr = &pStack[nStackIndex * nComponentWidth];
+
+            SumFunction::add(nOutSum, pStackPtr);
+            SumFunction::sub(nInSum, pStackPtr);
+        }
+    }
+}
+
+template <typename SumFunction>
+void stackBlurVertical(BitmapReadAccess* pReadAccess, BitmapWriteAccess* 
pWriteAccess,
+                       BlurSharedData& rShared)
+{
+    long nWidth = pReadAccess->Width();
+    long nHeight = pReadAccess->Height();
+
+    sal_uInt8* pStack = rShared.maStackBuffer.data();
+    sal_uInt8* pStackPtr;
+
+    long nLastIndexY = nHeight - 1;
+
+    long nMultiplyValue = rShared.getMultiplyValue();
+    long nShiftValue = rShared.getShiftValue();
+
+    long nRadius = rShared.mnRadius;
+    long nComponentWidth = rShared.mnComponentWidth;
+    long nDiv = rShared.mnDiv;
+
+    Scanline pSourcePointer;
+    Scanline pDestinationPointer;
+
+    long nYPosition;
+    long nStackIndex;
+    long nStackIndexStart;
+    long nWeight;
+
+    long* nSum = rShared.mnSumVector.data();
+    long* nInSum = rShared.mnInSumVector.data();
+    long* nOutSum = rShared.mnOutSumVector.data();
+
+    rShared.calculateWeightAndPositions(nLastIndexY);
+    long* pPositionPointer = rShared.maPositionTable.data();
+    long* pWeightPointer = rShared.maWeightTable.data();
+
+    for (long x = 0; x < nWidth; x++)
+    {
+        SumFunction::set(nSum, 0L);
+        SumFunction::set(nInSum, 0L);
+        SumFunction::set(nOutSum, 0L);
+
+        for (long i = 0; i < nDiv; i++)
+        {
+            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]);
+
+            pStackPtr = &pStack[nComponentWidth * i];
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            nWeight = pWeightPointer[i];
+
+            SumFunction::add(nSum, pSourcePointer[0] * nWeight);
+
+            if (i - nRadius > 0)
+            {
+                SumFunction::add(nInSum, pSourcePointer);
+            }
+            else
+            {
+                SumFunction::add(nOutSum, pSourcePointer);
+            }
+        }
+
+        nStackIndex = nRadius;
+        nYPosition = std::min(nRadius, nLastIndexY);
+
+        pSourcePointer = pReadAccess->GetScanline(nYPosition) + 
nComponentWidth * x;
+
+        for (long y = 0; y < nHeight; y++)
+        {
+            pDestinationPointer = pWriteAccess->GetScanline(y) + 
nComponentWidth * x;
+
+            SumFunction::assignMulAndShr(pDestinationPointer, nSum, 
nMultiplyValue, nShiftValue);
+
+            SumFunction::sub(nSum, nOutSum);
+
+            nStackIndexStart = nStackIndex + nDiv - nRadius;
+            if (nStackIndexStart >= nDiv)
+            {
+                nStackIndexStart -= nDiv;
+            }
+            pStackPtr = &pStack[nComponentWidth * nStackIndexStart];
+
+            SumFunction::sub(nOutSum, pStackPtr);
+
+            if (nYPosition < nLastIndexY)
+            {
+                nYPosition++;
+                pSourcePointer = pReadAccess->GetScanline(nYPosition) + 
nComponentWidth * x;
+            }
+
+            SumFunction::assignPtr(pStackPtr, pSourcePointer);
+
+            SumFunction::add(nInSum, pSourcePointer);
+
+            SumFunction::add(nSum, nInSum);
+
+            nStackIndex++;
+            if (nStackIndex >= nDiv)
+            {
+                nStackIndex = 0;
+            }
+
+            pStackPtr = &pStack[nStackIndex * nComponentWidth];
+
+            SumFunction::add(nOutSum, pStackPtr);
+
+            SumFunction::sub(nInSum, pStackPtr);
+        }
+    }
+}
+
+void stackBlur24(Bitmap& rBitmap, sal_Int32 nRadius, sal_Int32 nComponentWidth)
+{
+    // Limit radius
+    nRadius = std::clamp<sal_Int32>(nRadius, 2, 254);
+    const long nColorChannels = 3; // 3 color channel
+    BlurSharedData aData(nRadius, nComponentWidth, nColorChannels);
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        BitmapScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurHorizontal<SumFunction24>(pReadAccess.get(), 
pWriteAccess.get(), aData);
+    }
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        BitmapScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurVertical<SumFunction24>(pReadAccess.get(), 
pWriteAccess.get(), aData);
+    }
+}
+
+void stackBlur8(Bitmap& rBitmap, sal_Int32 nRadius, sal_Int32 nComponentWidth)
+{
+    // Limit radius
+    nRadius = std::clamp<sal_Int32>(nRadius, 2, 254);
+    const long nColorChannels = 1; // 1 color channel
+    BlurSharedData aData(nRadius, nComponentWidth, nColorChannels);
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        BitmapScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurHorizontal<SumFunction8>(pReadAccess.get(), 
pWriteAccess.get(), aData);
+    }
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        BitmapScopedWriteAccess pWriteAccess(rBitmap);
+
+        stackBlurVertical<SumFunction8>(pReadAccess.get(), pWriteAccess.get(), 
aData);
+    }
+}
+
+void centerExtendBitmap(Bitmap& rBitmap, sal_Int32 nExtendSize, Color aColor)
+{
+    const Size& rSize = rBitmap.GetSizePixel();
+    const Size aNewSize(rSize.Width() + nExtendSize * 2, rSize.Height() + 
nExtendSize * 2);
+
+    Bitmap aNewBitmap(aNewSize, rBitmap.GetBitCount());
+
+    {
+        Bitmap::ScopedReadAccess pReadAccess(rBitmap);
+        BitmapScopedWriteAccess pWriteAccess(aNewBitmap);
+
+        long nWidthBorder = nExtendSize + rSize.Width();
+        long nHeightBorder = nExtendSize + rSize.Height();
+
+        for (long y = 0; y < aNewSize.Height(); y++)
+        {
+            for (long x = 0; x < aNewSize.Width(); x++)
+            {
+                if (y < nExtendSize || y >= nHeightBorder || x < nExtendSize 
|| x >= nWidthBorder)
+                {
+                    pWriteAccess->SetPixel(y, x, aColor);
+                }
+                else
+                {
+                    pWriteAccess->SetPixel(y, x,
+                                           pReadAccess->GetPixel(y - 
nExtendSize, x - nExtendSize));
+                }
+            }
+        }
+    }
+    rBitmap = aNewBitmap;
+}
+
+} // end anonymous namespace
+
+/**
+ * Implementation of stack blur - a fast Gaussian blur approximation.
+ * nRadius - blur radious, valid values are between 2 and 254
+ * bExtend - extend the bitmap in all directions by the radius
+ *
+ * Stack Blur Algorithm by Mario Klingemann <ma...@quasimondo.com>
+ * (http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html)
+ *
+ * Additionally eferences and implementations:
+ * - Blur.js by Jacob Kelley
+ *   (http://www.blurjs.com)
+ * - BlurEffectForAndroidDesign by Nicolas Pomepuy
+ *   (https://github.com/PomepuyN/BlurEffectForAndroidDesign)
+ * - StackBluriOS by Thomas Landspurg
+ *   (https://github.com/tomsoft1/StackBluriOS)
+ * - stackblur.cpp by Benjamin Yates
+ *   (https://gist.github.com/benjamin9999/3809142)
+ * - stack blur in fog 2D graphic library by Petr Kobalicek
+ *   (https://code.google.com/p/fog/)
+ *
+ */
+BitmapFilterStackBlur::BitmapFilterStackBlur(sal_Int32 nRadius, bool bExtend)
+    : mnRadius(nRadius)
+    , mbExtend(bExtend)
+{
+}
+
+BitmapFilterStackBlur::~BitmapFilterStackBlur() {}
+
+BitmapEx BitmapFilterStackBlur::execute(BitmapEx const& rBitmapEx) const
+{
+    Bitmap aBitmap = rBitmapEx.GetBitmap();
+    Bitmap result = filter(aBitmap);
+    return BitmapEx(result, rBitmapEx.GetMask());
+}
+
+Bitmap BitmapFilterStackBlur::filter(Bitmap const& rBitmap) const
+{
+    Bitmap bitmapCopy(rBitmap);
+    ScanlineFormat nScanlineFormat;
+    {
+        Bitmap::ScopedReadAccess pReadAccess(bitmapCopy);
+        nScanlineFormat = pReadAccess->GetScanlineFormat();
+    }
+
+    if (nScanlineFormat == ScanlineFormat::N24BitTcRgb
+        || nScanlineFormat == ScanlineFormat::N24BitTcBgr
+        || nScanlineFormat == ScanlineFormat::N32BitTcMask
+        || nScanlineFormat == ScanlineFormat::N32BitTcBgra)
+    {
+        int nComponentWidth = (nScanlineFormat == ScanlineFormat::N32BitTcMask
+                               || nScanlineFormat == 
ScanlineFormat::N32BitTcBgra)
+                                  ? 4
+                                  : 3;
+
+        if (mbExtend)
+        {
+            centerExtendBitmap(bitmapCopy, mnRadius, COL_WHITE);
+        }
+
+        stackBlur24(bitmapCopy, mnRadius, nComponentWidth);
+    }
+    else if (nScanlineFormat == ScanlineFormat::N8BitPal)
+    {
+        int nComponentWidth = 1;
+
+        if (mbExtend)
+        {
+            centerExtendBitmap(bitmapCopy, mnRadius, COL_WHITE);
+        }
+
+        stackBlur8(bitmapCopy, mnRadius, nComponentWidth);
+    }
+
+    return bitmapCopy;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 0e1f3979e5ba..6e707e953ab1 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -21,6 +21,7 @@
 
 #include <vcl/bitmap.hxx>
 #include <vcl/bitmapex.hxx>
+#include <vcl/BitmapFilterStackBlur.hxx>
 #include <vcl/bitmapaccess.hxx>
 #include <vcl/canvastools.hxx>
 #include <vcl/gdimtf.hxx>
@@ -48,6 +49,9 @@
 #include <tools/helpers.hxx>
 #include <tools/debug.hxx>
 
+#include <vcl/dibtools.hxx>
+#include <tools/stream.hxx>
+
 void OutputDevice::DrawBitmap( const Point& rDestPt, const Bitmap& rBitmap )
 {
     assert(!is_double_buffered_window());
diff --git a/xmloff/inc/xmlsdtypes.hxx b/xmloff/inc/xmlsdtypes.hxx
index b49639d43a94..6b060d322f7c 100644
--- a/xmloff/inc/xmlsdtypes.hxx
+++ b/xmloff/inc/xmlsdtypes.hxx
@@ -68,6 +68,7 @@
 #define XML_SD_TYPE_IMAGE_SCALE_MODE                (XML_SD_TYPES_START + 34 )
 #define XML_SD_TYPE_LINECAP                         (XML_SD_TYPES_START + 35 )
 #define XML_SD_TYPE_FITTOSIZE_AUTOFIT               (XML_SD_TYPES_START + 36 )
+#define XML_SD_TYPE_GLOW                            (XML_SD_TYPES_START + 37 )
 
 //////////////////////////////////////////////////////////////////////////////
 // 3D property types
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 2005e929a684..46125e067982 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -929,6 +929,9 @@ namespace xmloff::token {
         TOKEN( "gcd",                             XML_GCD ),
         TOKEN( "generator",                       XML_GENERATOR ),
         TOKEN( "geq",                             XML_GEQ ),
+        TOKEN( "glow",                            XML_GLOW ),
+        TOKEN( "glow-radius",                     XML_GLOW_RADIUS ),
+        TOKEN( "glow-color",                      XML_GLOW_COLOR ),
         TOKEN( "gouraud",                         XML_GOURAUD ),
         TOKEN( "gradient",                        XML_GRADIENT ),
         TOKEN( "angle",                           XML_GRADIENT_ANGLE ),
diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx
index 19b325f8e1c5..4cedc7c148c0 100644
--- a/xmloff/source/draw/sdpropls.cxx
+++ b/xmloff/source/draw/sdpropls.cxx
@@ -152,6 +152,11 @@ const XMLPropertyMapEntry aXMLSDProperties[] =
     GMAP( "ShadowColor",                        XML_NAMESPACE_DRAW, 
XML_SHADOW_COLOR,           XML_TYPE_COLOR, 0 ),
     GMAP( "ShadowTransparence",             XML_NAMESPACE_DRAW, 
XML_SHADOW_OPACITY, XML_TYPE_NEG_PERCENT, 0 ),
 
+    // glow attributes
+    GMAPV( "GlowEffect",                       XML_NAMESPACE_LO_EXT, XML_GLOW, 
                XML_SD_TYPE_GLOW  , 0, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    GMAPV( "GlowEffectRad",                    XML_NAMESPACE_LO_EXT, 
XML_GLOW_RADIUS,          XML_TYPE_MEASURE  , 0, 
SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    GMAPV( "GlowEffectColor",                  XML_NAMESPACE_LO_EXT, 
XML_GLOW_COLOR,           XML_TYPE_COLOR    , 0, 
SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+
     // graphic attributes
     GMAP( "GraphicColorMode",               XML_NAMESPACE_DRAW, 
XML_COLOR_MODE,             XML_TYPE_COLOR_MODE, 0 ), // exists in SW, too, 
with same property name
     GMAP( "AdjustLuminance",                XML_NAMESPACE_DRAW, XML_LUMINANCE, 
             XML_TYPE_PERCENT16, 0 ), // signed? exists in SW, too, with same 
property name
@@ -1019,6 +1024,11 @@ const XMLPropertyHandler* 
XMLSdPropHdlFactory::GetPropertyHandler( sal_Int32 nTy
                 pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_VISIBLE), 
GetXMLToken(XML_HIDDEN) );
                 break;
             }
+            case XML_SD_TYPE_GLOW :
+            {
+                pHdl = new XMLNamedBoolPropertyHdl( GetXMLToken(XML_VISIBLE), 
GetXMLToken(XML_HIDDEN) );
+                break;
+            }
             case XML_TYPE_SD_MIRROR:
             {
                 pHdl = new XMLNamedBoolPropertyHdl( 
GetXMLToken(XML_HORIZONTAL), GetXMLToken(XML_NONE) );
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 34e145b30e46..31dae860a15e 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -847,6 +847,9 @@ gap-width
 gcd
 generator
 geq
+glow
+glow-radius
+glow-color
 gouraud
 gradient
 angle
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to