svgio/Library_svgio.mk                        |    2 
 svgio/inc/svgfemergenode.hxx                  |   44 +++++++++++++++
 svgio/inc/svgfemergenodenode.hxx              |   44 +++++++++++++++
 svgio/inc/svgtoken.hxx                        |    2 
 svgio/qa/cppunit/SvgImportTest.cxx            |   16 +++++
 svgio/qa/cppunit/data/filterFeMerge.svg       |   18 ++++++
 svgio/source/svgreader/svgdocumenthandler.cxx |   16 +++++
 svgio/source/svgreader/svgfemergenode.cxx     |   74 ++++++++++++++++++++++++++
 svgio/source/svgreader/svgfemergenodenode.cxx |   60 +++++++++++++++++++++
 svgio/source/svgreader/svgtoken.cxx           |    2 
 10 files changed, 278 insertions(+)

New commits:
commit 73e5b6667cad47d462ac1bce4f96c53b31315d18
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Tue Mar 12 18:15:38 2024 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Mar 12 23:03:33 2024 +0100

    tdf#159660: Add support for feMerge and feMergeNode
    
    Change-Id: I52e35f6eb5efc7b064145486aa4e6fb2366b143c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164722
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/svgio/Library_svgio.mk b/svgio/Library_svgio.mk
index edd83ed57251..f1e43ced6ac1 100644
--- a/svgio/Library_svgio.mk
+++ b/svgio/Library_svgio.mk
@@ -65,6 +65,8 @@ $(eval $(call gb_Library_add_exception_objects,svgio,\
     svgio/source/svgreader/svgfefloodnode \
     svgio/source/svgreader/svgfeimagenode \
     svgio/source/svgreader/svgfegaussianblurnode \
+    svgio/source/svgreader/svgfemergenode \
+    svgio/source/svgreader/svgfemergenodenode \
     svgio/source/svgreader/svgfeoffsetnode \
     svgio/source/svgreader/svgfilternode \
     svgio/source/svgreader/svggradientnode \
diff --git a/svgio/inc/svgfemergenode.hxx b/svgio/inc/svgfemergenode.hxx
new file mode 100644
index 000000000000..ec407f4e2274
--- /dev/null
+++ b/svgio/inc/svgfemergenode.hxx
@@ -0,0 +1,44 @@
+/* -*- 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 "svgfilternode.hxx"
+#include "svgstyleattributes.hxx"
+
+namespace svgio::svgreader
+{
+class SvgFeMergeNode : public SvgFilterNode
+{
+private:
+    OUString maResult;
+
+public:
+    SvgFeMergeNode(SVGToken aType, SvgDocument& rDocument, SvgNode* pParent);
+    virtual ~SvgFeMergeNode() override;
+
+    virtual void parseAttribute(SVGToken aSVGToken, const OUString& aContent) 
override;
+
+    void apply(drawinglayer::primitive2d::Primitive2DContainer& rTarget,
+               const SvgFilterNode* pParent) const override;
+};
+
+} // end of namespace svgio::svgreader
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/inc/svgfemergenodenode.hxx b/svgio/inc/svgfemergenodenode.hxx
new file mode 100644
index 000000000000..5ae77c586c56
--- /dev/null
+++ b/svgio/inc/svgfemergenodenode.hxx
@@ -0,0 +1,44 @@
+/* -*- 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 "svgfemergenode.hxx"
+#include "svgstyleattributes.hxx"
+
+namespace svgio::svgreader
+{
+class SvgFeMergeNodeNode final : public SvgFeMergeNode
+{
+private:
+    OUString maIn;
+
+public:
+    SvgFeMergeNodeNode(SvgDocument& rDocument, SvgNode* pParent);
+    virtual ~SvgFeMergeNodeNode() override;
+
+    virtual void parseAttribute(SVGToken aSVGToken, const OUString& aContent) 
override;
+
+    void apply(drawinglayer::primitive2d::Primitive2DContainer& rTarget,
+               const SvgFilterNode* pParent) const override;
+};
+
+} // 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 613b75049335..7dc616db149e 100644
--- a/svgio/inc/svgtoken.hxx
+++ b/svgio/inc/svgtoken.hxx
@@ -86,6 +86,8 @@ namespace svgio::svgreader
             FeFlood,
             FeImage,
             FeGaussianBlur,
+            FeMerge,
+            FeMergeNode,
             FeOffset,
             Filter,
             FloodColor,
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx 
b/svgio/qa/cppunit/SvgImportTest.cxx
index 708ab7dcc970..62e8993c7aa8 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -259,6 +259,22 @@ CPPUNIT_TEST_FIXTURE(Test, testResultFilterAttribute)
     assertXPath(pDocument, 
"/primitive2D/transform/transform/softedge/polypolygoncolor"_ostr, 
"color"_ostr, "#ffffff");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testFilterFeMerge)
+{
+    Primitive2DSequence aSequence = 
parseSvg(u"/svgio/qa/cppunit/data/filterFeMerge.svg");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);
+
+    CPPUNIT_ASSERT (pDocument);
+
+    assertXPath(pDocument, "/primitive2D/transform/mask/softedge"_ostr, 2);
+    assertXPath(pDocument, "/primitive2D/transform/mask/polypolygon"_ostr, 1);
+    assertXPath(pDocument, 
"/primitive2D/transform/mask/polypolygoncolor"_ostr, 1);
+    assertXPath(pDocument, 
"/primitive2D/transform/mask/polypolygonstroke"_ostr, 1);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testFilterFeOffset)
 {
     Primitive2DSequence aSequenceTdf132246 = 
parseSvg(u"/svgio/qa/cppunit/data/filterFeOffset.svg");
diff --git a/svgio/qa/cppunit/data/filterFeMerge.svg 
b/svgio/qa/cppunit/data/filterFeMerge.svg
new file mode 100644
index 000000000000..39143834962e
--- /dev/null
+++ b/svgio/qa/cppunit/data/filterFeMerge.svg
@@ -0,0 +1,18 @@
+<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg";>
+  <filter id="feOffset" x="-40" y="-20" width="100" height="200">
+    <feOffset in="SourceGraphic" dx="60" dy="60" />
+    <feGaussianBlur stdDeviation="5" result="blur2" />
+    <feMerge>
+      <feMergeNode in="blur2" />
+      <feMergeNode in="SourceGraphic" />
+    </feMerge>
+  </filter>
+
+  <rect
+    x="40"
+    y="40"
+    width="100"
+    height="100"
+    style="stroke: #000000; fill: green; filter: url(#feOffset);" />
+</svg>
+
diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx 
b/svgio/source/svgreader/svgdocumenthandler.cxx
index 5e89edad6ca7..e45dcad857a9 100644
--- a/svgio/source/svgreader/svgdocumenthandler.cxx
+++ b/svgio/source/svgreader/svgdocumenthandler.cxx
@@ -46,6 +46,8 @@
 #include <svgfefloodnode.hxx>
 #include <svgfeimagenode.hxx>
 #include <svgfegaussianblurnode.hxx>
+#include <svgfemergenode.hxx>
+#include <svgfemergenodenode.hxx>
 #include <svgfeoffsetnode.hxx>
 #include <svgfilternode.hxx>
 #include <svgmasknode.hxx>
@@ -410,6 +412,20 @@ namespace
                     mpTarget->parseAttributes(xAttribs);
                     break;
                 }
+                case SVGToken::FeMerge:
+                {
+                    /// new node for feMerge
+                    mpTarget = new SvgFeMergeNode(aSVGToken, maDocument, 
mpTarget);
+                    mpTarget->parseAttributes(xAttribs);
+                    break;
+                }
+                case SVGToken::FeMergeNode:
+                {
+                    /// new node for feMergeNode
+                    mpTarget = new SvgFeMergeNodeNode(maDocument, mpTarget);
+                    mpTarget->parseAttributes(xAttribs);
+                    break;
+                }
                 case SVGToken::FeOffset:
                 {
                     /// new node for feOffset
diff --git a/svgio/source/svgreader/svgfemergenode.cxx 
b/svgio/source/svgreader/svgfemergenode.cxx
new file mode 100644
index 000000000000..4f25df038ab9
--- /dev/null
+++ b/svgio/source/svgreader/svgfemergenode.cxx
@@ -0,0 +1,74 @@
+/*
+ * 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 <svgfemergenode.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace svgio::svgreader
+{
+SvgFeMergeNode::SvgFeMergeNode(SVGToken aType, SvgDocument& rDocument, 
SvgNode* pParent)
+    : SvgFilterNode(aType, rDocument, pParent)
+{
+}
+
+SvgFeMergeNode::~SvgFeMergeNode() {}
+
+void SvgFeMergeNode::parseAttribute(SVGToken aSVGToken, const OUString& 
aContent)
+{
+    // parse own
+    switch (aSVGToken)
+    {
+        case SVGToken::Style:
+        {
+            readLocalCssStyle(aContent);
+            break;
+        }
+        case SVGToken::Result:
+        {
+            maResult = aContent.trim();
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+}
+
+void SvgFeMergeNode::apply(drawinglayer::primitive2d::Primitive2DContainer& 
rTarget,
+                           const SvgFilterNode* pParent) const
+{
+    const auto& rChildren = getChildren();
+    const sal_uInt32 nCount(rChildren.size());
+
+    // apply children's filters
+    for (sal_uInt32 a(0); a < nCount; a++)
+    {
+        SvgFeMergeNode* pFeMergeNode = 
dynamic_cast<SvgFeMergeNode*>(rChildren[a].get());
+        if (pFeMergeNode)
+        {
+            pFeMergeNode->apply(rTarget, pParent);
+        }
+    }
+
+    pParent->addGraphicSourceToMapper(maResult, rTarget);
+}
+
+} // end of namespace svgio::svgreader
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/source/svgreader/svgfemergenodenode.cxx 
b/svgio/source/svgreader/svgfemergenodenode.cxx
new file mode 100644
index 000000000000..0d2b2da56e84
--- /dev/null
+++ b/svgio/source/svgreader/svgfemergenodenode.cxx
@@ -0,0 +1,60 @@
+/*
+ * 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 <svgfemergenodenode.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace svgio::svgreader
+{
+SvgFeMergeNodeNode::SvgFeMergeNodeNode(SvgDocument& rDocument, SvgNode* 
pParent)
+    : SvgFeMergeNode(SVGToken::FeMergeNode, rDocument, pParent)
+{
+}
+
+SvgFeMergeNodeNode::~SvgFeMergeNodeNode() {}
+
+void SvgFeMergeNodeNode::parseAttribute(SVGToken aSVGToken, const OUString& 
aContent)
+{
+    // parse own
+    switch (aSVGToken)
+    {
+        case SVGToken::In:
+        {
+            maIn = aContent.trim();
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+}
+
+void 
SvgFeMergeNodeNode::apply(drawinglayer::primitive2d::Primitive2DContainer& 
rTarget,
+                               const SvgFilterNode* pParent) const
+{
+    if (const drawinglayer::primitive2d::Primitive2DContainer* rSource
+        = pParent->findGraphicSource(maIn))
+    {
+        rTarget.append(*rSource);
+    }
+}
+
+} // end of namespace svgio::svgreader
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/source/svgreader/svgtoken.cxx 
b/svgio/source/svgreader/svgtoken.cxx
index 2edcd528793e..3a1f2eb3e251 100644
--- a/svgio/source/svgreader/svgtoken.cxx
+++ b/svgio/source/svgreader/svgtoken.cxx
@@ -84,6 +84,8 @@ constexpr auto aSVGTokenMap = 
frozen::make_unordered_map<std::u16string_view, SV
     { u"feFlood", SVGToken::FeFlood },
     { u"feImage", SVGToken::FeImage },
     { u"feGaussianBlur", SVGToken::FeGaussianBlur },
+    { u"feMerge", SVGToken::FeMerge },
+    { u"feMergeNode", SVGToken::FeMergeNode },
     { u"feOffset", SVGToken::FeOffset },
     { u"filter", SVGToken::Filter },
     { u"flood-color", SVGToken::FloodColor },

Reply via email to