summaryrefslogtreecommitdiff
path: root/svgio/source
diff options
context:
space:
mode:
authorXisco Fauli <xiscofauli@libreoffice.org>2024-03-14 23:53:49 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2024-03-15 01:06:22 +0100
commitb240f6198fae7221b7cd3e4678403ad99827b53d (patch)
tree4fe24d057f26b58ccc17af4355485ad8ae0518dd /svgio/source
parentad161bf882099553949469f99759493c38169c8a (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.cxx69
-rw-r--r--svgio/source/svgreader/svgtoken.cxx1
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 },