tdf#48062: Add support for atop operator in feComposite
Change-Id: Ifb83b4361d37566d189a7c5b11835f2a5e0eecc2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164862
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/svgio/inc/svgfecompositenode.hxx b/svgio/inc/svgfecompositenode.hxx
index 2fa321c..fcbc24e 100644
--- a/svgio/inc/svgfecompositenode.hxx
+++ b/svgio/inc/svgfecompositenode.hxx
@@ -30,6 +30,7 @@ enum class Operator
In,
Out,
Xor,
Atop,
};
class SvgFeCompositeNode : public SvgFilterNode
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index dc933c9..88bf4bc 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -249,6 +249,10 @@ CPPUNIT_TEST_FIXTURE(Test, testFilterFeComposite)
// out operator
assertXPath(pDocument, "/primitive2D/transform/mask[4]/polypolygoncolor"_ostr, 3);
assertXPath(pDocument, "/primitive2D/transform/mask[4]/polypolygon/polygon/point"_ostr, 6);
// atop operator
assertXPath(pDocument, "/primitive2D/transform/mask[5]/polypolygoncolor"_ostr, 3);
assertXPath(pDocument, "/primitive2D/transform/mask[5]/polypolygon/polygon[1]/point"_ostr, 6);
assertXPath(pDocument, "/primitive2D/transform/mask[5]/polypolygon/polygon[2]/point"_ostr, 4);
}
CPPUNIT_TEST_FIXTURE(Test, testFilterFeGaussianBlur)
diff --git a/svgio/source/svgreader/svgfecompositenode.cxx b/svgio/source/svgreader/svgfecompositenode.cxx
index 95ec021..1e20a0e 100644
--- a/svgio/source/svgreader/svgfecompositenode.cxx
+++ b/svgio/source/svgreader/svgfecompositenode.cxx
@@ -78,6 +78,10 @@ void SvgFeCompositeNode::parseAttribute(SVGToken aSVGToken, const OUString& aCon
{
maOperator = Operator::Xor;
}
else if (o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"atop"))
{
maOperator = Operator::Atop;
}
}
break;
}
@@ -131,6 +135,13 @@ void SvgFeCompositeNode::apply(drawinglayer::primitive2d::Primitive2DContainer&
{
aResult = basegfx::utils::solvePolygonOperationXor(aPolyPolygon, aPolyPolygon2);
}
else if (maOperator == Operator::Atop)
{
// Atop is the union of In and Out.
// The parts of in2 graphic that do not overlap with the in graphic stay untouched.
aResult = basegfx::utils::solvePolygonOperationDiff(aPolyPolygon2, aPolyPolygon);
aResult.append(basegfx::utils::solvePolygonOperationAnd(aPolyPolygon, aPolyPolygon2));
}
rTarget = drawinglayer::primitive2d::Primitive2DContainer{
new drawinglayer::primitive2d::MaskPrimitive2D(std::move(aResult), std::move(rTarget))