tdf#155932: tdf#97717: only apply opacity when primitive

Partially revert d47b37eea9779e3c354e6c19a7211a306965b7ef
"tdf#97717: do not call add_postProcess from g element"
since we still need to call add_postProcess from g to
apply the clip-path

Change-Id: Ibdc5afadc0db239d0b0e14810943009a4c0a16a9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153353
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
(cherry picked from commit f222b28f69740de1b3c8fb639fef32eb55ff420c)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153339
diff --git a/svgio/inc/svgstyleattributes.hxx b/svgio/inc/svgstyleattributes.hxx
index 52876ea..b54e3cd 100644
--- a/svgio/inc/svgstyleattributes.hxx
+++ b/svgio/inc/svgstyleattributes.hxx
@@ -293,7 +293,8 @@ namespace svgio::svgreader
            void add_postProcess(
                drawinglayer::primitive2d::Primitive2DContainer& rTarget,
                drawinglayer::primitive2d::Primitive2DContainer&& rSource,
                const std::optional<basegfx::B2DHomMatrix>& pTransform) const;
                const std::optional<basegfx::B2DHomMatrix>& pTransform,
                bool bIsPrimitive) const;

            /// helper to set mpCssStyleParent temporarily for CSS style hierarchies
            void setCssStyleParent(const SvgStyleAttributes* pNew) { mpCssStyleParent = pNew; }
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index 716bfba..018daa0 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -330,6 +330,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf145896)
    assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[3]", "color", "#0000ff");
}

CPPUNIT_TEST_FIXTURE(Test, testTdf155932)
{
    Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf155932.svg");
    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));

    drawinglayer::Primitive2dXmlDump dumper;
    xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);

    CPPUNIT_ASSERT (pDocument);

    assertXPath(pDocument, "/primitive2D/transform/mask/mask/unifiedtransparence", "transparence", "50");
    assertXPath(pDocument, "/primitive2D/transform/mask/mask/unifiedtransparence[1]/polypolygoncolor", "color", "#0000ff");
}

CPPUNIT_TEST_FIXTURE(Test, testTdf97717)
{
    Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf97717.svg");
diff --git a/svgio/qa/cppunit/data/tdf155932.svg b/svgio/qa/cppunit/data/tdf155932.svg
new file mode 100644
index 0000000..b533eda
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf155932.svg
@@ -0,0 +1,22 @@
<svg
  width="100%"
  height="100%"
  viewBox="0 0 150 500"
  preserveAspectRatio="xMidYMid meet"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- ref -->
  <defs>
    <g id="circles">
      <circle cx="30" cy="30" r="20" fill="blue" fill-opacity="0.5" />
    </g>
  </defs>
  <clipPath id="myClip">
    <circle r="35" />
  </clipPath>

  <g clip-path="url(#myClip)">
	  <circle cx="30" cy="30" r="20" fill="blue" fill-opacity="0.5" />
  </g>
</svg>

diff --git a/svgio/source/svgreader/svganode.cxx b/svgio/source/svgreader/svganode.cxx
index 5d992a3..927b13d 100644
--- a/svgio/source/svgreader/svganode.cxx
+++ b/svgio/source/svgreader/svganode.cxx
@@ -94,7 +94,7 @@ namespace svgio::svgreader

                if(!aContent.empty())
                {
                    pStyle->add_postProcess(rTarget, std::move(aContent), getTransform());
                    pStyle->add_postProcess(rTarget, std::move(aContent), getTransform(), true);
                }
            }
        }
diff --git a/svgio/source/svgreader/svgcirclenode.cxx b/svgio/source/svgreader/svgcirclenode.cxx
index 0ec940f..0cf15e5 100644
--- a/svgio/source/svgreader/svgcirclenode.cxx
+++ b/svgio/source/svgreader/svgcirclenode.cxx
@@ -135,7 +135,7 @@ namespace svgio::svgreader

            if(!aNewTarget.empty())
            {
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
            }
        }
} // end of namespace svgio::svgreader
diff --git a/svgio/source/svgreader/svgellipsenode.cxx b/svgio/source/svgreader/svgellipsenode.cxx
index b6208dd..9b5fa1b 100644
--- a/svgio/source/svgreader/svgellipsenode.cxx
+++ b/svgio/source/svgreader/svgellipsenode.cxx
@@ -150,7 +150,7 @@ namespace svgio::svgreader

            if(!aNewTarget.empty())
            {
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
            }
        }
} // end of namespace svgio::svgreader
diff --git a/svgio/source/svgreader/svggnode.cxx b/svgio/source/svgreader/svggnode.cxx
index f49e737..d668f9c 100644
--- a/svgio/source/svgreader/svggnode.cxx
+++ b/svgio/source/svgreader/svggnode.cxx
@@ -19,7 +19,6 @@

#include <svggnode.hxx>
#include <osl/diagnose.h>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>

namespace svgio::svgreader
{
@@ -86,26 +85,26 @@ namespace svgio::svgreader

        void SvgGNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DContainer& rTarget, bool bReferenced) const
        {
            SvgNode::decomposeSvgNode(rTarget, bReferenced);

            // if g element has transform, apply it
            if(SVGToken::G == getType())
            if(SVGToken::Defs == getType())
            {
                if(getTransform())
                // #i125258# no decompose needed for defs element, call parent for SVGTokenDefs
                SvgNode::decomposeSvgNode(rTarget, bReferenced);
            }
            else
            {
                // #i125258# for SVGTokenG decompose children
                const SvgStyleAttributes* pStyle = getSvgStyleAttributes();

                if(pStyle)
                {
                    drawinglayer::primitive2d::Primitive2DContainer aSource(std::move(rTarget));
                    // create embedding group element with transformation
                    const drawinglayer::primitive2d::Primitive2DReference xRef(
                        new drawinglayer::primitive2d::TransformPrimitive2D(
                            *getTransform(),
                            std::move(aSource)));
                    drawinglayer::primitive2d::Primitive2DContainer aContent;

                    aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
                    // decompose children
                    SvgNode::decomposeSvgNode(aContent, bReferenced);

                    if(!aSource.empty())
                    if(!aContent.empty())
                    {
                        // append to current target
                        rTarget.append(aSource);
                        pStyle->add_postProcess(rTarget, std::move(aContent), getTransform(), false);
                    }
                }
            }
diff --git a/svgio/source/svgreader/svgimagenode.cxx b/svgio/source/svgreader/svgimagenode.cxx
index 19c8c94..45e5467 100644
--- a/svgio/source/svgreader/svgimagenode.cxx
+++ b/svgio/source/svgreader/svgimagenode.cxx
@@ -340,7 +340,7 @@ namespace svgio::svgreader
            }

            // embed and add to rTarget, take local extra-transform into account
            pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
            pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
        }

} // end of namespace svgio::svgreader
diff --git a/svgio/source/svgreader/svglinenode.cxx b/svgio/source/svgreader/svglinenode.cxx
index b49f9c7..2fc5e64 100644
--- a/svgio/source/svgreader/svglinenode.cxx
+++ b/svgio/source/svgreader/svglinenode.cxx
@@ -145,7 +145,7 @@ namespace svgio::svgreader

            if(!aNewTarget.empty())
            {
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
            }
        }
} // end of namespace svgio::svgreader
diff --git a/svgio/source/svgreader/svgpathnode.cxx b/svgio/source/svgreader/svgpathnode.cxx
index b3b498b..82b6037 100644
--- a/svgio/source/svgreader/svgpathnode.cxx
+++ b/svgio/source/svgreader/svgpathnode.cxx
@@ -108,7 +108,7 @@ namespace svgio::svgreader

                if(!aNewTarget.empty())
                {
                    pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                    pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
                }
            }
        }
diff --git a/svgio/source/svgreader/svgpolynode.cxx b/svgio/source/svgreader/svgpolynode.cxx
index 8866345..84beea4 100644
--- a/svgio/source/svgreader/svgpolynode.cxx
+++ b/svgio/source/svgreader/svgpolynode.cxx
@@ -106,7 +106,7 @@ namespace svgio::svgreader

                if(!aNewTarget.empty())
                {
                    pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                    pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
                }
            }
        }
diff --git a/svgio/source/svgreader/svgrectnode.cxx b/svgio/source/svgreader/svgrectnode.cxx
index d744343..3e81927 100644
--- a/svgio/source/svgreader/svgrectnode.cxx
+++ b/svgio/source/svgreader/svgrectnode.cxx
@@ -207,7 +207,7 @@ namespace svgio::svgreader

            if(!aNewTarget.empty())
            {
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
            }
        }
} // end of namespace svgio::svgreader
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index 9e9bd5e..092f847 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -1161,7 +1161,8 @@ namespace svgio::svgreader
        void SvgStyleAttributes::add_postProcess(
            drawinglayer::primitive2d::Primitive2DContainer& rTarget,
            drawinglayer::primitive2d::Primitive2DContainer&& rSource,
            const std::optional<basegfx::B2DHomMatrix>& pTransform) const
            const std::optional<basegfx::B2DHomMatrix>& pTransform,
            bool bIsPrimitive) const
        {
            if(rSource.empty())
                return;
@@ -1175,15 +1176,20 @@ namespace svgio::svgreader

            drawinglayer::primitive2d::Primitive2DContainer aSource(std::move(rSource));

            if(basegfx::fTools::less(fOpacity, 1.0))
            // tdf#97717: only apply opacity when it's a primitive, otherwise, it might be
            // applied more than once, since getOpacity() checks the parents
            if (bIsPrimitive)
            {
                // embed in UnifiedTransparencePrimitive2D
                const drawinglayer::primitive2d::Primitive2DReference xRef(
                    new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                        std::move(aSource),
                        1.0 - fOpacity));
                if(basegfx::fTools::less(fOpacity, 1.0))
                {
                    // embed in UnifiedTransparencePrimitive2D
                    const drawinglayer::primitive2d::Primitive2DReference xRef(
                        new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                            std::move(aSource),
                            1.0 - fOpacity));

                aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
                    aSource = drawinglayer::primitive2d::Primitive2DContainer { xRef };
                }
            }

            if(pTransform)
diff --git a/svgio/source/svgreader/svgtextnode.cxx b/svgio/source/svgreader/svgtextnode.cxx
index f8c0694..55ba6b6 100644
--- a/svgio/source/svgreader/svgtextnode.cxx
+++ b/svgio/source/svgreader/svgtextnode.cxx
@@ -251,7 +251,7 @@ namespace svgio::svgreader

            if(!aNewTarget.empty())
            {
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform());
                pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true);
            }
        }