diff options
author | Noel Grandin <noelgrandin@gmail.com> | 2024-02-03 14:54:12 +0200 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-02-06 20:32:16 +0100 |
commit | 2eb8316f5a87629a50484b7f89ce4183370dd357 (patch) | |
tree | 2fa8dfc4314caf4f75c1c8f13e2644ae3702e128 | |
parent | b77d256b96c5cfb34fa953b3ffc64c664b2a7743 (diff) |
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.grandin@collabora.co.uk>
(cherry picked from commit 1ae7a81e542c9b072e519d0ea0d4773ed26ca251)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162908
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
4 files changed, 39 insertions, 7 deletions
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 9324ad1b1849..51c66e52452a 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; } } |