svgio/inc/svgstyleattributes.hxx | 3 - svgio/qa/cppunit/SvgImportTest.cxx | 29 ++++++++++ svgio/qa/cppunit/data/tdf149673.svg | 7 ++ svgio/qa/cppunit/data/tdf156201.svg | 36 ++++++++++++ svgio/source/svgreader/svganode.cxx | 2 svgio/source/svgreader/svgcirclenode.cxx | 2 svgio/source/svgreader/svgellipsenode.cxx | 2 svgio/source/svgreader/svggnode.cxx | 2 svgio/source/svgreader/svgimagenode.cxx | 2 svgio/source/svgreader/svglinenode.cxx | 2 svgio/source/svgreader/svgpathnode.cxx | 2 svgio/source/svgreader/svgpolynode.cxx | 2 svgio/source/svgreader/svgrectnode.cxx | 2 svgio/source/svgreader/svgstyleattributes.cxx | 73 ++++++++++---------------- svgio/source/svgreader/svgtextnode.cxx | 2 svgio/source/svgreader/svgusenode.cxx | 2 16 files changed, 114 insertions(+), 56 deletions(-)
New commits: commit 56039daae4a436d7ea1b093a02cf0e8ad3bda4a9 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Mon Jul 10 14:46:34 2023 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jul 10 16:54:06 2023 +0200 tdf#149673: only check opacity from parent... ... if it has a local css style Because it's the first in the style stack Partially reverts 3e0e67a152e9631574e28dacb6e06a96f03ebca2 "tdf#155932: tdf#97717: only apply opacity when primitive" Change-Id: I6a6bf08a519c84ac58c6111fd7da308cbf8a3021 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154270 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/svgio/inc/svgstyleattributes.hxx b/svgio/inc/svgstyleattributes.hxx index 0516fa2543af..4ada2e687ee9 100644 --- a/svgio/inc/svgstyleattributes.hxx +++ b/svgio/inc/svgstyleattributes.hxx @@ -287,8 +287,7 @@ namespace svgio::svgreader void add_postProcess( drawinglayer::primitive2d::Primitive2DContainer& rTarget, drawinglayer::primitive2d::Primitive2DContainer&& rSource, - const std::optional<basegfx::B2DHomMatrix>& pTransform, - bool bIsPrimitive) const; + const std::optional<basegfx::B2DHomMatrix>& pTransform) 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 fc9557a5c312..0f8b31d4b1cc 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -835,6 +835,22 @@ CPPUNIT_TEST_FIXTURE(Test, testRGBColor) assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxy", "110"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf149673) +{ + Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf149673.svg"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); + + CPPUNIT_ASSERT (pDocument); + + assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "90"); + assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence/polypolygoncolor[1]", "color", "#ff0000"); + assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence/polypolygoncolor[2]", "color", "#00ff00"); + assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence/polypolygoncolor[3]", "color", "#0000ff"); +} + CPPUNIT_TEST_FIXTURE(Test, testRGBAColor) { Primitive2DSequence aSequenceRGBAColor = parseSvg(u"/svgio/qa/cppunit/data/RGBAColor.svg"); diff --git a/svgio/qa/cppunit/data/tdf149673.svg b/svgio/qa/cppunit/data/tdf149673.svg new file mode 100644 index 000000000000..f73b9959d342 --- /dev/null +++ b/svgio/qa/cppunit/data/tdf149673.svg @@ -0,0 +1,7 @@ +<svg id="svg1" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"> + <g id="g1" opacity=".1"> + <circle id="circle1" cx="100" cy="60" fill="#f00" r="40"/> + <circle id="circle2" cx="70" cy="100" fill="#0f0" r="40"/> + <circle id="circle3" cx="130" cy="100" fill="#00f" r="40"/> + </g> +</svg> diff --git a/svgio/source/svgreader/svganode.cxx b/svgio/source/svgreader/svganode.cxx index 83dd7c50175e..e700574c5a40 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(), true); + pStyle->add_postProcess(rTarget, std::move(aContent), getTransform()); } } } diff --git a/svgio/source/svgreader/svgcirclenode.cxx b/svgio/source/svgreader/svgcirclenode.cxx index 363e85d111ab..513c128cf272 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } } // end of namespace svgio::svgreader diff --git a/svgio/source/svgreader/svgellipsenode.cxx b/svgio/source/svgreader/svgellipsenode.cxx index a822ef7134f0..8f203fc49869 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } } // end of namespace svgio::svgreader diff --git a/svgio/source/svgreader/svggnode.cxx b/svgio/source/svgreader/svggnode.cxx index e59db2972e13..d833a6fa92c4 100644 --- a/svgio/source/svgreader/svggnode.cxx +++ b/svgio/source/svgreader/svggnode.cxx @@ -97,7 +97,7 @@ namespace svgio::svgreader if(!aContent.empty()) { - pStyle->add_postProcess(rTarget, std::move(aContent), getTransform(), false); + pStyle->add_postProcess(rTarget, std::move(aContent), getTransform()); } } } diff --git a/svgio/source/svgreader/svgimagenode.cxx b/svgio/source/svgreader/svgimagenode.cxx index fa7cbe675a13..2ce6ce4c8038 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } // end of namespace svgio::svgreader diff --git a/svgio/source/svgreader/svglinenode.cxx b/svgio/source/svgreader/svglinenode.cxx index 7f433c7f6fc1..ea1ab343ff53 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } } // end of namespace svgio::svgreader diff --git a/svgio/source/svgreader/svgpathnode.cxx b/svgio/source/svgreader/svgpathnode.cxx index f34d4d3198c8..d52114aa6da8 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } } diff --git a/svgio/source/svgreader/svgpolynode.cxx b/svgio/source/svgreader/svgpolynode.cxx index 38a908a18756..74cd722915e4 100644 --- a/svgio/source/svgreader/svgpolynode.cxx +++ b/svgio/source/svgreader/svgpolynode.cxx @@ -105,7 +105,7 @@ namespace svgio::svgreader if(!aNewTarget.empty()) { - pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } } diff --git a/svgio/source/svgreader/svgrectnode.cxx b/svgio/source/svgreader/svgrectnode.cxx index 782887be9f35..291d8540912f 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } } // end of namespace svgio::svgreader diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index 91c27aeff637..fd4482057f17 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -1163,8 +1163,7 @@ namespace svgio::svgreader void SvgStyleAttributes::add_postProcess( drawinglayer::primitive2d::Primitive2DContainer& rTarget, drawinglayer::primitive2d::Primitive2DContainer&& rSource, - const std::optional<basegfx::B2DHomMatrix>& pTransform, - bool bIsPrimitive) const + const std::optional<basegfx::B2DHomMatrix>& pTransform) const { const double fOpacity(getOpacity().solve(mrOwner)); @@ -1175,20 +1174,15 @@ namespace svgio::svgreader drawinglayer::primitive2d::Primitive2DContainer aSource(std::move(rSource)); - // 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) + if(basegfx::fTools::less(fOpacity, 1.0)) { - 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)); + // 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) @@ -1291,7 +1285,7 @@ namespace svgio::svgreader maClipRule(FillRule::notset), maBaselineShift(BaselineShift::Baseline), maBaselineShiftNumber(0), - maResolvingParent(30, 0), + maResolvingParent(29, 0), mbIsClipPathContent(SVGToken::ClipPathNode == mrOwner.getType()), mbStrokeDasharraySet(false) { @@ -2282,14 +2276,16 @@ namespace svgio::svgreader return maOpacity; } - const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); - - if (pSvgStyleAttributes && maResolvingParent[8] < nStyleDepthLimit) + // This is called from add_postProcess so only check the parent style + // if it has a local css style, because it's the first in the stack + if(mrOwner.hasLocalCssStyle()) { - ++maResolvingParent[8]; - auto ret = pSvgStyleAttributes->getOpacity(); - --maResolvingParent[8]; - return ret; + const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); + + if (pSvgStyleAttributes && pSvgStyleAttributes->maOpacity.isSet()) + { + return pSvgStyleAttributes->maOpacity; + } } // default is 1 @@ -3051,11 +3047,11 @@ namespace svgio::svgreader { const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); - if (pSvgStyleAttributes && maResolvingParent[29] < nStyleDepthLimit) + if (pSvgStyleAttributes && maResolvingParent[8] < nStyleDepthLimit) { - ++maResolvingParent[29]; + ++maResolvingParent[8]; const SvgNumber aParentNumber = pSvgStyleAttributes->getBaselineShiftNumber(); - --maResolvingParent[29]; + --maResolvingParent[8]; return SvgNumber( aParentNumber.getNumber() * maBaselineShiftNumber.getNumber() * 0.01, diff --git a/svgio/source/svgreader/svgtextnode.cxx b/svgio/source/svgreader/svgtextnode.cxx index 35e130a097de..5b8cc3187070 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(), true); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), getTransform()); } } diff --git a/svgio/source/svgreader/svgusenode.cxx b/svgio/source/svgreader/svgusenode.cxx index b0fed16c73eb..312f8152b058 100644 --- a/svgio/source/svgreader/svgusenode.cxx +++ b/svgio/source/svgreader/svgusenode.cxx @@ -172,7 +172,7 @@ namespace svgio::svgreader if(fOpacity > 0.0 && Display::None != getDisplay()) { - pStyle->add_postProcess(rTarget, std::move(aNewTarget), aTransform, false); + pStyle->add_postProcess(rTarget, std::move(aNewTarget), aTransform); } } } commit 3d5b5914ef56395a8ba3d4c0a2eff8a5c52046b4 Author: Xisco Fauli <xiscofa...@libreoffice.org> AuthorDate: Mon Jul 10 14:10:01 2023 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jul 10 16:53:58 2023 +0200 tdf#156201: just check one level up in the style stack Otherwise, the parent might also have a local css style Change-Id: Ib6d1340045f22861aee3e526d22d014eeb2f5d38 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154248 Tested-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index 24f146592249..fc9557a5c312 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -505,6 +505,19 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf156018) assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]", "color", "#0000ff"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf156201) +{ + Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf156201.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/transform/transform/polypolygoncolor", "color", "#2f3ba1"); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf156167) { Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf156167.svg"); diff --git a/svgio/qa/cppunit/data/tdf156201.svg b/svgio/qa/cppunit/data/tdf156201.svg new file mode 100644 index 000000000000..3000e17f459e --- /dev/null +++ b/svgio/qa/cppunit/data/tdf156201.svg @@ -0,0 +1,36 @@ +<svg style="width: 100%; height: 100%;" height="492pt" version="1.1" viewBox="0 0 500 492" width="500pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <g id="PathCollection_1"> + <defs> + <path d=" +M52.0418 -266.565 +L54.1695 -266.795 +L54.1955 -266.832 +L54.2469 -266.844 +L56.3492 -268.627 +L57.4099 -268.849 +L59.524 -270.389 +L60.4641 -271.625 +L62.5433 -273.716 +L62.8642 -275.66 +L63.198 -277.417 +L62.6856 -278.465 +L60.8035 -281.602 +L60.4975 -281.91 +L59.9992 -282.386 +L57.6251 -284.681 +L56.2525 -285.174 +L54.6591 -286.742 +L54.5155 -286.797 +L52.0418 -279.184 +L52.0418 -270.892" id="C0_0_32ce96eee2"></path> + </defs> + <g clip-path="url(#p65124e5d4c)"> + <use style="fill:#2f3ba1;" x="0.0" xlink:href="#C0_0_32ce96eee2" y="492.3555"></use> + </g> + </g> + <defs> + <clipPath id="p65124e5d4c"> + <rect height="446.4" width="446.4" x="38.27125" y="23.14175"></rect> + </clipPath> + </defs> +</svg> diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index 12766fde7986..91c27aeff637 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -1291,7 +1291,7 @@ namespace svgio::svgreader maClipRule(FillRule::notset), maBaselineShift(BaselineShift::Baseline), maBaselineShiftNumber(0), - maResolvingParent(33, 0), + maResolvingParent(30, 0), mbIsClipPathContent(SVGToken::ClipPathNode == mrOwner.getType()), mbStrokeDasharraySet(false) { @@ -2376,11 +2376,11 @@ namespace svgio::svgreader const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); - if (pSvgStyleAttributes && maResolvingParent[31] < nStyleDepthLimit) + if (pSvgStyleAttributes && maResolvingParent[25] < nStyleDepthLimit) { - ++maResolvingParent[31]; + ++maResolvingParent[25]; auto ret = pSvgStyleAttributes->getClipRule(); - --maResolvingParent[31]; + --maResolvingParent[25]; return ret; } @@ -2865,12 +2865,9 @@ namespace svgio::svgreader { const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); - if (pSvgStyleAttributes && maResolvingParent[30] < nStyleDepthLimit) + if (pSvgStyleAttributes) { - ++maResolvingParent[30]; - auto ret = pSvgStyleAttributes->getClipPathXLink(); - --maResolvingParent[30]; - return ret; + return pSvgStyleAttributes->maClipPathXLink; } } @@ -2901,12 +2898,9 @@ namespace svgio::svgreader { const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); - if (pSvgStyleAttributes && maResolvingParent[32] < nStyleDepthLimit) + if (pSvgStyleAttributes) { - ++maResolvingParent[32]; - auto ret = pSvgStyleAttributes->getFilterXLink(); - --maResolvingParent[32]; - return ret; + return pSvgStyleAttributes->maFilterXLink; } } @@ -2937,12 +2931,9 @@ namespace svgio::svgreader { const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle(); - if (pSvgStyleAttributes && maResolvingParent[25] < nStyleDepthLimit) + if (pSvgStyleAttributes) { - ++maResolvingParent[25]; - auto ret = pSvgStyleAttributes->getMaskXLink(); - --maResolvingParent[25]; - return ret; + return pSvgStyleAttributes->maMaskXLink; } }