svgio/Library_svgio.mk | 1 svgio/inc/svgfecolormatrixnode.hxx | 51 ++++++++++++++++ svgio/inc/svgtoken.hxx | 1 svgio/qa/cppunit/SvgImportTest.cxx | 13 ++++ svgio/qa/cppunit/data/filterLuminanceToAlpha.svg | 11 +++ svgio/source/svgreader/svgdocumenthandler.cxx | 15 ++++ svgio/source/svgreader/svgfecolormatrixnode.cxx | 72 +++++++++++++++++++++++ svgio/source/svgreader/svgfilternode.cxx | 7 ++ svgio/source/svgreader/svgstyleattributes.cxx | 5 + svgio/source/svgreader/svgtoken.cxx | 2 10 files changed, 176 insertions(+), 2 deletions(-)
New commits: commit a0ce0d4418ad92dd0e3a70cf698c549b544d6084 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Thu Jun 8 14:31:54 2023 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Jun 8 22:54:38 2023 +0200 tdf#155735: Add basic support for feColorMatrix for now, it only supports type="luminanceToAlpha" Change-Id: Ia84df9af08ac2be2e496a5fadb490deaf48210cf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152741 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit ebef488f765e753fd9acc42084ba25ea37e586f2) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152758 diff --git a/svgio/Library_svgio.mk b/svgio/Library_svgio.mk index 247653732d6f..6221cb141316 100644 --- a/svgio/Library_svgio.mk +++ b/svgio/Library_svgio.mk @@ -58,6 +58,7 @@ $(eval $(call gb_Library_add_exception_objects,svgio,\ svgio/source/svgreader/svggnode \ svgio/source/svgreader/svganode \ svgio/source/svgreader/svgfegaussianblurnode \ + svgio/source/svgreader/svgfecolormatrixnode \ svgio/source/svgreader/svgfilternode \ svgio/source/svgreader/svggradientnode \ svgio/source/svgreader/svggradientstopnode \ diff --git a/svgio/inc/svgfecolormatrixnode.hxx b/svgio/inc/svgfecolormatrixnode.hxx new file mode 100644 index 000000000000..7436f737b04c --- /dev/null +++ b/svgio/inc/svgfecolormatrixnode.hxx @@ -0,0 +1,51 @@ +/* -*- 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" +#include <basegfx/matrix/b2dhommatrix.hxx> + +namespace svgio::svgreader +{ +enum class Type +{ + None, + LuminanceToAlpha +}; + +class SvgFeColorMatrixNode final : public SvgNode +{ +private: + Type maType; + +public: + SvgFeColorMatrixNode(SvgDocument& rDocument, SvgNode* pParent); + virtual ~SvgFeColorMatrixNode() 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 262b5f3dda55..18c1a092c238 100644 --- a/svgio/inc/svgtoken.hxx +++ b/svgio/inc/svgtoken.hxx @@ -81,6 +81,7 @@ namespace svgio::svgreader ClipPathNode, ClipPathProperty, FeGaussianBlur, + FeColorMatrix, Filter, Mask, ClipPathUnits, diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index ce4db97e0954..ad5852127551 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -135,6 +135,19 @@ CPPUNIT_TEST_FIXTURE(Test, testSymbol) assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00d000"); } +CPPUNIT_TEST_FIXTURE(Test, testFilterLuminanceToAlpha) +{ + Primitive2DSequence aSequenceTdf132246 = parseSvg(u"/svgio/qa/cppunit/data/filterLuminanceToAlpha.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/modifiedColor"); +} + CPPUNIT_TEST_FIXTURE(Test, testFilterFeGaussianBlur) { Primitive2DSequence aSequenceTdf132246 = parseSvg(u"/svgio/qa/cppunit/data/filterFeGaussianBlur.svg"); diff --git a/svgio/qa/cppunit/data/filterLuminanceToAlpha.svg b/svgio/qa/cppunit/data/filterLuminanceToAlpha.svg new file mode 100644 index 000000000000..854fad125446 --- /dev/null +++ b/svgio/qa/cppunit/data/filterLuminanceToAlpha.svg @@ -0,0 +1,11 @@ +<svg + width="230" + height="120" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <filter id="luminanceToAlpha"> + <feColorMatrix type="luminanceToAlpha"/> + </filter> + <circle cx="170" cy="60" r="50" fill="green" filter="url(#luminanceToAlpha)" /> +</svg> + diff --git a/svgio/source/svgreader/svgdocumenthandler.cxx b/svgio/source/svgreader/svgdocumenthandler.cxx index 5e61693e64c7..43151253aacc 100644 --- a/svgio/source/svgreader/svgdocumenthandler.cxx +++ b/svgio/source/svgreader/svgdocumenthandler.cxx @@ -42,6 +42,7 @@ #include <svgimagenode.hxx> #include <svgclippathnode.hxx> #include <svgfegaussianblurnode.hxx> +#include <svgfecolormatrixnode.hxx> #include <svgfilternode.hxx> #include <svgmasknode.hxx> #include <svgmarkernode.hxx> @@ -349,6 +350,13 @@ namespace mpTarget->parseAttributes(xAttribs); break; } + case SVGToken::FeColorMatrix: + { + /// new node for feColorMatrix + mpTarget = new SvgFeColorMatrixNode(maDocument, mpTarget); + mpTarget->parseAttributes(xAttribs); + break; + } case SVGToken::Filter: { /// new node for Filter @@ -450,11 +458,14 @@ namespace /// styles (as stylesheets) case SVGToken::Style: - /// structural elements clip-path, feGaussianBlur, filter and mask + /// structural elements clip-path and mask case SVGToken::ClipPathNode: + case SVGToken::Mask: + + /// structural elements for filters case SVGToken::FeGaussianBlur: + case SVGToken::FeColorMatrix: case SVGToken::Filter: - case SVGToken::Mask: /// structural element marker case SVGToken::Marker: diff --git a/svgio/source/svgreader/svgfecolormatrixnode.cxx b/svgio/source/svgreader/svgfecolormatrixnode.cxx new file mode 100644 index 000000000000..fb53f1d5c503 --- /dev/null +++ b/svgio/source/svgreader/svgfecolormatrixnode.cxx @@ -0,0 +1,72 @@ +/* -*- 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 <svgfecolormatrixnode.hxx> +#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <o3tl/string_view.hxx> + +namespace svgio::svgreader +{ +SvgFeColorMatrixNode::SvgFeColorMatrixNode(SvgDocument& rDocument, SvgNode* pParent) + : SvgNode(SVGToken::FeColorMatrix, rDocument, pParent) + , maType(Type::None) +{ +} + +SvgFeColorMatrixNode::~SvgFeColorMatrixNode() {} + +void SvgFeColorMatrixNode::parseAttribute(const OUString& /*rTokenName*/, SVGToken aSVGToken, + const OUString& aContent) +{ + // parse own + switch (aSVGToken) + { + case SVGToken::Type: + { + if (!aContent.isEmpty()) + { + if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"luminanceToAlpha")) + { + maType = Type::LuminanceToAlpha; + } + } + break; + } + default: + { + break; + } + } +} + +void SvgFeColorMatrixNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTarget) const +{ + if (maType == Type::LuminanceToAlpha) + { + const drawinglayer::primitive2d::Primitive2DReference xRef( + new drawinglayer::primitive2d::ModifiedColorPrimitive2D( + std::move(rTarget), + std::make_shared<basegfx::BColorModifier_luminance_to_alpha>())); + 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 8eb0beb65e6b..12656a7c28e7 100644 --- a/svgio/source/svgreader/svgfilternode.cxx +++ b/svgio/source/svgreader/svgfilternode.cxx @@ -19,6 +19,7 @@ #include <svgfilternode.hxx> #include <svgfegaussianblurnode.hxx> +#include <svgfecolormatrixnode.hxx> namespace svgio::svgreader { @@ -47,6 +48,12 @@ void SvgFilterNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTarg = dynamic_cast<const SvgFeGaussianBlurNode*>(pCandidate); pFeGaussianBlurNode->apply(rTarget); } + else if (pCandidate->getType() == SVGToken::FeColorMatrix) + { + const SvgFeColorMatrixNode* pFeColorMatrixNode + = dynamic_cast<const SvgFeColorMatrixNode*>(pCandidate); + pFeColorMatrixNode->apply(rTarget); + } } } diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index 600f1690cb80..58a982a8a927 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -1213,6 +1213,10 @@ namespace svgio::svgreader { pFilter->apply(aSource); } + } + + if(!aSource.empty()) // test again, applied filter may have lead to empty geometry + { const SvgMaskNode* pMask = accessMaskXLink(); if(pMask) @@ -1279,6 +1283,7 @@ namespace svgio::svgreader maTextAnchor(TextAnchor::notset), maVisibility(Visibility::notset), mpClipPathXLink(nullptr), + maFilterXLink(OUString()), mpFilterXLink(nullptr), mpMaskXLink(nullptr), mpMarkerStartXLink(nullptr), diff --git a/svgio/source/svgreader/svgtoken.cxx b/svgio/source/svgreader/svgtoken.cxx index 48a0c8eb47df..8228689606bf 100644 --- a/svgio/source/svgreader/svgtoken.cxx +++ b/svgio/source/svgreader/svgtoken.cxx @@ -73,6 +73,7 @@ namespace svgio::svgreader const char aSVGStrClipPathNode[] = "clipPath"; const char aSVGStrClipPathProperty[] = "clip-path"; const char aSVGStrFeGaussianBlur[] = "feGaussianBlur"; + const char aSVGStrFeColorMatrix[] = "feColorMatrix"; const char aSVGStrFilter[] = "filter"; const char aSVGStrMask[] = "mask"; const char aSVGStrClipPathUnits[] = "clipPathUnits"; @@ -224,6 +225,7 @@ namespace svgio::svgreader { aSVGStrClipPathNode, SVGToken::ClipPathNode }, { aSVGStrClipPathProperty, SVGToken::ClipPathProperty }, { aSVGStrFeGaussianBlur, SVGToken::FeGaussianBlur }, + { aSVGStrFeColorMatrix, SVGToken::FeColorMatrix }, { aSVGStrFilter, SVGToken::Filter }, { aSVGStrMask, SVGToken::Mask }, { aSVGStrClipPathUnits, SVGToken::ClipPathUnits },