drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx | 3 +- drawinglayer/source/primitive2d/transformprimitive2d.cxx | 18 ++++++++++--- include/drawinglayer/primitive2d/transformprimitive2d.hxx | 7 ++++- svgio/qa/cppunit/SvgImportTest.cxx | 18 ++++++++++++- 4 files changed, 39 insertions(+), 7 deletions(-)
New commits: commit 1ae7a81e542c9b072e519d0ea0d4773ed26ca251 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sat Feb 3 14:54:12 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Feb 5 12:10:58 2024 +0100 tdf#108037 Reduce time and memory consumed exporting to PDF by avoiding making multiple copies of the Primitive2D container that we pass to TransformPrimitive2D. Instead, make TransformPrimitive2D store its children using a GroupPrimitive2D, which means we can share the GroupPrimitive2D among all the TransformPrimitive2D instances we create. Change-Id: I8a4398f9db6a6ab013ee24ad53836975fba6f3df Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162951 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx index 8c50993e6033..bc9158687481 100644 --- a/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx @@ -70,11 +70,12 @@ namespace drawinglayer::primitive2d rGraphic, basegfx::B2DHomMatrix()); + rtl::Reference<GroupPrimitive2D> xGroup = new GroupPrimitive2D(std::move(xSeq)); for(const auto &a : aMatrices) { rContainer.push_back(new TransformPrimitive2D( getTransformation() * a, - Primitive2DContainer(xSeq))); + *xGroup)); } } else diff --git a/drawinglayer/source/primitive2d/transformprimitive2d.cxx b/drawinglayer/source/primitive2d/transformprimitive2d.cxx index 0442cd68aa62..8c36fa9a73b9 100644 --- a/drawinglayer/source/primitive2d/transformprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/transformprimitive2d.cxx @@ -19,6 +19,7 @@ #include <drawinglayer/primitive2d/transformprimitive2d.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/Tools.hxx> #include <utility> @@ -30,18 +31,27 @@ namespace drawinglayer::primitive2d TransformPrimitive2D::TransformPrimitive2D( basegfx::B2DHomMatrix aTransformation, Primitive2DContainer&& aChildren) - : GroupPrimitive2D(std::move(aChildren)), - maTransformation(std::move(aTransformation)) + : maTransformation(std::move(aTransformation)), + mxChildren(new GroupPrimitive2D(std::move(aChildren))) + { + } + + TransformPrimitive2D::TransformPrimitive2D( + basegfx::B2DHomMatrix aTransformation, + GroupPrimitive2D& rChildren) + : maTransformation(std::move(aTransformation)), + mxChildren(&rChildren) { } bool TransformPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { - if(GroupPrimitive2D::operator==(rPrimitive)) + if(BasePrimitive2D::operator==(rPrimitive)) { const TransformPrimitive2D& rCompare = static_cast< const TransformPrimitive2D& >(rPrimitive); - return (getTransformation() == rCompare.getTransformation()); + return maTransformation == rCompare.maTransformation + && arePrimitive2DReferencesEqual(mxChildren, rCompare.mxChildren); } return false; diff --git a/include/drawinglayer/primitive2d/transformprimitive2d.hxx b/include/drawinglayer/primitive2d/transformprimitive2d.hxx index 73e589b8c2e8..8c3c22cc5b90 100644 --- a/include/drawinglayer/primitive2d/transformprimitive2d.hxx +++ b/include/drawinglayer/primitive2d/transformprimitive2d.hxx @@ -46,19 +46,24 @@ namespace drawinglayer::primitive2d different, transformed states without the need to create those thousand primitive contents. */ - class DRAWINGLAYER_DLLPUBLIC TransformPrimitive2D final : public GroupPrimitive2D + class DRAWINGLAYER_DLLPUBLIC TransformPrimitive2D final : public BasePrimitive2D { private: // the transformation to apply to the child geometry basegfx::B2DHomMatrix maTransformation; + rtl::Reference<GroupPrimitive2D> mxChildren; public: /// constructor TransformPrimitive2D( basegfx::B2DHomMatrix aTransformation, Primitive2DContainer&& rChildren); + TransformPrimitive2D( + basegfx::B2DHomMatrix aTransformation, + GroupPrimitive2D& rChildren); /// data read access + const Primitive2DContainer& getChildren() const { return mxChildren->getChildren(); } const basegfx::B2DHomMatrix& getTransformation() const { return maTransformation; } /// compare operator diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index d99e56bfef35..13dff82187f3 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -8,6 +8,7 @@ */ #include <sal/config.h> +#include <sal/log.hxx> #include <test/bootstrapfixture.hxx> #include <test/xmltesttools.hxx> @@ -83,12 +84,27 @@ namespace { bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const Primitive2DSequence& rB) { - return std::equal(rA.begin(), rA.end(), rB.begin(), rB.end(), + auto rv = std::mismatch(rA.begin(), rA.end(), rB.begin(), rB.end(), [](const css::uno::Reference<css::graphic::XPrimitive2D>& a, const css::uno::Reference<css::graphic::XPrimitive2D>& b) { return drawinglayer::primitive2d::arePrimitive2DReferencesEqual(a, b); }); + if (rv.first == rA.end() && rv.second == rB.end()) + return true; + if (rv.first == rA.end() || rv.second == rB.end()) + { + SAL_WARN("svgio", + "first seq length == " << rA.size() << + "second seq length == " << rB.size()); + return false; + } + auto idx = std::distance(rA.begin(), rv.first); + SAL_WARN("svgio", + "first difference at index " << idx << + " expected element " << typeid(*rA[idx]).name() << + " but got element " << typeid(*rB[idx]).name()); + return false; } }