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;
 }
 }
 

Reply via email to