diff options
author | Xisco Fauli <xiscofauli@libreoffice.org> | 2023-06-28 23:46:37 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2023-06-29 10:40:06 +0200 |
commit | 14c40c460526f2e4ed2c24a3f50baae25a43a8f2 (patch) | |
tree | abe0964a546eddf5ade34bb71a6faa8fc6913f17 | |
parent | db591df99424dd7e1837946b36ca0658a02d520c (diff) |
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 <xiscofauli@libreoffice.org>
-rw-r--r-- | drawinglayer/source/tools/primitive2dxmldump.cxx | 15 | ||||
-rw-r--r-- | svgio/Library_svgio.mk | 1 | ||||
-rw-r--r-- | svgio/inc/svgfedropshadownode.hxx | 48 | ||||
-rw-r--r-- | svgio/inc/svgtoken.hxx | 1 | ||||
-rw-r--r-- | svgio/qa/cppunit/SvgImportTest.cxx | 17 | ||||
-rw-r--r-- | svgio/qa/cppunit/data/filterFeDropShadow.svg | 10 | ||||
-rw-r--r-- | svgio/source/svgreader/svgdocumenthandler.cxx | 9 | ||||
-rw-r--r-- | svgio/source/svgreader/svgfedropshadownode.cxx | 147 | ||||
-rw-r--r-- | svgio/source/svgreader/svgfilternode.cxx | 7 | ||||
-rw-r--r-- | svgio/source/svgreader/svgtoken.cxx | 3 |
10 files changed, 253 insertions, 5 deletions
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 }, |