diff options
author | Xisco Fauli <xiscofauli@libreoffice.org> | 2023-06-26 23:24:52 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2023-06-27 14:21:26 +0200 |
commit | c8caee61ff392db8bcf630309324b46d962886e1 (patch) | |
tree | aa56d0a46422597ce759654daf9d5af8bd33a45c | |
parent | 9321f8602ec903e1e311b831da0504826e1e4f90 (diff) |
tdf#156068: Add support for feOffset filter
Change-Id: I1b3dea0ee4f9eb2ee7498962b04baaf5ba68855c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153629
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r-- | svgio/Library_svgio.mk | 3 | ||||
-rw-r--r-- | svgio/inc/svgfeoffsetnode.hxx | 45 | ||||
-rw-r--r-- | svgio/inc/svgtoken.hxx | 3 | ||||
-rw-r--r-- | svgio/qa/cppunit/SvgImportTest.cxx | 21 | ||||
-rw-r--r-- | svgio/qa/cppunit/data/filterFeOffset.svg | 18 | ||||
-rw-r--r-- | svgio/source/svgreader/svgdocumenthandler.cxx | 17 | ||||
-rw-r--r-- | svgio/source/svgreader/svgfeoffsetnode.cxx | 92 | ||||
-rw-r--r-- | svgio/source/svgreader/svgfilternode.cxx | 9 | ||||
-rw-r--r-- | svgio/source/svgreader/svgtoken.cxx | 5 |
9 files changed, 204 insertions, 9 deletions
diff --git a/svgio/Library_svgio.mk b/svgio/Library_svgio.mk index 76c0e87123bb..3702806a311c 100644 --- a/svgio/Library_svgio.mk +++ b/svgio/Library_svgio.mk @@ -60,8 +60,9 @@ $(eval $(call gb_Library_add_exception_objects,svgio,\ svgio/source/svgreader/svgellipsenode \ svgio/source/svgreader/svggnode \ svgio/source/svgreader/svganode \ - svgio/source/svgreader/svgfegaussianblurnode \ svgio/source/svgreader/svgfecolormatrixnode \ + svgio/source/svgreader/svgfegaussianblurnode \ + svgio/source/svgreader/svgfeoffsetnode \ svgio/source/svgreader/svgfilternode \ svgio/source/svgreader/svggradientnode \ svgio/source/svgreader/svggradientstopnode \ diff --git a/svgio/inc/svgfeoffsetnode.hxx b/svgio/inc/svgfeoffsetnode.hxx new file mode 100644 index 000000000000..22bf212d7c20 --- /dev/null +++ b/svgio/inc/svgfeoffsetnode.hxx @@ -0,0 +1,45 @@ +/* -*- 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 SvgFeOffsetNode final : public SvgNode +{ +private: + SvgNumber maDx; + SvgNumber maDy; + +public: + SvgFeOffsetNode(SvgDocument& rDocument, SvgNode* pParent); + virtual ~SvgFeOffsetNode() 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 9c28674b1cfb..fb2e04c278f4 100644 --- a/svgio/inc/svgtoken.hxx +++ b/svgio/inc/svgtoken.hxx @@ -80,8 +80,9 @@ namespace svgio::svgreader Color, ClipPathNode, ClipPathProperty, - FeGaussianBlur, FeColorMatrix, + FeGaussianBlur, + FeOffset, Filter, Mask, ClipPathUnits, diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index c3bbc0f9c211..7e32e83faf3a 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -182,6 +182,27 @@ CPPUNIT_TEST_FIXTURE(Test, testFilterFeGaussianBlur) assertXPath(pDocument, "/primitive2D/transform/softedge", "radius", "5"); } +CPPUNIT_TEST_FIXTURE(Test, testFilterFeOffset) +{ + Primitive2DSequence aSequenceTdf132246 = parseSvg(u"/svgio/qa/cppunit/data/filterFeOffset.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/mask/transform", "xy11", "1"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy12", "0"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy13", "44"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy21", "0"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy22", "1"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy23", "66"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy31", "0"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy32", "0"); + assertXPath(pDocument, "/primitive2D/transform/mask/transform", "xy33", "1"); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf87309) { Primitive2DSequence aSequenceTdf87309 = parseSvg(u"/svgio/qa/cppunit/data/tdf87309.svg"); diff --git a/svgio/qa/cppunit/data/filterFeOffset.svg b/svgio/qa/cppunit/data/filterFeOffset.svg new file mode 100644 index 000000000000..89bb40eef888 --- /dev/null +++ b/svgio/qa/cppunit/data/filterFeOffset.svg @@ -0,0 +1,18 @@ +<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"> + <defs> + <filter id="offset" width="180" height="180"> + <feOffset in="SourceGraphic" dx="44" dy="66" /> + </filter> + </defs> + + <rect x="0" y="0" width="100" height="100" stroke="black" fill="green" /> + <rect + x="0" + y="0" + width="100" + height="100" + stroke="black" + fill="green" + filter="url(#offset)" /> +</svg> + diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx b/svgio/source/svgreader/svgdocumenthandler.cxx index 6158c70f631c..397a7fed74a1 100644 --- a/svgio/source/svgreader/svgdocumenthandler.cxx +++ b/svgio/source/svgreader/svgdocumenthandler.cxx @@ -43,6 +43,7 @@ #include <svgclippathnode.hxx> #include <svgfegaussianblurnode.hxx> #include <svgfecolormatrixnode.hxx> +#include <svgfeoffsetnode.hxx> #include <svgfilternode.hxx> #include <svgmasknode.hxx> #include <svgmarkernode.hxx> @@ -332,6 +333,13 @@ namespace mpTarget->parseAttributes(xAttribs); break; } + case SVGToken::FeColorMatrix: + { + /// new node for feColorMatrix + mpTarget = new SvgFeColorMatrixNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } case SVGToken::FeGaussianBlur: { /// new node for feGaussianBlur @@ -339,10 +347,10 @@ namespace mpTarget->parseAttributes(xAttribs); break; } - case SVGToken::FeColorMatrix: + case SVGToken::FeOffset: { - /// new node for feColorMatrix - mpTarget = new SvgFeColorMatrixNode(maDocument, mpTarget); + /// new node for feOffset + mpTarget = new SvgFeOffsetNode(maDocument, mpTarget); mpTarget->parseAttributes(xAttribs); break; } @@ -452,8 +460,9 @@ namespace case SVGToken::Mask: /// structural elements for filters - case SVGToken::FeGaussianBlur: case SVGToken::FeColorMatrix: + case SVGToken::FeGaussianBlur: + case SVGToken::FeOffset: case SVGToken::Filter: /// structural element marker diff --git a/svgio/source/svgreader/svgfeoffsetnode.cxx b/svgio/source/svgreader/svgfeoffsetnode.cxx new file mode 100644 index 000000000000..a2129b8f3ee5 --- /dev/null +++ b/svgio/source/svgreader/svgfeoffsetnode.cxx @@ -0,0 +1,92 @@ +/* -*- 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/transformprimitive2d.hxx> +#include <svgfeoffsetnode.hxx> +#include <o3tl/string_view.hxx> + +namespace svgio::svgreader +{ +SvgFeOffsetNode::SvgFeOffsetNode(SvgDocument& rDocument, SvgNode* pParent) + : SvgNode(SVGToken::FeOffset, rDocument, pParent) + , maDx(SvgNumber(0.0)) + , maDy(SvgNumber(0.0)) +{ +} + +SvgFeOffsetNode::~SvgFeOffsetNode() {} + +void SvgFeOffsetNode::parseAttribute(const OUString& /*rTokenName*/, SVGToken aSVGToken, + const OUString& aContent) +{ + // parse own + switch (aSVGToken) + { + case SVGToken::Dx: + { + SvgNumber aNum; + + if (readSingleNumber(aContent, aNum)) + { + if (aNum.isPositive()) + { + maDx = aNum; + } + } + break; + } + case SVGToken::Dy: + { + SvgNumber aNum; + + if (readSingleNumber(aContent, aNum)) + { + if (aNum.isPositive()) + { + maDy = aNum; + } + } + break; + } + default: + { + break; + } + } +} + +void SvgFeOffsetNode::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)); + } + + const drawinglayer::primitive2d::Primitive2DReference xRef( + new drawinglayer::primitive2d::TransformPrimitive2D(aTransform, std::move(rTarget))); + + rTarget = drawinglayer::primitive2d::Primitive2DContainer{ xRef }; +} + +} // 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 60d6371e1a0a..f95cf3530701 100644 --- a/svgio/source/svgreader/svgfilternode.cxx +++ b/svgio/source/svgreader/svgfilternode.cxx @@ -18,8 +18,9 @@ */ #include <svgfilternode.hxx> -#include <svgfegaussianblurnode.hxx> #include <svgfecolormatrixnode.hxx> +#include <svgfegaussianblurnode.hxx> +#include <svgfeoffsetnode.hxx> namespace svgio::svgreader { @@ -54,6 +55,12 @@ void SvgFilterNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTarg = dynamic_cast<const SvgFeColorMatrixNode&>(*pCandidate); rFeColorMatrixNode.apply(rTarget); } + else if (pCandidate->getType() == SVGToken::FeOffset) + { + const SvgFeOffsetNode& rFeOffsetNode + = dynamic_cast<const SvgFeOffsetNode&>(*pCandidate); + rFeOffsetNode.apply(rTarget); + } } } diff --git a/svgio/source/svgreader/svgtoken.cxx b/svgio/source/svgreader/svgtoken.cxx index ed50612323e5..83271638b99d 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, 139> aSVGTokenMapperList +constexpr frozen::unordered_map<std::u16string_view, SVGToken, 140> aSVGTokenMapperList { { u"width", SVGToken::Width }, { u"height", SVGToken::Height }, @@ -80,8 +80,9 @@ constexpr frozen::unordered_map<std::u16string_view, SVGToken, 139> aSVGTokenMap { u"color", SVGToken::Color }, { u"clipPath", SVGToken::ClipPathNode }, { u"clip-path", SVGToken::ClipPathProperty }, - { u"feGaussianBlur", SVGToken::FeGaussianBlur }, { u"feColorMatrix", SVGToken::FeColorMatrix }, + { u"feGaussianBlur", SVGToken::FeGaussianBlur }, + { u"feOffset", SVGToken::FeOffset }, { u"filter", SVGToken::Filter }, { u"mask", SVGToken::Mask }, { u"clipPathUnits", SVGToken::ClipPathUnits }, |