diff options
author | Xisco Fauli <xiscofauli@libreoffice.org> | 2024-03-14 23:53:49 +0100 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2024-03-15 01:06:22 +0100 |
commit | b240f6198fae7221b7cd3e4678403ad99827b53d (patch) | |
tree | 4fe24d057f26b58ccc17af4355485ad8ae0518dd /svgio/source | |
parent | ad161bf882099553949469f99759493c38169c8a (diff) |
tdf#48062: Add support for xor, in and out operators in feComposite
atop and arithmetic are still missing
Change-Id: I9b5bfeaa87b48071708ca4cb082916ea5f260adb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164852
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'svgio/source')
-rw-r--r-- | svgio/source/svgreader/svgfecompositenode.cxx | 69 | ||||
-rw-r--r-- | svgio/source/svgreader/svgtoken.cxx | 1 |
2 files changed, 66 insertions, 4 deletions
diff --git a/svgio/source/svgreader/svgfecompositenode.cxx b/svgio/source/svgreader/svgfecompositenode.cxx index b3418fca8709..95ec021969d8 100644 --- a/svgio/source/svgreader/svgfecompositenode.cxx +++ b/svgio/source/svgreader/svgfecompositenode.cxx @@ -18,11 +18,16 @@ #include <svgfecompositenode.hxx> #include <o3tl/string_view.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> namespace svgio::svgreader { SvgFeCompositeNode::SvgFeCompositeNode(SvgDocument& rDocument, SvgNode* pParent) : SvgFilterNode(SVGToken::FeComposite, rDocument, pParent) + , maOperator(Operator::Over) { } @@ -53,6 +58,29 @@ void SvgFeCompositeNode::parseAttribute(SVGToken aSVGToken, const OUString& aCon maResult = aContent.trim(); break; } + case SVGToken::Operator: + { + if (!aContent.isEmpty()) + { + if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"over")) + { + maOperator = Operator::Over; + } + else if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"in")) + { + maOperator = Operator::In; + } + else if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"out")) + { + maOperator = Operator::Out; + } + else if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"xor")) + { + maOperator = Operator::Xor; + } + } + break; + } default: { break; @@ -63,18 +91,51 @@ void SvgFeCompositeNode::parseAttribute(SVGToken aSVGToken, const OUString& aCon void SvgFeCompositeNode::apply(drawinglayer::primitive2d::Primitive2DContainer& rTarget, const SvgFilterNode* pParent) const { - if (const drawinglayer::primitive2d::Primitive2DContainer* rSource2 + basegfx::B2DPolyPolygon aPolyPolygon, aPolyPolygon2; + + // Process maIn2 first + if (const drawinglayer::primitive2d::Primitive2DContainer* pSource2 = pParent->findGraphicSource(maIn2)) { - rTarget = *rSource2; + rTarget.append(*pSource2); + const basegfx::B2DRange aRange2( + pSource2->getB2DRange(drawinglayer::geometry::ViewInformation2D())); + + aPolyPolygon2 = basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aRange2)); } - if (const drawinglayer::primitive2d::Primitive2DContainer* rSource + if (const drawinglayer::primitive2d::Primitive2DContainer* pSource = pParent->findGraphicSource(maIn)) { - rTarget.append(*rSource); + rTarget.append(*pSource); + const basegfx::B2DRange aRange( + pSource->getB2DRange(drawinglayer::geometry::ViewInformation2D())); + + aPolyPolygon = basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aRange)); + } + + basegfx::B2DPolyPolygon aResult; + if (maOperator == Operator::Over) + { + aResult = basegfx::utils::solvePolygonOperationOr(aPolyPolygon, aPolyPolygon2); + } + else if (maOperator == Operator::Out) + { + aResult = basegfx::utils::solvePolygonOperationDiff(aPolyPolygon, aPolyPolygon2); + } + else if (maOperator == Operator::In) + { + aResult = basegfx::utils::solvePolygonOperationAnd(aPolyPolygon, aPolyPolygon2); + } + else if (maOperator == Operator::Xor) + { + aResult = basegfx::utils::solvePolygonOperationXor(aPolyPolygon, aPolyPolygon2); } + rTarget = drawinglayer::primitive2d::Primitive2DContainer{ + new drawinglayer::primitive2d::MaskPrimitive2D(std::move(aResult), std::move(rTarget)) + }; + pParent->addGraphicSourceToMapper(maResult, rTarget); } diff --git a/svgio/source/svgreader/svgtoken.cxx b/svgio/source/svgreader/svgtoken.cxx index 04b3f9fa3ec6..b6e22b63c547 100644 --- a/svgio/source/svgreader/svgtoken.cxx +++ b/svgio/source/svgreader/svgtoken.cxx @@ -93,6 +93,7 @@ constexpr auto aSVGTokenMap = frozen::make_unordered_map<std::u16string_view, SV { u"filter", SVGToken::Filter }, { u"flood-color", SVGToken::FloodColor }, { u"flood-opacity", SVGToken::FloodOpacity }, + { u"operator", SVGToken::Operator }, { u"mask", SVGToken::Mask }, { u"clipPathUnits", SVGToken::ClipPathUnits }, { u"maskUnits", SVGToken::MaskUnits }, |