tdf#160373: Iterate over all parents to check whether it's a clipPath content

Change-Id: I383ec264e4c88ebcee2ae6a839b762bba8abfc12
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165347
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/svgio/inc/svgstyleattributes.hxx b/svgio/inc/svgstyleattributes.hxx
index bf921f8..c5c0954 100644
--- a/svgio/inc/svgstyleattributes.hxx
+++ b/svgio/inc/svgstyleattributes.hxx
@@ -243,10 +243,6 @@ namespace svgio::svgreader

            mutable std::vector<sal_uInt16> maResolvingParent;

            // defines if this attributes are part of a ClipPath. If yes,
            // rough geometry will be created on decomposition by patching
            // values for fill, stroke, strokeWidth and others
            bool                        mbIsClipPathContent : 1;

            // #121221# Defines if evtl. an empty array *is* set
            bool                        mbStrokeDasharraySet : 1;
@@ -318,6 +314,11 @@ namespace svgio::svgreader
            SvgStyleAttributes(SvgNode& rOwner);
            ~SvgStyleAttributes();

            // Check if this attribute is part of a ClipPath.
            // If so, rough geometry will be created on decomposition by patching
            // values for fill, stroke, strokeWidth and others
            bool isClipPathContent() const;

            /// fill content
            bool isFillSet() const; // #i125258# ask if fill is a direct hard attribute (no hierarchy)
            const basegfx::BColor* getFill() const;
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index 88bf4bc..b0dd847 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -576,6 +576,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf156168)
    assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke[4]/line"_ostr, "color"_ostr, "#00ff00");
}

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

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

    CPPUNIT_ASSERT (pDocument);

    // Without the fix in place, nothing would be displayed
    assertXPath(pDocument, "/primitive2D/transform/transform/polypolygoncolor"_ostr, "color"_ostr, "#0000ff");
}

CPPUNIT_TEST_FIXTURE(Test, testTdf129356)
{
    Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf129356.svg");
diff --git a/svgio/qa/cppunit/data/tdf160373.svg b/svgio/qa/cppunit/data/tdf160373.svg
new file mode 100644
index 0000000..73b18bb
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf160373.svg
@@ -0,0 +1,14 @@
<?xml version='1.0' encoding='UTF-8' ?>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='503.75pt' height='503.25pt' viewBox='0 0 503.75 503.25'>
<defs>
  <style type='text/css'><![CDATA[
     rect { fill: none; }
  ]]></style>
</defs>
  <clipPath id='cpMC4wMHw1MDMuNzV8MC4wMHw1MDMuMjU='>
    <rect x='0.00' y='0.00' width='503.75' height='503.25' />
  </clipPath>
<g clip-path='url(#cpMC4wMHw1MDMuNzV8MC4wMHw1MDMuMjU=)'>
<rect class="r5" x="10" y="0" height="50" width="50" style="fill:blue"></rect>
</g>
</svg>
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index d5e3ad3..0ae986f 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -1287,18 +1287,9 @@ namespace svgio::svgreader
            maBaselineShift(BaselineShift::Baseline),
            maBaselineShiftNumber(0),
            maDominantBaseline(DominantBaseline::Auto),
            maResolvingParent(31, 0),
            mbIsClipPathContent(SVGToken::ClipPathNode == mrOwner.getType()),
            maResolvingParent(32, 0),
            mbStrokeDasharraySet(false)
        {
            const SvgStyleAttributes* pParentStyle = getParentStyle();
            if(!mbIsClipPathContent)
            {
                if(pParentStyle)
                {
                    mbIsClipPathContent = pParentStyle->mbIsClipPathContent;
                }
            }
        }

        SvgStyleAttributes::~SvgStyleAttributes()
@@ -2005,10 +1996,27 @@ namespace svgio::svgreader
            }
        }

        bool SvgStyleAttributes::isClipPathContent() const
        {
            if (SVGToken::ClipPathNode == mrOwner.getType())
                return true;

            const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
            if (pSvgStyleAttributes && maResolvingParent[31] < nStyleDepthLimit)
            {
                ++maResolvingParent[31];
                bool ret = pSvgStyleAttributes->isClipPathContent();
                --maResolvingParent[31];
                return ret;
            }

            return false;
        }

        // #i125258# ask if fill is a direct hard attribute (no hierarchy)
        bool SvgStyleAttributes::isFillSet() const
        {
            if(mbIsClipPathContent)
            if(isClipPathContent())
            {
                return false;
            }
@@ -2042,7 +2050,7 @@ namespace svgio::svgreader
                {
                    return &maFill.getBColor();
                }
                else if(mbIsClipPathContent)
                else if(isClipPathContent())
                {
                    const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();

@@ -2066,7 +2074,7 @@ namespace svgio::svgreader
                    const basegfx::BColor* pFill = pSvgStyleAttributes->getFill();
                    --maResolvingParent[0];

                    if(mbIsClipPathContent)
                    if(isClipPathContent())
                    {
                        if (pFill)
                        {
@@ -2269,7 +2277,7 @@ namespace svgio::svgreader
                return ret;
            }

            if(mbIsClipPathContent)
            if(isClipPathContent())
            {
                return SvgNumber(0.0);
            }