drawinglayer/source/tools/primitive2dxmldump.cxx |   15 +-
 svgio/Library_svgio.mk                           |    1 
 svgio/inc/svgfedropshadownode.hxx                |   48 +++++++
 svgio/inc/svgtoken.hxx                           |    1 
 svgio/qa/cppunit/SvgImportTest.cxx               |   17 ++
 svgio/qa/cppunit/data/filterFeDropShadow.svg     |   10 +
 svgio/source/svgreader/svgdocumenthandler.cxx    |    9 +
 svgio/source/svgreader/svgfedropshadownode.cxx   |  147 +++++++++++++++++++++++
 svgio/source/svgreader/svgfilternode.cxx         |    7 +
 svgio/source/svgreader/svgtoken.cxx              |    3 
 10 files changed, 253 insertions(+), 5 deletions(-)

New commits:
commit 14c40c460526f2e4ed2c24a3f50baae25a43a8f2
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Wed Jun 28 23:46:37 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Jun 29 10:40:06 2023 +0200

    tdf#156066: Add support for feDropShadow filter
    
    Change-Id: I0b2772a7211efb91821853e3369cfc3a5ef6a932
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153727
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx 
b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 37ea828a6fbb..8adaf82327d3 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -40,6 +40,7 @@
 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
 #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
 #include <drawinglayer/primitive2d/sceneprimitive2d.hxx>
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/attribute/lineattribute.hxx>
 #include <drawinglayer/attribute/fontattribute.hxx>
@@ -1116,11 +1117,17 @@ void Primitive2dXmlDump::decomposeAndWrite(
             case PRIMITIVE2D_ID_SHADOWPRIMITIVE2D:
             {
                 // ShadowPrimitive2D.
+                const ShadowPrimitive2D& rShadowPrimitive2D
+                    = dynamic_cast<const ShadowPrimitive2D&>(*pBasePrimitive);
                 rWriter.startElement("shadow");
-                drawinglayer::primitive2d::Primitive2DContainer 
aPrimitiveContainer;
-                pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
-                                                   
drawinglayer::geometry::ViewInformation2D());
-                decomposeAndWrite(aPrimitiveContainer, rWriter);
+                rWriter.attribute("color",
+                                  
convertColorToString(rShadowPrimitive2D.getShadowColor()));
+                rWriter.attributeDouble("blur", 
rShadowPrimitive2D.getShadowBlur());
+
+                rWriter.startElement("transform");
+                writeMatrix(rWriter, rShadowPrimitive2D.getShadowTransform());
+                rWriter.endElement();
+
                 rWriter.endElement();
                 break;
             }
diff --git a/svgio/Library_svgio.mk b/svgio/Library_svgio.mk
index 20797e339a81..56d1f8dc1ae3 100644
--- a/svgio/Library_svgio.mk
+++ b/svgio/Library_svgio.mk
@@ -61,6 +61,7 @@ $(eval $(call gb_Library_add_exception_objects,svgio,\
     svgio/source/svgreader/svggnode \
     svgio/source/svgreader/svganode \
     svgio/source/svgreader/svgfecolormatrixnode \
+    svgio/source/svgreader/svgfedropshadownode \
     svgio/source/svgreader/svgfefloodnode \
     svgio/source/svgreader/svgfegaussianblurnode \
     svgio/source/svgreader/svgfeoffsetnode \
diff --git a/svgio/inc/svgfedropshadownode.hxx 
b/svgio/inc/svgfedropshadownode.hxx
new file mode 100644
index 000000000000..5cc4b51ed797
--- /dev/null
+++ b/svgio/inc/svgfedropshadownode.hxx
@@ -0,0 +1,48 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include "svgnode.hxx"
+#include "svgstyleattributes.hxx"
+
+namespace svgio::svgreader
+{
+class SvgFeDropShadowNode final : public SvgNode
+{
+private:
+    SvgNumber maDx;
+    SvgNumber maDy;
+    SvgNumber maStdDeviation;
+    SvgPaint maFloodColor;
+    SvgNumber maFloodOpacity;
+
+public:
+    SvgFeDropShadowNode(SvgDocument& rDocument, SvgNode* pParent);
+    virtual ~SvgFeDropShadowNode() override;
+
+    virtual void parseAttribute(const OUString& rTokenName, SVGToken aSVGToken,
+                                const OUString& aContent) override;
+
+    void apply(drawinglayer::primitive2d::Primitive2DContainer& rTarget) const;
+};
+
+} // end of namespace svgio::svgreader
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/inc/svgtoken.hxx b/svgio/inc/svgtoken.hxx
index 239cda0eb4cc..7d75a0e097a5 100644
--- a/svgio/inc/svgtoken.hxx
+++ b/svgio/inc/svgtoken.hxx
@@ -81,6 +81,7 @@ namespace svgio::svgreader
             ClipPathNode,
             ClipPathProperty,
             FeColorMatrix,
+            FeDropShadow,
             FeFlood,
             FeGaussianBlur,
             FeOffset,
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx 
b/svgio/qa/cppunit/SvgImportTest.cxx
index 9383b7ac5430..5aa25aed5b1e 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -221,6 +221,23 @@ CPPUNIT_TEST_FIXTURE(Test, testFilterFeFlood)
     assertXPath(pDocument, 
"/primitive2D/transform/unifiedtransparence/polypolygoncolor/polypolygon", 
"miny", "50");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testFilterFeDropShadow)
+{
+    Primitive2DSequence aSequenceTdf132246 = 
parseSvg(u"/svgio/qa/cppunit/data/filterFeDropShadow.svg");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf132246.getLength()));
+
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf132246);
+
+    CPPUNIT_ASSERT (pDocument);
+
+    assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", 
"transparence", "50");
+    assertXPath(pDocument, 
"/primitive2D/transform/unifiedtransparence/shadow", "color", "#0000ff");
+    assertXPath(pDocument, 
"/primitive2D/transform/unifiedtransparence/shadow", "blur", "0.2");
+    assertXPath(pDocument, 
"/primitive2D/transform/unifiedtransparence/shadow", "blur", "0.2");
+    assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", 
"#ffc0cb");
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf87309)
 {
     Primitive2DSequence aSequenceTdf87309 = 
parseSvg(u"/svgio/qa/cppunit/data/tdf87309.svg");
diff --git a/svgio/qa/cppunit/data/filterFeDropShadow.svg 
b/svgio/qa/cppunit/data/filterFeDropShadow.svg
new file mode 100644
index 000000000000..a6405c93af15
--- /dev/null
+++ b/svgio/qa/cppunit/data/filterFeDropShadow.svg
@@ -0,0 +1,10 @@
+<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg";>
+  <defs>
+    <filter id="shadow">
+      <feDropShadow dx="0.6" dy="0.4" stdDeviation="0.2" flood-color="blue" 
flood-opacity="0.5" />
+    </filter>
+  </defs>
+
+  <circle cx="5" cy="50%" r="4" style="fill:pink; filter:url(#shadow);" />
+</svg>
+
diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx 
b/svgio/source/svgreader/svgdocumenthandler.cxx
index 7883383c5287..a070540e68eb 100644
--- a/svgio/source/svgreader/svgdocumenthandler.cxx
+++ b/svgio/source/svgreader/svgdocumenthandler.cxx
@@ -42,6 +42,7 @@
 #include <svgimagenode.hxx>
 #include <svgclippathnode.hxx>
 #include <svgfecolormatrixnode.hxx>
+#include <svgfedropshadownode.hxx>
 #include <svgfefloodnode.hxx>
 #include <svgfegaussianblurnode.hxx>
 #include <svgfeoffsetnode.hxx>
@@ -341,6 +342,13 @@ namespace
                     mpTarget->parseAttributes(xAttribs);
                     break;
                 }
+                case SVGToken::FeDropShadow:
+                {
+                    /// new node for feDropShadow
+                    mpTarget = new SvgFeDropShadowNode(maDocument, mpTarget);
+                    mpTarget->parseAttributes(xAttribs);
+                    break;
+                }
                 case SVGToken::FeFlood:
                 {
                     /// new node for feFlood
@@ -469,6 +477,7 @@ namespace
 
                 /// structural elements for filters
                 case SVGToken::FeColorMatrix:
+                case SVGToken::FeDropShadow:
                 case SVGToken::FeFlood:
                 case SVGToken::FeGaussianBlur:
                 case SVGToken::FeOffset:
diff --git a/svgio/source/svgreader/svgfedropshadownode.cxx 
b/svgio/source/svgreader/svgfedropshadownode.cxx
new file mode 100644
index 000000000000..56dd5dcf9587
--- /dev/null
+++ b/svgio/source/svgreader/svgfedropshadownode.cxx
@@ -0,0 +1,147 @@
+/* -*- 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/Primitive2DContainer.hxx>
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <svgfedropshadownode.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace svgio::svgreader
+{
+SvgFeDropShadowNode::SvgFeDropShadowNode(SvgDocument& rDocument, SvgNode* 
pParent)
+    : SvgNode(SVGToken::FeDropShadow, rDocument, pParent)
+    , maDx(0.0)
+    , maDy(0.0)
+    , maStdDeviation(0.0)
+    , maFloodColor(SvgPaint())
+    , maFloodOpacity(1.0)
+{
+}
+
+SvgFeDropShadowNode::~SvgFeDropShadowNode() {}
+
+void SvgFeDropShadowNode::parseAttribute(const OUString& /*rTokenName*/, 
SVGToken aSVGToken,
+                                         const OUString& aContent)
+{
+    // parse own
+    switch (aSVGToken)
+    {
+        case SVGToken::Style:
+        {
+            readLocalCssStyle(aContent);
+            break;
+        }
+        case SVGToken::Dx:
+        {
+            SvgNumber aNum;
+
+            if (readSingleNumber(aContent, aNum))
+            {
+                maDx = aNum;
+            }
+            break;
+        }
+        case SVGToken::Dy:
+        {
+            SvgNumber aNum;
+
+            if (readSingleNumber(aContent, aNum))
+            {
+                maDy = aNum;
+            }
+            break;
+        }
+        case SVGToken::StdDeviation:
+        {
+            SvgNumber aNum;
+
+            if (readSingleNumber(aContent, aNum))
+            {
+                maStdDeviation = aNum;
+            }
+            break;
+        }
+        case SVGToken::FloodColor:
+        {
+            SvgPaint aSvgPaint;
+            OUString aURL;
+            SvgNumber aOpacity;
+
+            if (readSvgPaint(aContent, aSvgPaint, aURL, aOpacity))
+            {
+                maFloodColor = aSvgPaint;
+            }
+            break;
+        }
+        case SVGToken::FloodOpacity:
+        {
+            SvgNumber aNum;
+
+            if (readSingleNumber(aContent, aNum))
+            {
+                maFloodOpacity = SvgNumber(std::clamp(aNum.getNumber(), 0.0, 
1.0), aNum.getUnit(),
+                                           aNum.isSet());
+            }
+            break;
+        }
+
+        default:
+        {
+            break;
+        }
+    }
+}
+
+void 
SvgFeDropShadowNode::apply(drawinglayer::primitive2d::Primitive2DContainer& 
rTarget) const
+{
+    basegfx::B2DHomMatrix aTransform;
+    if (maDx.isSet() || maDy.isSet())
+    {
+        aTransform.translate(maDx.solve(*this, NumberType::xcoordinate),
+                             maDy.solve(*this, NumberType::ycoordinate));
+    }
+
+    drawinglayer::primitive2d::Primitive2DContainer aTempTarget;
+
+    // Create the shadow
+    aTempTarget.append(drawinglayer::primitive2d::Primitive2DReference(
+        new drawinglayer::primitive2d::ShadowPrimitive2D(
+            aTransform, maFloodColor.getBColor(), maStdDeviation.getNumber(),
+            drawinglayer::primitive2d::Primitive2DContainer(rTarget))));
+
+    const double fOpacity(maFloodOpacity.solve(*this));
+    if (basegfx::fTools::less(fOpacity, 1.0))
+    {
+        // Apply transparence to the shadow
+        aTempTarget.append(drawinglayer::primitive2d::Primitive2DReference(
+            new 
drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(std::move(aTempTarget),
+                                                                          1.0 
- fOpacity)));
+    }
+
+    // Append the original target
+    aTempTarget.append(rTarget);
+
+    rTarget = aTempTarget;
+}
+
+} // end of namespace svgio::svgreader
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/source/svgreader/svgfilternode.cxx 
b/svgio/source/svgreader/svgfilternode.cxx
index 6ff71f002e73..3afdc6b0b524 100644
--- a/svgio/source/svgreader/svgfilternode.cxx
+++ b/svgio/source/svgreader/svgfilternode.cxx
@@ -19,6 +19,7 @@
 
 #include <svgfilternode.hxx>
 #include <svgfecolormatrixnode.hxx>
+#include <svgfedropshadownode.hxx>
 #include <svgfefloodnode.hxx>
 #include <svgfegaussianblurnode.hxx>
 #include <svgfeoffsetnode.hxx>
@@ -67,6 +68,12 @@ void 
SvgFilterNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTarg
             const SvgFeFloodNode& rFeFloodNode = dynamic_cast<const 
SvgFeFloodNode&>(*pCandidate);
             rFeFloodNode.apply(rTarget);
         }
+        else if (pCandidate->getType() == SVGToken::FeDropShadow)
+        {
+            const SvgFeDropShadowNode& rFeDropShadowNode
+                = dynamic_cast<const SvgFeDropShadowNode&>(*pCandidate);
+            rFeDropShadowNode.apply(rTarget);
+        }
     }
 }
 
diff --git a/svgio/source/svgreader/svgtoken.cxx 
b/svgio/source/svgreader/svgtoken.cxx
index 7a49896b0ed1..2383a6d79abd 100644
--- a/svgio/source/svgreader/svgtoken.cxx
+++ b/svgio/source/svgreader/svgtoken.cxx
@@ -28,7 +28,7 @@ namespace svgio::svgreader
 constexpr const std::u16string_view constToken_Title = u"title";
 constexpr const std::u16string_view constToken_Desc = u"desc";
 
-constexpr frozen::unordered_map<std::u16string_view, SVGToken, 143> 
aSVGTokenMapperList
+constexpr frozen::unordered_map<std::u16string_view, SVGToken, 144> 
aSVGTokenMapperList
 {
     { u"width", SVGToken::Width },
     { u"height", SVGToken::Height },
@@ -81,6 +81,7 @@ constexpr frozen::unordered_map<std::u16string_view, 
SVGToken, 143> aSVGTokenMap
     { u"clipPath", SVGToken::ClipPathNode },
     { u"clip-path", SVGToken::ClipPathProperty },
     { u"feColorMatrix", SVGToken::FeColorMatrix },
+    { u"feDropShadow", SVGToken::FeDropShadow },
     { u"feFlood", SVGToken::FeFlood },
     { u"feGaussianBlur", SVGToken::FeGaussianBlur },
     { u"feOffset", SVGToken::FeOffset },

Reply via email to