drawinglayer/inc/primitive2d/texteffectprimitive2d.hxx                |    5 
 drawinglayer/inc/primitive2d/textlineprimitive2d.hxx                  |    2 
 drawinglayer/inc/primitive2d/textstrikeoutprimitive2d.hxx             |    4 
 drawinglayer/inc/primitive2d/wallpaperprimitive2d.hxx                 |    2 
 drawinglayer/qa/unit/border.cxx                                       |    8 
 drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx  |   17 
 drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx    |    7 
 drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx     |   12 
 drawinglayer/source/primitive2d/PolyPolygonHairlinePrimitive2D.cxx    |    9 
 drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D.cxx       |    7 
 drawinglayer/source/primitive2d/PolyPolygonMarkerPrimitive2D.cxx      |    9 
 drawinglayer/source/primitive2d/PolyPolygonSelectionPrimitive2D.cxx   |    8 
 drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D.cxx      |    9 
 drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx        |   14 
 drawinglayer/source/primitive2d/borderlineprimitive2d.cxx             |   17 
 drawinglayer/source/primitive2d/controlprimitive2d.cxx                |   10 
 drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx         |    8 
 drawinglayer/source/primitive2d/discreteshadowprimitive2d.cxx         |    8 
 drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx             |    4 
 drawinglayer/source/primitive2d/epsprimitive2d.cxx                    |    7 
 drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx           |   28 -
 drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx            |   14 
 drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx              |   12 
 drawinglayer/source/primitive2d/graphicprimitive2d.cxx                |   12 
 drawinglayer/source/primitive2d/gridprimitive2d.cxx                   |   23 -
 drawinglayer/source/primitive2d/helplineprimitive2d.cxx               |   24 -
 drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx            |   11 
 drawinglayer/source/primitive2d/mediaprimitive2d.cxx                  |    4 
 drawinglayer/source/primitive2d/metafileprimitive2d.cxx               |    8 
 drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx            |    8 
 drawinglayer/source/primitive2d/patternfillprimitive2d.cxx            |   14 
 drawinglayer/source/primitive2d/polygonprimitive2d.cxx                |   60 +-
 drawinglayer/source/primitive2d/primitivetools2d.cxx                  |   28 -
 drawinglayer/source/primitive2d/sceneprimitive2d.cxx                  |   23 -
 drawinglayer/source/primitive2d/svggradientprimitive2d.cxx            |   50 +-
 drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx          |  134 
+++---
 drawinglayer/source/primitive2d/texteffectprimitive2d.cxx             |   39 -
 drawinglayer/source/primitive2d/textlineprimitive2d.cxx               |   16 
 drawinglayer/source/primitive2d/textprimitive2d.cxx                   |   17 
 drawinglayer/source/primitive2d/textstrikeoutprimitive2d.cxx          |   17 
 drawinglayer/source/primitive2d/wallpaperprimitive2d.cxx              |    9 
 drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx             |    4 
 drawinglayer/source/processor2d/baseprocessor2d.cxx                   |    3 
 drawinglayer/source/tools/wmfemfhelper.cxx                            |    8 
 include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx |   11 
 include/drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx   |    5 
 include/drawinglayer/primitive2d/PolyPolygonGraphicPrimitive2D.hxx    |    5 
 include/drawinglayer/primitive2d/PolyPolygonHairlinePrimitive2D.hxx   |    5 
 include/drawinglayer/primitive2d/PolyPolygonHatchPrimitive2D.hxx      |    5 
 include/drawinglayer/primitive2d/PolyPolygonMarkerPrimitive2D.hxx     |    5 
 include/drawinglayer/primitive2d/PolyPolygonSelectionPrimitive2D.hxx  |    5 
 include/drawinglayer/primitive2d/PolyPolygonStrokePrimitive2D.hxx     |    5 
 include/drawinglayer/primitive2d/PolygonMarkerPrimitive2D.hxx         |    5 
 include/drawinglayer/primitive2d/PolygonStrokeArrowPrimitive2D.hxx    |    5 
 include/drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx         |    5 
 include/drawinglayer/primitive2d/PolygonWavePrimitive2D.hxx           |    5 
 include/drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx       |    5 
 include/drawinglayer/primitive2d/borderlineprimitive2d.hxx            |    5 
 include/drawinglayer/primitive2d/controlprimitive2d.hxx               |    5 
 include/drawinglayer/primitive2d/discretebitmapprimitive2d.hxx        |    2 
 include/drawinglayer/primitive2d/discreteshadowprimitive2d.hxx        |    2 
 include/drawinglayer/primitive2d/embedded3dprimitive2d.hxx            |    2 
 include/drawinglayer/primitive2d/epsprimitive2d.hxx                   |    2 
 include/drawinglayer/primitive2d/fillgradientprimitive2d.hxx          |    4 
 include/drawinglayer/primitive2d/fillgraphicprimitive2d.hxx           |    2 
 include/drawinglayer/primitive2d/fillhatchprimitive2d.hxx             |    2 
 include/drawinglayer/primitive2d/graphicprimitive2d.hxx               |    5 
 include/drawinglayer/primitive2d/gridprimitive2d.hxx                  |    2 
 include/drawinglayer/primitive2d/helplineprimitive2d.hxx              |    2 
 include/drawinglayer/primitive2d/markerarrayprimitive2d.hxx           |    2 
 include/drawinglayer/primitive2d/mediaprimitive2d.hxx                 |    2 
 include/drawinglayer/primitive2d/metafileprimitive2d.hxx              |    2 
 include/drawinglayer/primitive2d/pagepreviewprimitive2d.hxx           |    2 
 include/drawinglayer/primitive2d/patternfillprimitive2d.hxx           |    2 
 include/drawinglayer/primitive2d/sceneprimitive2d.hxx                 |    2 
 include/drawinglayer/primitive2d/svggradientprimitive2d.hxx           |   13 
 include/drawinglayer/primitive2d/textdecoratedprimitive2d.hxx         |    2 
 include/drawinglayer/primitive2d/textprimitive2d.hxx                  |    5 
 include/drawinglayer/primitive2d/wrongspellprimitive2d.hxx            |    2 
 include/svx/sdr/primitive2d/sdrframeborderprimitive2d.hxx             |    3 
 svx/inc/sdr/overlay/overlaytools.hxx                                  |   12 
 svx/inc/sdr/primitive2d/sdrcaptionprimitive2d.hxx                     |    2 
 svx/inc/sdr/primitive2d/sdrcellprimitive.hxx                          |    5 
 svx/inc/sdr/primitive2d/sdrconnectorprimitive2d.hxx                   |    2 
 svx/inc/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx                 |    2 
 svx/inc/sdr/primitive2d/sdrellipseprimitive2d.hxx                     |    4 
 svx/inc/sdr/primitive2d/sdrgrafprimitive2d.hxx                        |    5 
 svx/inc/sdr/primitive2d/sdrmeasureprimitive2d.hxx                     |    2 
 svx/inc/sdr/primitive2d/sdrolecontentprimitive2d.hxx                  |    2 
 svx/inc/sdr/primitive2d/sdrpathprimitive2d.hxx                        |    2 
 svx/inc/sdr/primitive2d/sdrrectangleprimitive2d.hxx                   |    2 
 svx/inc/sdr/primitive2d/sdrtextprimitive2d.hxx                        |   14 
 svx/qa/unit/svdraw.cxx                                                |   10 
 svx/qa/unit/table.cxx                                                 |    4 
 svx/source/diagram/IDiagramHelper.cxx                                 |   20 
 svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx              |   15 
 svx/source/sdr/overlay/overlaytools.cxx                               |  222 
++++------
 svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx                  |    5 
 svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx                |    5 
 svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx              |    5 
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx                  |   20 
 svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx                  |    9 
 svx/source/sdr/primitive2d/sdrframeborderprimitive2d.cxx              |   12 
 svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx                     |    7 
 svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx                  |    4 
 svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx               |   16 
 svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx                     |    5 
 svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx                |    5 
 svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx                     |   34 -
 svx/source/table/viewcontactoftableobj.cxx                            |   10 
 sw/source/core/draw/dflyobj.cxx                                       |   10 
 sw/source/core/layout/paintfrm.cxx                                    |   19 
 sw/source/uibase/docvw/AnchorOverlayObject.cxx                        |   19 
 sw/source/uibase/docvw/ShadowOverlayObject.cxx                        |   21 
 114 files changed, 726 insertions(+), 681 deletions(-)

New commits:
commit 3b83c6ac804cf7adcea036d1fb7dda113a72f457
Author:     Noel Grandin <[email protected]>
AuthorDate: Sun Feb 4 13:15:01 2024 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Mon Feb 12 11:36:05 2024 +0100

    make BufferedDecompositionPrimitive2D store a Primitive2DReference..
    
    .. instead of a Primitive2DContainer.
    
    The container very frequently contains only a single item, since
    the decomposition method often sticks only a single top-level node
    in there, so it turns out to be a net loss overall, memory
    consumption-wise.
    
    Also, if we return a single Primitive2DReference from
    a BufferedDecomposition, that maximises the sharing of
    data between the BufferedDecomposition objects at the
    bottom of the decomposed tree, and objects higher up.
    
    Change-Id: Iaf272e60e2997299cc35a1bd209c51b6b79e9a8b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162976
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/drawinglayer/inc/primitive2d/texteffectprimitive2d.hxx 
b/drawinglayer/inc/primitive2d/texteffectprimitive2d.hxx
index c586c6f23509..2ff1a963321e 100644
--- a/drawinglayer/inc/primitive2d/texteffectprimitive2d.hxx
+++ b/drawinglayer/inc/primitive2d/texteffectprimitive2d.hxx
@@ -57,9 +57,8 @@ private:
     basegfx::B2DHomMatrix maLastObjectToViewTransformation;
 
     /// create local decomposition
-    virtual void
-    create2DDecomposition(Primitive2DContainer& rContainer,
-                          const geometry::ViewInformation2D& rViewInformation) 
const override;
+    virtual Primitive2DReference
+    create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) 
const override;
 
 public:
     /// constructor
diff --git a/drawinglayer/inc/primitive2d/textlineprimitive2d.hxx 
b/drawinglayer/inc/primitive2d/textlineprimitive2d.hxx
index e27364e7895b..904ee38e31c6 100644
--- a/drawinglayer/inc/primitive2d/textlineprimitive2d.hxx
+++ b/drawinglayer/inc/primitive2d/textlineprimitive2d.hxx
@@ -41,7 +41,7 @@ namespace drawinglayer::primitive2d
             basegfx::BColor                             maLineColor;
 
             /// local decomposition.
-            virtual void create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
+            virtual Primitive2DReference create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const override;
 
         public:
             /// constructor
diff --git a/drawinglayer/inc/primitive2d/textstrikeoutprimitive2d.hxx 
b/drawinglayer/inc/primitive2d/textstrikeoutprimitive2d.hxx
index 516299198192..ffb8c144e77f 100644
--- a/drawinglayer/inc/primitive2d/textstrikeoutprimitive2d.hxx
+++ b/drawinglayer/inc/primitive2d/textstrikeoutprimitive2d.hxx
@@ -68,7 +68,7 @@ namespace drawinglayer::primitive2d
             css::lang::Locale                       maLocale;
 
             /// local decomposition.
-            virtual void create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
+            virtual Primitive2DReference create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const override;
 
         public:
             /// constructor
@@ -105,7 +105,7 @@ namespace drawinglayer::primitive2d
             TextStrikeout                           meTextStrikeout;
 
             /// local decomposition.
-            virtual void create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
+            virtual Primitive2DReference create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const override;
 
         public:
             /// constructor
diff --git a/drawinglayer/inc/primitive2d/wallpaperprimitive2d.hxx 
b/drawinglayer/inc/primitive2d/wallpaperprimitive2d.hxx
index c92006b36db3..cf9a1ea49320 100644
--- a/drawinglayer/inc/primitive2d/wallpaperprimitive2d.hxx
+++ b/drawinglayer/inc/primitive2d/wallpaperprimitive2d.hxx
@@ -47,7 +47,7 @@ namespace drawinglayer::primitive2d
             WallpaperStyle                      meWallpaperStyle;
 
             /// create local decomposition
-            virtual void create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const override;
+            virtual Primitive2DReference create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const override;
 
         public:
             /// constructor
diff --git a/drawinglayer/qa/unit/border.cxx b/drawinglayer/qa/unit/border.cxx
index f6f9feba5427..c69e0e94e7ba 100644
--- a/drawinglayer/qa/unit/border.cxx
+++ b/drawinglayer/qa/unit/border.cxx
@@ -14,6 +14,7 @@
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
 #include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
 #include <drawinglayer/processor2d/processor2dtools.hxx>
 #include <rtl/ref.hxx>
@@ -72,11 +73,14 @@ CPPUNIT_TEST_FIXTURE(DrawinglayerBorderTest, 
testDoubleDecompositionSolid)
     aBorder->get2DDecomposition(aContainer, aView);
 
     // Make sure it results in two borders as it's a double one.
-    CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), aContainer.size());
+    CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), aContainer.size());
+    auto* pGroupPrimitive
+        = dynamic_cast<const 
drawinglayer::primitive2d::GroupPrimitive2D*>(aContainer[0].get());
+    CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), 
pGroupPrimitive->getChildren().size());
 
     // Get the inside line, now a PolygonStrokePrimitive2D
     auto pInside = dynamic_cast<const 
drawinglayer::primitive2d::PolygonStrokePrimitive2D*>(
-        aContainer[0].get());
+        pGroupPrimitive->getChildren()[0].get());
     CPPUNIT_ASSERT(pInside);
 
     // Make sure the inside line's height is fLeftWidth.
diff --git 
a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
index 92d32a4dd73a..61eb34251913 100644
--- a/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/BufferedDecompositionPrimitive2D.cxx
@@ -53,10 +53,10 @@ namespace drawinglayer::primitive2d
 {
 void flushBufferedDecomposition(BufferedDecompositionPrimitive2D& rTarget)
 {
-    rTarget.setBuffered2DDecomposition(Primitive2DContainer());
+    rTarget.setBuffered2DDecomposition(nullptr);
 }
 
-const Primitive2DContainer& 
BufferedDecompositionPrimitive2D::getBuffered2DDecomposition() const
+const Primitive2DReference& 
BufferedDecompositionPrimitive2D::getBuffered2DDecomposition() const
 {
     if (0 != maCallbackSeconds && maCallbackTimer.is())
     {
@@ -67,7 +67,7 @@ const Primitive2DContainer& 
BufferedDecompositionPrimitive2D::getBuffered2DDecom
     return maBuffered2DDecomposition;
 }
 
-void 
BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DContainer&&
 rNew)
+void 
BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DReference
 rNew)
 {
     if (0 == maCallbackSeconds)
     {
@@ -78,7 +78,7 @@ void 
BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DCon
 
     if (maCallbackTimer.is())
     {
-        if (rNew.empty())
+        if (!rNew)
         {
             // stop timer
             maCallbackTimer->stop();
@@ -91,7 +91,7 @@ void 
BufferedDecompositionPrimitive2D::setBuffered2DDecomposition(Primitive2DCon
                 maCallbackTimer->start();
         }
     }
-    else if (!rNew.empty())
+    else if (rNew)
     {
         // decomposition defined/set/changed, init & start timer
         maCallbackTimer.set(new LocalCallbackTimer(*this));
@@ -126,12 +126,11 @@ void BufferedDecompositionPrimitive2D::get2DDecomposition(
     Primitive2DDecompositionVisitor& rVisitor,
     const geometry::ViewInformation2D& rViewInformation) const
 {
-    if (getBuffered2DDecomposition().empty())
+    if (!getBuffered2DDecomposition())
     {
-        Primitive2DContainer aNewSequence;
-        create2DDecomposition(aNewSequence, rViewInformation);
+        Primitive2DReference aNew = create2DDecomposition(rViewInformation);
         
const_cast<BufferedDecompositionPrimitive2D*>(this)->setBuffered2DDecomposition(
-            std::move(aNewSequence));
+            std::move(aNew));
     }
 
     if (0 == maCallbackSeconds)
diff --git a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
index c6e700f28fe3..4fe3321e62f8 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGradientPrimitive2D.cxx
@@ -29,8 +29,8 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonGradientPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonGradientPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     if (!getFillGradient().isDefault())
     {
@@ -41,8 +41,9 @@ void PolyPolygonGradientPrimitive2D::create2DDecomposition(
         Primitive2DContainer aSubSequence{ pNewGradient };
 
         // create mask primitive
-        rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), 
std::move(aSubSequence)));
+        return new MaskPrimitive2D(getB2DPolyPolygon(), 
std::move(aSubSequence));
     }
+    return nullptr;
 }
 
 PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
index 328e98896240..31a7acb03d7c 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx
@@ -31,24 +31,24 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonGraphicPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonGraphicPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     if (getFillGraphic().isDefault())
-        return;
+        return nullptr;
 
     const Graphic& rGraphic = getFillGraphic().getGraphic();
     const GraphicType aType(rGraphic.GetType());
 
     // is there a bitmap or a metafile (do we have content)?
     if (GraphicType::Bitmap != aType && GraphicType::GdiMetafile != aType)
-        return;
+        return nullptr;
 
     const Size aPrefSize(rGraphic.GetPrefSize());
 
     // does content have a size?
     if (!(aPrefSize.Width() && aPrefSize.Height()))
-        return;
+        return nullptr;
 
     // create SubSequence with FillGraphicPrimitive2D based on polygon range
     const basegfx::B2DRange aOutRange(getB2DPolyPolygon().getB2DRange());
@@ -93,7 +93,7 @@ void PolyPolygonGraphicPrimitive2D::create2DDecomposition(
     }
 
     // embed to mask primitive
-    rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), 
Primitive2DContainer{ xSubRef }));
+    return new MaskPrimitive2D(getB2DPolyPolygon(), Primitive2DContainer{ 
xSubRef });
 }
 
 PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/PolyPolygonHairlinePrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonHairlinePrimitive2D.cxx
index 8f6ad15abb9e..88b15160e2c0 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonHairlinePrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonHairlinePrimitive2D.cxx
@@ -19,6 +19,7 @@
 
 #include <drawinglayer/primitive2d/PolyPolygonHairlinePrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
@@ -28,17 +29,19 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonHairlinePrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonHairlinePrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
     const sal_uInt32 nCount(aPolyPolygon.count());
 
+    Primitive2DContainer aContainer;
     for (sal_uInt32 a(0); a < nCount; a++)
     {
-        rContainer.push_back(
+        aContainer.push_back(
             new PolygonHairlinePrimitive2D(aPolyPolygon.getB2DPolygon(a), 
getBColor()));
     }
+    return new GroupPrimitive2D(std::move(aContainer));
 }
 
 
PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(basegfx::B2DPolyPolygon
 aPolyPolygon,
diff --git a/drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D.cxx
index 79fcd78cc99b..2379e54e3de8 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonHatchPrimitive2D.cxx
@@ -29,8 +29,8 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonHatchPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonHatchPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     if (!getFillHatch().isDefault())
     {
@@ -41,8 +41,9 @@ void PolyPolygonHatchPrimitive2D::create2DDecomposition(
         Primitive2DContainer aSubSequence{ pNewHatch };
 
         // create mask primitive
-        rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), 
std::move(aSubSequence)));
+        return new MaskPrimitive2D(getB2DPolyPolygon(), 
std::move(aSubSequence));
     }
+    return nullptr;
 }
 
 PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/PolyPolygonMarkerPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonMarkerPrimitive2D.cxx
index a8ee5e5d25de..9c9e3b1ae81f 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonMarkerPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonMarkerPrimitive2D.cxx
@@ -19,6 +19,7 @@
 
 #include <drawinglayer/primitive2d/PolyPolygonMarkerPrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolygonMarkerPrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
@@ -28,18 +29,20 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonMarkerPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonMarkerPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
     const sal_uInt32 nCount(aPolyPolygon.count());
 
+    Primitive2DContainer aContainer;
     for (sal_uInt32 a(0); a < nCount; a++)
     {
-        rContainer.push_back(new 
PolygonMarkerPrimitive2D(aPolyPolygon.getB2DPolygon(a),
+        aContainer.push_back(new 
PolygonMarkerPrimitive2D(aPolyPolygon.getB2DPolygon(a),
                                                           getRGBColorA(), 
getRGBColorB(),
                                                           
getDiscreteDashLength()));
     }
+    return new GroupPrimitive2D(std::move(aContainer));
 }
 
 
PolyPolygonMarkerPrimitive2D::PolyPolygonMarkerPrimitive2D(basegfx::B2DPolyPolygon
 aPolyPolygon,
diff --git 
a/drawinglayer/source/primitive2d/PolyPolygonSelectionPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonSelectionPrimitive2D.cxx
index 3da2116fc2a8..a5595a4bcaeb 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonSelectionPrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonSelectionPrimitive2D.cxx
@@ -31,11 +31,11 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonSelectionPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonSelectionPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     if (getTransparence() >= 1.0 || !getB2DPolyPolygon().count())
-        return;
+        return nullptr;
 
     Primitive2DContainer aRetval;
 
@@ -67,7 +67,7 @@ void PolyPolygonSelectionPrimitive2D::create2DDecomposition(
         aRetval = Primitive2DContainer{ aTrans };
     }
 
-    rContainer.append(std::move(aRetval));
+    return new GroupPrimitive2D(std::move(aRetval));
 }
 
 PolyPolygonSelectionPrimitive2D::PolyPolygonSelectionPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D.cxx 
b/drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D.cxx
index 2ee13898711e..9c32d8853d8d 100644
--- a/drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D.cxx
+++ b/drawinglayer/source/primitive2d/PolyPolygonStrokePrimitive2D.cxx
@@ -22,23 +22,26 @@
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
 #include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <utility>
 
 using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-void PolyPolygonStrokePrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolyPolygonStrokePrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
     const sal_uInt32 nCount(aPolyPolygon.count());
 
+    Primitive2DContainer aContainer;
     for (sal_uInt32 a(0); a < nCount; a++)
     {
-        rContainer.push_back(new PolygonStrokePrimitive2D(
+        aContainer.push_back(new PolygonStrokePrimitive2D(
             aPolyPolygon.getB2DPolygon(a), getLineAttribute(), 
getStrokeAttribute()));
     }
+    return new GroupPrimitive2D(std::move(aContainer));
 }
 
 PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx 
b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
index c3759be5b918..ea1b2a56942a 100644
--- a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
@@ -31,15 +31,15 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void 
BackgroundColorPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference 
BackgroundColorPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             // transparency invalid or completely transparent, done
             if(getTransparency() < 0.0 || getTransparency() >= 1.0)
-                return;
+                return nullptr;
 
             // no viewport, not visible, done
             if(rViewInformation.getViewport().isEmpty())
-                return;
+                return nullptr;
 
             // create decompose geometry
             const basegfx::B2DPolygon 
aOutline(basegfx::utils::createPolygonFromRect(rViewInformation.getViewport()));
@@ -55,7 +55,7 @@ namespace drawinglayer::primitive2d
                         getTransparency());
             }
 
-            rContainer.push_back(aDecompose);
+            return aDecompose;
         }
 
         BackgroundColorPrimitive2D::BackgroundColorPrimitive2D(
@@ -86,13 +86,13 @@ namespace drawinglayer::primitive2d
 
         void 
BackgroundColorPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& 
rVisitor, const geometry::ViewInformation2D& rViewInformation) const
         {
-            if(!getBuffered2DDecomposition().empty() && (maLastViewport != 
rViewInformation.getViewport()))
+            if(getBuffered2DDecomposition() && (maLastViewport != 
rViewInformation.getViewport()))
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< BackgroundColorPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< BackgroundColorPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember ViewRange
                 const_cast< BackgroundColorPrimitive2D* 
>(this)->maLastViewport = rViewInformation.getViewport();
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx 
b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 68eed1864828..3ea94f1aefbb 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -23,6 +23,7 @@
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <rtl/math.hxx>
 
 #include <algorithm>
@@ -113,10 +114,10 @@ namespace drawinglayer::primitive2d
             return fRetval;
         }
 
-        void 
BorderLinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, 
const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
BorderLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& 
/*rViewInformation*/) const
         {
             if (getStart().equal(getEnd()) || getBorderLines().empty())
-                return;
+                return nullptr;
 
             // get data and vectors
             basegfx::B2DVector aVector(getEnd() - getStart());
@@ -125,6 +126,7 @@ namespace drawinglayer::primitive2d
             const double fFullWidth(getFullWidth());
             double fOffset(fFullWidth * -0.5);
 
+            Primitive2DContainer aContainer;
             for(const auto& candidate : maBorderLines)
             {
                 const double fWidth(candidate.getLineAttribute().getWidth());
@@ -142,7 +144,7 @@ namespace drawinglayer::primitive2d
                         // start and end extends lead to an edge perpendicular 
to the line, so we can just use
                         // a PolygonStrokePrimitive2D for representation
                         addPolygonStrokePrimitive2D(
-                            rContainer,
+                            aContainer,
                             aStart - (aVector * candidate.getStartLeft()),
                             aEnd + (aVector * candidate.getEndLeft()),
                             candidate.getLineAttribute(),
@@ -163,7 +165,7 @@ namespace drawinglayer::primitive2d
                             aPolygon.append(aEnd + aHalfLineOffset + (aVector 
* candidate.getEndRight()));
                             aPolygon.append(aStart + aHalfLineOffset - 
(aVector * candidate.getStartRight()));
 
-                            rContainer.push_back(
+                            aContainer.push_back(
                                 new PolyPolygonColorPrimitive2D(
                                     basegfx::B2DPolyPolygon(aPolygon),
                                     candidate.getLineAttribute().getColor()));
@@ -198,7 +200,7 @@ namespace drawinglayer::primitive2d
                                     aPolygon.append(aStart + aHalfLineOffset - 
(aVector * candidate.getStartRight()));
                                 }
 
-                                rContainer.push_back(
+                                aContainer.push_back(
                                     new PolyPolygonColorPrimitive2D(
                                         basegfx::B2DPolyPolygon(aPolygon),
                                         
candidate.getLineAttribute().getColor()));
@@ -227,7 +229,7 @@ namespace drawinglayer::primitive2d
                                 aPolygon.append(aEnd + aHalfLineOffset + 
(aVector * fMin));
                                 aPolygon.append(aEnd - aHalfLineOffset + 
(aVector * fMin));
 
-                                rContainer.push_back(
+                                aContainer.push_back(
                                     new PolyPolygonColorPrimitive2D(
                                         basegfx::B2DPolyPolygon(aPolygon),
                                         
candidate.getLineAttribute().getColor()));
@@ -237,7 +239,7 @@ namespace drawinglayer::primitive2d
                             }
 
                             addPolygonStrokePrimitive2D(
-                                rContainer,
+                                aContainer,
                                 aStrokeStart,
                                 aStrokeEnd,
                                 candidate.getLineAttribute(),
@@ -248,6 +250,7 @@ namespace drawinglayer::primitive2d
 
                 fOffset += fWidth;
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         bool BorderLinePrimitive2D::isHorizontalOrVertical(const 
geometry::ViewInformation2D& rViewInformation) const
diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx 
b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
index fc6f69be521d..730e522dc6f6 100644
--- a/drawinglayer/source/primitive2d/controlprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
@@ -224,7 +224,7 @@ namespace drawinglayer::primitive2d
             return xRetval;
         }
 
-        void ControlPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference ControlPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             // try to create a bitmap decomposition. If that fails for some 
reason,
             // at least create a replacement decomposition.
@@ -235,7 +235,7 @@ namespace drawinglayer::primitive2d
                 xReference = createPlaceholderDecomposition();
             }
 
-            rContainer.push_back(xReference);
+            return xReference;
         }
 
         ControlPrimitive2D::ControlPrimitive2D(
@@ -319,16 +319,16 @@ namespace drawinglayer::primitive2d
             // destroy existing decomposition. To detect change, use size of 
unit size in view coordinates
             const basegfx::B2DVector 
aNewScaling(rViewInformation.getObjectToViewTransformation() * 
basegfx::B2DVector(1.0, 1.0));
 
-            if(!getBuffered2DDecomposition().empty())
+            if(getBuffered2DDecomposition())
             {
                 if(!maLastViewScaling.equal(aNewScaling))
                 {
                     // conditions of last local decomposition have changed, 
delete
-                    const_cast< ControlPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                    const_cast< ControlPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
                 }
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember ViewTransformation
                 const_cast< ControlPrimitive2D* >(this)->maLastViewScaling = 
aNewScaling;
diff --git a/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx 
b/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx
index 7ec7040ff2a1..66dcfcb403e1 100644
--- a/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/discretebitmapprimitive2d.cxx
@@ -25,14 +25,14 @@
 
 namespace drawinglayer::primitive2d
 {
-        void 
DiscreteBitmapPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
DiscreteBitmapPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             // use getViewTransformation() and getObjectTransformation() from
             // ObjectAndViewTransformationDependentPrimitive2D to create a 
BitmapPrimitive2D
             // with the correct mapping
 
             if(getBitmapEx().IsEmpty())
-                return;
+                return nullptr;
 
             // get discrete size
             const Size& rSizePixel = getBitmapEx().GetSizePixel();
@@ -64,10 +64,10 @@ namespace drawinglayer::primitive2d
             aObjectTransform = aInverseObjectTransformation * aObjectTransform;
 
             // create BitmapPrimitive2D with now object-local coordinate data
-            rContainer.push_back(
+            return
                 new BitmapPrimitive2D(
                     getBitmapEx(),
-                    aObjectTransform));
+                    aObjectTransform);
         }
 
         DiscreteBitmapPrimitive2D::DiscreteBitmapPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/discreteshadowprimitive2d.cxx 
b/drawinglayer/source/primitive2d/discreteshadowprimitive2d.cxx
index dfeade98e8c7..1ff96ce60886 100644
--- a/drawinglayer/source/primitive2d/discreteshadowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/discreteshadowprimitive2d.cxx
@@ -151,12 +151,12 @@ namespace drawinglayer::primitive2d
 
 namespace drawinglayer::primitive2d
 {
-        void 
DiscreteShadowPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
DiscreteShadowPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             Primitive2DContainer xRetval;
 
             if(getDiscreteShadow().getBitmapEx().IsEmpty())
-                return;
+                return nullptr;
 
             const sal_Int32 
nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
             const basegfx::B2DVector aScale(getTransform() * 
basegfx::B2DVector(1.0, 1.0));
@@ -250,10 +250,10 @@ namespace drawinglayer::primitive2d
                         fBorderY + fSingleY));
 
             // put all in object transformation to get to target positions
-            rContainer.push_back(
+            return
                 new TransformPrimitive2D(
                     getTransform(),
-                    std::move(xRetval)));
+                    std::move(xRetval));
         }
 
         DiscreteShadowPrimitive2D::DiscreteShadowPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx 
b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
index 96fd4e86dbf4..6c7ebd113a43 100644
--- a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
@@ -59,13 +59,13 @@ namespace drawinglayer::primitive2d
             return !maShadowPrimitives.empty();
         }
 
-        void 
Embedded3DPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, 
const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference 
Embedded3DPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& 
rViewInformation) const
         {
             // use info to create a yellow 2d rectangle, similar to empty 3d 
scenes and/or groups
             const basegfx::B2DRange 
aLocal2DRange(getB2DRange(rViewInformation));
             basegfx::B2DPolygon 
aOutline(basegfx::utils::createPolygonFromRect(aLocal2DRange));
             const basegfx::BColor aYellow(1.0, 1.0, 0.0);
-            rContainer.push_back(new 
PolygonHairlinePrimitive2D(std::move(aOutline), aYellow));
+            return new PolygonHairlinePrimitive2D(std::move(aOutline), 
aYellow);
         }
 
         Embedded3DPrimitive2D::Embedded3DPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/epsprimitive2d.cxx 
b/drawinglayer/source/primitive2d/epsprimitive2d.cxx
index 249bd3abaab1..760d5d764c41 100644
--- a/drawinglayer/source/primitive2d/epsprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/epsprimitive2d.cxx
@@ -24,7 +24,7 @@
 
 namespace drawinglayer::primitive2d
 {
-        void EpsPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference EpsPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             const GDIMetaFile& rSubstituteContent = getMetaFile();
 
@@ -34,11 +34,12 @@ namespace drawinglayer::primitive2d
                 // To really use the Eps data, a renderer has to know and 
interpret this primitive
                 // directly.
 
-                rContainer.push_back(
+                return
                     new MetafilePrimitive2D(
                         getEpsTransform(),
-                        rSubstituteContent));
+                        rSubstituteContent);
             }
+            return nullptr;
         }
 
         EpsPrimitive2D::EpsPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx 
b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
index f39daccc4320..1166c8950881 100644
--- a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
@@ -23,6 +23,7 @@
 #include <texture/texture.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <utility>
 #include <algorithm>
 
@@ -141,19 +142,20 @@ namespace drawinglayer::primitive2d
             }
         }
 
-        void FillGradientPrimitive2D::createFill(Primitive2DContainer& 
rContainer, bool bOverlapping) const
+        Primitive2DReference FillGradientPrimitive2D::createFill(bool 
bOverlapping) const
         {
+            Primitive2DContainer aContainer;
             if (bOverlapping)
             {
                 // OverlappingFill: create solid fill with outmost color
-                rContainer.push_back(
+                aContainer.push_back(
                     new PolyPolygonColorPrimitive2D(
                         basegfx::B2DPolyPolygon(
                             
basegfx::utils::createPolygonFromRect(getOutputRange())),
                         getOuterColor()));
 
                 // create solid fill steps by providing callback as lambda
-                auto aCallback([&rContainer,this](
+                auto aCallback([&aContainer,this](
                     const basegfx::B2DHomMatrix& rMatrix,
                     const basegfx::BColor& rColor)
                 {
@@ -162,7 +164,7 @@ namespace drawinglayer::primitive2d
                     aNewPoly.transform(rMatrix);
 
                     // create solid fill
-                    rContainer.push_back(
+                    aContainer.push_back(
                         new PolyPolygonColorPrimitive2D(
                             basegfx::B2DPolyPolygon(aNewPoly),
                             rColor));
@@ -179,7 +181,7 @@ namespace drawinglayer::primitive2d
                     // not really a gradient, we need to create a start 
primitive
                     // entry using the single color and the covered area
                     const basegfx::B2DRange aOutmostRange(getOutputRange());
-                    rContainer.push_back(
+                    aContainer.push_back(
                         new PolyPolygonColorPrimitive2D(
                             
basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aOutmostRange)),
                             getOuterColor()));
@@ -190,11 +192,11 @@ namespace drawinglayer::primitive2d
                     basegfx::B2DPolyPolygon aCombinedPolyPoly;
                     basegfx::BColor aLastColor;
 
-                    auto 
aCallback([&rContainer,&aCombinedPolyPoly,&aLastColor,this](
+                    auto 
aCallback([&aContainer,&aCombinedPolyPoly,&aLastColor,this](
                         const basegfx::B2DHomMatrix& rMatrix,
                         const basegfx::BColor& rColor)
                     {
-                        if (rContainer.empty())
+                        if (aContainer.empty())
                         {
                             // 1st callback, init CombinedPolyPoly & create 
1st entry
                             basegfx::B2DRange aOutmostRange(getOutputRange());
@@ -211,7 +213,7 @@ namespace drawinglayer::primitive2d
                             aCombinedPolyPoly.append(aFirstPoly);
 
                             // create first primitive
-                            rContainer.push_back(
+                            aContainer.push_back(
                                 new PolyPolygonColorPrimitive2D(
                                     aCombinedPolyPoly,
                                     getOuterColor()));
@@ -232,7 +234,7 @@ namespace drawinglayer::primitive2d
                             aCombinedPolyPoly.append(aNextPoly);
 
                             // create primitive with correct color
-                            rContainer.push_back(
+                            aContainer.push_back(
                                 new PolyPolygonColorPrimitive2D(
                                     aCombinedPolyPoly,
                                     aLastColor));
@@ -247,15 +249,16 @@ namespace drawinglayer::primitive2d
                     generateMatricesAndColors(aCallback);
 
                     // add last inner polygon with last color
-                    rContainer.push_back(
+                    aContainer.push_back(
                         new PolyPolygonColorPrimitive2D(
                             aCombinedPolyPoly,
                             aLastColor));
                 }
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
-        void 
FillGradientPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
FillGradientPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             // default creates overlapping fill which works with AntiAliasing 
and without.
             // The non-overlapping version does not create single filled 
polygons, but
@@ -266,8 +269,9 @@ namespace drawinglayer::primitive2d
 
             if(!getFillGradient().isDefault())
             {
-                createFill(rContainer, /*bOverlapping*/true);
+                return createFill(/*bOverlapping*/true);
             }
+            return nullptr;
         }
 
         FillGradientPrimitive2D::FillGradientPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx 
b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx
index bc9158687481..a553687e7787 100644
--- a/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillgraphicprimitive2d.cxx
@@ -34,24 +34,25 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void 
FillGraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, 
const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
FillGraphicPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             const attribute::FillGraphicAttribute& rAttribute = 
getFillGraphic();
 
             if(rAttribute.isDefault())
-                return;
+                return nullptr;
 
             const Graphic& rGraphic = rAttribute.getGraphic();
 
             if(GraphicType::Bitmap != rGraphic.GetType() && 
GraphicType::GdiMetafile != rGraphic.GetType())
-                return;
+                return nullptr;
 
             const Size aSize(rGraphic.GetPrefSize());
 
             if(!(aSize.Width() && aSize.Height()))
-                return;
+                return nullptr;
 
             // we have a graphic (bitmap or metafile) with some size
+            Primitive2DContainer aContainer;
             if(rAttribute.getTiling())
             {
                 // get object range and create tiling matrices
@@ -73,7 +74,7 @@ namespace drawinglayer::primitive2d
                 rtl::Reference<GroupPrimitive2D> xGroup = new 
GroupPrimitive2D(std::move(xSeq));
                 for(const auto &a : aMatrices)
                 {
-                    rContainer.push_back(new TransformPrimitive2D(
+                    aContainer.push_back(new TransformPrimitive2D(
                         getTransformation() * a,
                         *xGroup));
                 }
@@ -86,10 +87,11 @@ namespace drawinglayer::primitive2d
                         rAttribute.getGraphicRange().getRange(),
                         rAttribute.getGraphicRange().getMinimum()));
 
-                create2DDecompositionOfGraphic(rContainer,
+                create2DDecompositionOfGraphic(aContainer,
                     rGraphic,
                     aObjectTransform);
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         FillGraphicPrimitive2D::FillGraphicPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx 
b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
index 1e86c907c406..c855460824e7 100644
--- a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
@@ -21,6 +21,7 @@
 #include <texture/texture.hxx>
 #include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
@@ -33,10 +34,10 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void FillHatchPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference FillHatchPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             if(getFillHatch().isDefault())
-                return;
+                return nullptr;
 
             // create hatch
             const basegfx::BColor aHatchColor(getFillHatch().getColor());
@@ -100,12 +101,12 @@ namespace drawinglayer::primitive2d
 
             // prepare return value
             const bool bFillBackground(getFillHatch().isFillBackground());
-
+            Primitive2DContainer aContainer;
             // evtl. create filled background
             if(bFillBackground)
             {
                 // create primitive for background
-                rContainer.push_back(
+                aContainer.push_back(
                     new PolyPolygonColorPrimitive2D(
                         basegfx::B2DPolyPolygon(
                             
basegfx::utils::createPolygonFromRect(getOutputRange())), getBColor()));
@@ -124,8 +125,9 @@ namespace drawinglayer::primitive2d
                 aNewLine.append(rMatrix * aEnd);
 
                 // create hairline
-                rContainer.push_back(new 
PolygonHairlinePrimitive2D(std::move(aNewLine), aHatchColor));
+                aContainer.push_back(new 
PolygonHairlinePrimitive2D(std::move(aNewLine), aHatchColor));
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         FillHatchPrimitive2D::FillHatchPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx 
b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
index bcccf3ad9d00..8219d25d59bc 100644
--- a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -31,13 +31,13 @@
 
 namespace drawinglayer::primitive2d
 {
-void GraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer,
-                                               const 
geometry::ViewInformation2D&) const
+Primitive2DReference
+GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D&) 
const
 {
     if (0 == getGraphicAttr().GetAlpha())
     {
         // content is invisible, done
-        return;
+        return nullptr;
     }
 
     // do not apply mirroring from GraphicAttr to the Metafile by calling
@@ -107,7 +107,7 @@ void 
GraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer,
     if (aRetval.empty())
     {
         // content is invisible, done
-        return;
+        return nullptr;
     }
 
     if (isAdjusted || isDrawMode)
@@ -127,7 +127,7 @@ void 
GraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer,
         if (aRetval.empty())
         {
             // content is invisible, done
-            return;
+            return nullptr;
         }
     }
 
@@ -164,7 +164,7 @@ void 
GraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer,
             getGraphicAttr().GetBottomCrop() * aCropScaleFactor.getY()) };
     }
 
-    rContainer.append(std::move(aRetval));
+    return new GroupPrimitive2D(std::move(aRetval));
 }
 
 GraphicPrimitive2D::GraphicPrimitive2D(basegfx::B2DHomMatrix aTransform,
diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx 
b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
index b43d05486dac..1a996188f03c 100644
--- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
@@ -20,6 +20,7 @@
 #include <drawinglayer/primitive2d/gridprimitive2d.hxx>
 #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
 #include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
@@ -31,10 +32,10 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void GridPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference GridPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             if(!(!rViewInformation.getViewport().isEmpty() && getWidth() > 0.0 
&& getHeight() > 0.0))
-                return;
+                return nullptr;
 
             // decompose grid matrix to get logic size
             basegfx::B2DVector aScale, aTranslate;
@@ -159,7 +160,7 @@ namespace drawinglayer::primitive2d
             }
 
             if(aExtendedViewport.isEmpty())
-                return;
+                return nullptr;
 
             // prepare point vectors for point and cross markers
             std::vector< basegfx::B2DPoint > aPositionsPoint;
@@ -229,25 +230,27 @@ namespace drawinglayer::primitive2d
             const sal_uInt32 nCountCross(aPositionsCross.size());
 
             // add PointArrayPrimitive2D if point markers were added
+            Primitive2DContainer aContainer;
             if(nCountPoint)
             {
-                rContainer.push_back(new 
PointArrayPrimitive2D(std::move(aPositionsPoint), getBColor()));
+                aContainer.push_back(new 
PointArrayPrimitive2D(std::move(aPositionsPoint), getBColor()));
             }
 
             // add MarkerArrayPrimitive2D if cross markers were added
             if(!nCountCross)
-                return;
+                return new GroupPrimitive2D(std::move(aContainer));
 
             if(!getSubdivisionsX() && !getSubdivisionsY())
             {
                 // no subdivisions, so fall back to points at grid positions, 
no need to
                 // visualize a difference between divisions and sub-divisions
-                rContainer.push_back(new 
PointArrayPrimitive2D(std::move(aPositionsCross), getBColor()));
+                aContainer.push_back(new 
PointArrayPrimitive2D(std::move(aPositionsCross), getBColor()));
             }
             else
             {
-                rContainer.push_back(new 
MarkerArrayPrimitive2D(std::move(aPositionsCross), getCrossMarker()));
+                aContainer.push_back(new 
MarkerArrayPrimitive2D(std::move(aPositionsCross), getCrossMarker()));
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         GridPrimitive2D::GridPrimitive2D(
@@ -306,16 +309,16 @@ namespace drawinglayer::primitive2d
 
         void 
GridPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, 
const geometry::ViewInformation2D& rViewInformation) const
         {
-            if(!getBuffered2DDecomposition().empty())
+            if(getBuffered2DDecomposition())
             {
                 if(maLastViewport != rViewInformation.getViewport() || 
maLastObjectToViewTransformation != 
rViewInformation.getObjectToViewTransformation())
                 {
                     // conditions of last local decomposition have changed, 
delete
-                    const_cast< GridPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                    const_cast< GridPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
                 }
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember ViewRange and ViewTransformation
                 const_cast< GridPrimitive2D* 
>(this)->maLastObjectToViewTransformation = 
rViewInformation.getObjectToViewTransformation();
diff --git a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx 
b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
index 56d53d8e73fc..047084eb1469 100644
--- a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
@@ -23,6 +23,7 @@
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
 #include <drawinglayer/primitive2d/PolygonMarkerPrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 
 
 using namespace com::sun::star;
@@ -30,14 +31,14 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void HelplinePrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference HelplinePrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             if(rViewInformation.getViewport().isEmpty() || 
getDirection().equalZero())
-                return;
+                return nullptr;
 
             // position to view coordinates, DashLen and DashLen in logic
             const basegfx::B2DPoint 
aViewPosition(rViewInformation.getObjectToViewTransformation() * getPosition());
-
+            Primitive2DReference xRet;
             switch(getStyle())
             {
                 default : // HelplineStyle2D::Point
@@ -52,7 +53,7 @@ namespace drawinglayer::primitive2d
                     aLineA.append(aStartA);
                     aLineA.append(aEndA);
                     
aLineA.transform(rViewInformation.getInverseObjectToViewTransformation());
-                    rContainer.push_back(new 
PolygonMarkerPrimitive2D(std::move(aLineA), getRGBColA(), getRGBColB(), 
getDiscreteDashLength()));
+                    auto xMarker1 = new 
PolygonMarkerPrimitive2D(std::move(aLineA), getRGBColA(), getRGBColB(), 
getDiscreteDashLength());
 
                     const basegfx::B2DVector 
aPerpendicularNormalizedDirection(basegfx::getPerpendicular(aNormalizedDirection));
                     const basegfx::B2DPoint aStartB(aViewPosition - 
aPerpendicularNormalizedDirection);
@@ -61,8 +62,9 @@ namespace drawinglayer::primitive2d
                     aLineB.append(aStartB);
                     aLineB.append(aEndB);
                     
aLineB.transform(rViewInformation.getInverseObjectToViewTransformation());
-                    rContainer.push_back(new 
PolygonMarkerPrimitive2D(std::move(aLineB), getRGBColA(), getRGBColB(), 
getDiscreteDashLength()));
+                    auto xMarker2 = new 
PolygonMarkerPrimitive2D(std::move(aLineB), getRGBColA(), getRGBColB(), 
getDiscreteDashLength());
 
+                    xRet = new GroupPrimitive2D(Primitive2DContainer{xMarker1, 
xMarker2});
                     break;
                 }
                 case HelplineStyle2D::Line :
@@ -106,18 +108,20 @@ namespace drawinglayer::primitive2d
                     {
                         // clip against visible area
                         const basegfx::B2DPolyPolygon 
aResult(basegfx::utils::clipPolygonOnRange(aLine, 
rViewInformation.getDiscreteViewport(), true, true));
-
+                        Primitive2DContainer aContainer;
                         for(sal_uInt32 a(0); a < aResult.count(); a++)
                         {
                             basegfx::B2DPolygon 
aPart(aResult.getB2DPolygon(a));
                             
aPart.transform(rViewInformation.getInverseObjectToViewTransformation());
-                            rContainer.push_back(new 
PolygonMarkerPrimitive2D(std::move(aPart), getRGBColA(), getRGBColB(), 
getDiscreteDashLength()));
+                            aContainer.push_back(new 
PolygonMarkerPrimitive2D(std::move(aPart), getRGBColA(), getRGBColB(), 
getDiscreteDashLength()));
                         }
+                        xRet = new GroupPrimitive2D(std::move(aContainer));
                     }
 
                     break;
                 }
             }
+            return xRet;
         }
 
         HelplinePrimitive2D::HelplinePrimitive2D(
@@ -155,16 +159,16 @@ namespace drawinglayer::primitive2d
 
         void 
HelplinePrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& 
rVisitor, const geometry::ViewInformation2D& rViewInformation) const
         {
-            if(!getBuffered2DDecomposition().empty())
+            if(getBuffered2DDecomposition())
             {
                 if(maLastViewport != rViewInformation.getViewport() || 
maLastObjectToViewTransformation != 
rViewInformation.getObjectToViewTransformation())
                 {
                     // conditions of last local decomposition have changed, 
delete
-                    const_cast< HelplinePrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                    const_cast< HelplinePrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
                 }
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember ViewRange and ViewTransformation
                 const_cast< HelplinePrimitive2D* 
>(this)->maLastObjectToViewTransformation = 
rViewInformation.getObjectToViewTransformation();
diff --git a/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx 
b/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx
index 62d1cd5c26ca..1702b16496d8 100644
--- a/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx
@@ -22,6 +22,7 @@
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
 
 
@@ -30,19 +31,19 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void 
MarkerArrayPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, 
const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference 
MarkerArrayPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             const std::vector< basegfx::B2DPoint >& rPositions = 
getPositions();
             const sal_uInt32 nMarkerCount(rPositions.size());
 
             if(!nMarkerCount || getMarker().IsEmpty())
-                return;
+                return nullptr;
 
             // get pixel size
             Size aBitmapSize(getMarker().GetSizePixel());
 
             if(!(aBitmapSize.Width() && aBitmapSize.Height()))
-                return;
+                return nullptr;
 
             // get logic half pixel size
             basegfx::B2DVector 
aLogicHalfSize(rViewInformation.getInverseObjectToViewTransformation() *
@@ -51,6 +52,7 @@ namespace drawinglayer::primitive2d
             // use half size for expand
             aLogicHalfSize *= 0.5;
 
+            Primitive2DContainer aContainer;
             for(const auto& rPosition : rPositions)
             {
                 const basegfx::B2DRange aRange(rPosition - aLogicHalfSize, 
rPosition + aLogicHalfSize);
@@ -61,11 +63,12 @@ namespace drawinglayer::primitive2d
                 aTransform.set(0, 2, aRange.getMinX());
                 aTransform.set(1, 2, aRange.getMinY());
 
-                rContainer.push_back(
+                aContainer.push_back(
                     new BitmapPrimitive2D(
                         getMarker(),
                         aTransform));
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         MarkerArrayPrimitive2D::MarkerArrayPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/mediaprimitive2d.cxx 
b/drawinglayer/source/primitive2d/mediaprimitive2d.cxx
index c9a1ef6e1645..eb70c7602c8c 100644
--- a/drawinglayer/source/primitive2d/mediaprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/mediaprimitive2d.cxx
@@ -32,7 +32,7 @@
 
 namespace drawinglayer::primitive2d
 {
-        void MediaPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference MediaPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             Primitive2DContainer xRetval;
             xRetval.resize(1);
@@ -89,7 +89,7 @@ namespace drawinglayer::primitive2d
                 }
             }
 
-            rContainer.append(std::move(xRetval));
+            return new GroupPrimitive2D(std::move(xRetval));
         }
 
         MediaPrimitive2D::MediaPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx 
b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index 67f9fcdad4d3..46ddf6582571 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -31,14 +31,14 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void MetafilePrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference MetafilePrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             // Interpret the Metafile and get the content. There should be 
only one target, as in the start condition,
             // but iterating will be the right thing to do when some push/pop 
is not closed
             Primitive2DContainer 
xRetval(wmfemfhelper::interpretMetafile(getMetaFile(), rViewInformation));
 
             if(xRetval.empty())
-                return;
+                return nullptr;
 
             // get target size
             const ::tools::Rectangle 
aMtfTarget(getMetaFile().GetPrefMapMode().GetOrigin(), 
getMetaFile().GetPrefSize());
@@ -81,9 +81,7 @@ namespace drawinglayer::primitive2d
                     aAdaptedTransform,
                     std::move(xRetval)));
 
-            xRetval = Primitive2DContainer { aEmbeddedTransform };
-
-            rContainer.append(std::move(xRetval));
+            return aEmbeddedTransform;
         }
 
         MetafilePrimitive2D::MetafilePrimitive2D(
diff --git a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx 
b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx
index 7e274e78e9c1..447be709185e 100644
--- a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx
@@ -32,14 +32,14 @@ using namespace com::sun::star;
 
 namespace drawinglayer::primitive2d
 {
-        void 
PagePreviewPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, 
const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference 
PagePreviewPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             Primitive2DContainer aContent(getPageContent());
 
             if(!(!aContent.empty()
                 && basegfx::fTools::more(getContentWidth(), 0.0)
                 && basegfx::fTools::more(getContentHeight(), 0.0)))
-                return;
+                return nullptr;
 
             // the decomposed matrix will be needed
             basegfx::B2DVector aScale, aTranslate;
@@ -47,7 +47,7 @@ namespace drawinglayer::primitive2d
             getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
 
             if(!(basegfx::fTools::more(aScale.getX(), 0.0) && 
basegfx::fTools::more(aScale.getY(), 0.0)))
-                return;
+                return nullptr;
 
             // check if content overlaps with target size and needs to be 
embedded with a
             // clipping primitive
@@ -98,7 +98,7 @@ namespace drawinglayer::primitive2d
             aPageTrans = aCombined * aPageTrans;
 
             // embed in necessary transformation to map from SdrPage to 
SdrPageObject
-            rContainer.push_back(new TransformPrimitive2D(aPageTrans, 
std::move(aContent)));
+            return new TransformPrimitive2D(aPageTrans, std::move(aContent));
         }
 
         PagePreviewPrimitive2D::PagePreviewPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx 
b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
index 627de80eec16..516b0042d960 100644
--- a/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/patternfillprimitive2d.cxx
@@ -202,20 +202,20 @@ namespace drawinglayer::primitive2d
                         nWidth * nHeight);
         }
 
-        void 
PatternFillPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, 
const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference 
PatternFillPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
             Primitive2DContainer aRetval;
 
             if(getChildren().empty())
-                return;
+                return nullptr;
 
             if(!(!getReferenceRange().isEmpty() && 
getReferenceRange().getWidth() > 0.0 && getReferenceRange().getHeight() > 0.0))
-                return;
+                return nullptr;
 
             const basegfx::B2DRange aMaskRange(getMask().getB2DRange());
 
             if(!(!aMaskRange.isEmpty() && aMaskRange.getWidth() > 0.0 && 
aMaskRange.getHeight() > 0.0))
-                return;
+                return nullptr;
 
             // create tiling matrices
             std::vector< basegfx::B2DHomMatrix > aMatrices;
@@ -252,10 +252,10 @@ namespace drawinglayer::primitive2d
             }
 
             // embed result in mask
-            rContainer.push_back(
+            return
                 new MaskPrimitive2D(
                     getMask(),
-                    std::move(aRetval)));
+                    std::move(aRetval));
         }
 
         PatternFillPrimitive2D::PatternFillPrimitive2D(
@@ -341,7 +341,7 @@ namespace drawinglayer::primitive2d
                 PatternFillPrimitive2D* pThat = const_cast< 
PatternFillPrimitive2D* >(this);
                 pThat->mnDiscreteWidth = nW;
                 pThat->mnDiscreteHeight = nH;
-                pThat->setBuffered2DDecomposition(Primitive2DContainer());
+                pThat->setBuffered2DDecomposition(nullptr);
             }
 
             // call parent
diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx 
b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
index 435408cd5846..ab6833a44ffa 100644
--- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -26,6 +26,7 @@
 #include <drawinglayer/primitive2d/PolygonWavePrimitive2D.hxx>
 #include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <basegfx/polygon/b2dlinegeometry.hxx>
 #include <com/sun/star/drawing/LineCap.hpp>
@@ -207,8 +208,8 @@ void LineRectanglePrimitive2D::get2DDecomposition(
     rVisitor.visit(aSequence);
 }
 
-void PolygonMarkerPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
rViewInformation) const
+Primitive2DReference PolygonMarkerPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& rViewInformation) const
 {
     // calculate logic DashLength
     const basegfx::B2DVector 
aDashVector(rViewInformation.getInverseObjectToViewTransformation()
@@ -227,14 +228,16 @@ void PolygonMarkerPrimitive2D::create2DDecomposition(
         basegfx::utils::applyLineDashing(getB2DPolygon(), aDash, 
&aDashedPolyPolyA,
                                          &aDashedPolyPolyB, 2.0 * 
fLogicDashLength);
 
-        rContainer.push_back(
+        Primitive2DContainer aContainer;
+        aContainer.push_back(
             new PolyPolygonHairlinePrimitive2D(std::move(aDashedPolyPolyA), 
getRGBColorA()));
-        rContainer.push_back(
+        aContainer.push_back(
             new PolyPolygonHairlinePrimitive2D(std::move(aDashedPolyPolyB), 
getRGBColorB()));
+        return new GroupPrimitive2D(std::move(aContainer));
     }
     else
     {
-        rContainer.push_back(new PolygonHairlinePrimitive2D(getB2DPolygon(), 
getRGBColorA()));
+        return new PolygonHairlinePrimitive2D(getB2DPolygon(), getRGBColorA());
     }
 }
 
@@ -295,7 +298,7 @@ void PolygonMarkerPrimitive2D::get2DDecomposition(
 {
     bool bNeedNewDecomposition(false);
 
-    if (!getBuffered2DDecomposition().empty())
+    if (getBuffered2DDecomposition())
     {
         if (rViewInformation.getInverseObjectToViewTransformation()
             != maLastInverseObjectToViewTransformation)
@@ -307,11 +310,10 @@ void PolygonMarkerPrimitive2D::get2DDecomposition(
     if (bNeedNewDecomposition)
     {
         // conditions of last local decomposition have changed, delete
-        
const_cast<PolygonMarkerPrimitive2D*>(this)->setBuffered2DDecomposition(
-            Primitive2DContainer());
+        
const_cast<PolygonMarkerPrimitive2D*>(this)->setBuffered2DDecomposition(nullptr);
     }
 
-    if (getBuffered2DDecomposition().empty())
+    if (!getBuffered2DDecomposition())
     {
         // remember last used InverseObjectToViewTransformation
         PolygonMarkerPrimitive2D* pThat = 
const_cast<PolygonMarkerPrimitive2D*>(this);
@@ -333,11 +335,11 @@ sal_uInt32 PolygonMarkerPrimitive2D::getPrimitive2DID() 
const
 
 namespace drawinglayer::primitive2d
 {
-void PolygonStrokePrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolygonStrokePrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     if (!getB2DPolygon().count())
-        return;
+        return nullptr;
 
     // #i102241# try to simplify before usage
     const basegfx::B2DPolygon 
aB2DPolygon(basegfx::utils::simplifyCurveSegments(getB2DPolygon()));
@@ -377,6 +379,7 @@ void PolygonStrokePrimitive2D::create2DDecomposition(
         }
 
         // create primitive
+        Primitive2DContainer aContainer;
         for (sal_uInt32 b(0); b < aAreaPolyPolygon.count(); b++)
         {
             // put into single polyPolygon primitives to make clear that this 
is NOT meant
@@ -384,14 +387,15 @@ void PolygonStrokePrimitive2D::create2DDecomposition(
             // melting process may be used here one day.
             basegfx::B2DPolyPolygon 
aNewPolyPolygon(aAreaPolyPolygon.getB2DPolygon(b));
             const basegfx::BColor aColor(getLineAttribute().getColor());
-            rContainer.push_back(
+            aContainer.push_back(
                 new PolyPolygonColorPrimitive2D(std::move(aNewPolyPolygon), 
aColor));
         }
+        return new GroupPrimitive2D(std::move(aContainer));
     }
     else
     {
-        rContainer.push_back(new 
PolyPolygonHairlinePrimitive2D(std::move(aHairLinePolyPolygon),
-                                                                
getLineAttribute().getColor()));
+        return new 
PolyPolygonHairlinePrimitive2D(std::move(aHairLinePolyPolygon),
+                                                  
getLineAttribute().getColor());
     }
 }
 
@@ -594,11 +598,11 @@ sal_uInt32 PolygonStrokePrimitive2D::getPrimitive2DID() 
const
     return PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D;
 }
 
-void PolygonWavePrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolygonWavePrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     if (!getB2DPolygon().count())
-        return;
+        return nullptr;
 
     const bool bHasWidth(!basegfx::fTools::equalZero(getWaveWidth()));
     const bool bHasHeight(!basegfx::fTools::equalZero(getWaveHeight()));
@@ -608,14 +612,14 @@ void PolygonWavePrimitive2D::create2DDecomposition(
         // create waveline curve
         basegfx::B2DPolygon aWaveline(
             basegfx::utils::createWaveline(getB2DPolygon(), getWaveWidth(), 
getWaveHeight()));
-        rContainer.push_back(new 
PolygonStrokePrimitive2D(std::move(aWaveline), getLineAttribute(),
-                                                          
getStrokeAttribute()));
+        return new PolygonStrokePrimitive2D(std::move(aWaveline), 
getLineAttribute(),
+                                            getStrokeAttribute());
     }
     else
     {
         // flat waveline, decompose to simple line primitive
-        rContainer.push_back(new PolygonStrokePrimitive2D(getB2DPolygon(), 
getLineAttribute(),
-                                                          
getStrokeAttribute()));
+        return new PolygonStrokePrimitive2D(getB2DPolygon(), 
getLineAttribute(),
+                                            getStrokeAttribute());
     }
 }
 
@@ -697,8 +701,8 @@ sal_uInt32 PolygonWavePrimitive2D::getPrimitive2DID() const
     return PRIMITIVE2D_ID_POLYGONWAVEPRIMITIVE2D;
 }
 
-void PolygonStrokeArrowPrimitive2D::create2DDecomposition(
-    Primitive2DContainer& rContainer, const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+Primitive2DReference PolygonStrokeArrowPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
 {
     // copy local polygon, it may be changed
     basegfx::B2DPolygon aLocalPolygon(getB2DPolygon());
@@ -748,20 +752,22 @@ void PolygonStrokeArrowPrimitive2D::create2DDecomposition(
     }
 
     // add shaft
-    rContainer.push_back(new 
PolygonStrokePrimitive2D(std::move(aLocalPolygon), getLineAttribute(),
+    Primitive2DContainer aContainer;
+    aContainer.push_back(new 
PolygonStrokePrimitive2D(std::move(aLocalPolygon), getLineAttribute(),
                                                       getStrokeAttribute()));
 
     if (aArrowA.count())
     {
-        rContainer.push_back(
+        aContainer.push_back(
             new PolyPolygonColorPrimitive2D(std::move(aArrowA), 
getLineAttribute().getColor()));
     }
 
     if (aArrowB.count())
     {
-        rContainer.push_back(
+        aContainer.push_back(
             new PolyPolygonColorPrimitive2D(std::move(aArrowB), 
getLineAttribute().getColor()));
     }
+    return new GroupPrimitive2D(std::move(aContainer));
 }
 
 PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/primitivetools2d.cxx 
b/drawinglayer/source/primitive2d/primitivetools2d.cxx
index 7c6d426e95a2..04a91fe9b55b 100644
--- a/drawinglayer/source/primitive2d/primitivetools2d.cxx
+++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx
@@ -30,13 +30,13 @@ namespace drawinglayer::primitive2d
             const basegfx::B2DVector 
aDiscreteVector(rViewInformation.getInverseObjectToViewTransformation() * 
basegfx::B2DVector(1.0, 1.0));
             const double fDiscreteUnit(std::min(fabs(aDiscreteVector.getX()), 
fabs(aDiscreteVector.getY())));
 
-            if(!getBuffered2DDecomposition().empty() && 
!basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit()))
+            if(getBuffered2DDecomposition() && 
!basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit()))
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< DiscreteMetricDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< DiscreteMetricDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember new valid DiscreteUnit
                 const_cast< DiscreteMetricDependentPrimitive2D* 
>(this)->mfDiscreteUnit = fDiscreteUnit;
@@ -54,13 +54,13 @@ namespace drawinglayer::primitive2d
             // get the current Viewport
             const basegfx::B2DRange& rViewport = 
rViewInformation.getViewport();
 
-            if(!getBuffered2DDecomposition().empty() && 
!rViewport.equal(getViewport()))
+            if(getBuffered2DDecomposition() && !rViewport.equal(getViewport()))
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< ViewportDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< ViewportDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember new valid DiscreteUnit
                 const_cast< ViewportDependentPrimitive2D* >(this)->maViewport 
= rViewport;
@@ -75,13 +75,13 @@ namespace drawinglayer::primitive2d
             // get the current ViewTransformation
             const basegfx::B2DHomMatrix& rViewTransformation = 
rViewInformation.getViewTransformation();
 
-            if(!getBuffered2DDecomposition().empty() && rViewTransformation != 
getViewTransformation())
+            if(getBuffered2DDecomposition() && rViewTransformation != 
getViewTransformation())
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< ViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< ViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember new valid ViewTransformation
                 const_cast< ViewTransformationDependentPrimitive2D* 
>(this)->maViewTransformation = rViewTransformation;
@@ -96,22 +96,22 @@ namespace drawinglayer::primitive2d
             // get the current ViewTransformation
             const basegfx::B2DHomMatrix& rViewTransformation = 
rViewInformation.getViewTransformation();
 
-            if(!getBuffered2DDecomposition().empty() && rViewTransformation != 
getViewTransformation())
+            if(getBuffered2DDecomposition() && rViewTransformation != 
getViewTransformation())
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
             // get the current ObjectTransformation
             const basegfx::B2DHomMatrix& rObjectTransformation = 
rViewInformation.getObjectTransformation();
 
-            if(!getBuffered2DDecomposition().empty() && rObjectTransformation 
!= getObjectTransformation())
+            if(getBuffered2DDecomposition() && rObjectTransformation != 
getObjectTransformation())
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 // remember new valid ViewTransformation, and 
ObjectTransformation
                 const_cast< ObjectAndViewTransformationDependentPrimitive2D* 
>(this)->maViewTransformation = rViewTransformation;
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx 
b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index 8a6943a83924..5dac8e5c7223 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -24,6 +24,7 @@
 #include <drawinglayer/attribute/sdrlightattribute3d.hxx>
 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
 #include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
 #include <processor3d/zbufferprocessor3d.hxx>
 #include <processor3d/shadow3dextractor.hxx>
 #include <drawinglayer/geometry/viewinformation2d.hxx>
@@ -212,8 +213,9 @@ namespace drawinglayer::primitive2d
             }
         }
 
-        void ScenePrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& rViewInformation) const
+        Primitive2DReference ScenePrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
+            Primitive2DContainer aContainer;
             // create 2D shadows from contained 3D primitives. This creates 
the shadow primitives on demand and tells if
             // there are some or not. Do this at start, the shadow might still 
be visible even when the scene is not
             if(impGetShadow3D())
@@ -226,7 +228,7 @@ namespace drawinglayer::primitive2d
                 if(aViewRange.isEmpty() || aShadow2DRange.overlaps(aViewRange))
                 {
                     // add extracted 2d shadows (before 3d scene creations 
itself)
-                    rContainer.append(maShadowPrimitives);
+                    aContainer.append(maShadowPrimitives);
                 }
             }
 
@@ -238,7 +240,7 @@ namespace drawinglayer::primitive2d
             calculateDiscreteSizes(rViewInformation, aDiscreteRange, 
aVisibleDiscreteRange, aUnitVisibleRange);
 
             if(aVisibleDiscreteRange.isEmpty())
-                return;
+                return new GroupPrimitive2D(std::move(aContainer));
 
             // test if discrete view size (pixel) maybe too big and limit it
             double fViewSizeX(aVisibleDiscreteRange.getWidth());
@@ -412,7 +414,7 @@ namespace drawinglayer::primitive2d
             }
 
             if(!(nRasterWidth && nRasterHeight))
-                return;
+                return new GroupPrimitive2D(std::move(aContainer));
 
             // create view unit buffer
             basegfx::BZPixelRaster aBZPixelRaster(
@@ -508,7 +510,7 @@ namespace drawinglayer::primitive2d
             const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
 
             if(!(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight()))
-                return;
+                return new GroupPrimitive2D(std::move(aContainer));
 
             // create transform for the created bitmap in discrete coordinates 
first.
             basegfx::B2DHomMatrix aNew2DTransform;
@@ -522,7 +524,7 @@ namespace drawinglayer::primitive2d
             aNew2DTransform *= aInverseOToV;
 
             // create bitmap primitive and add
-            rContainer.push_back(
+            aContainer.push_back(
                 new BitmapPrimitive2D(
                     maOldRenderedBitmap,
                     aNew2DTransform));
@@ -534,8 +536,9 @@ namespace drawinglayer::primitive2d
             {
                 basegfx::B2DPolygon 
aOutline(basegfx::utils::createUnitPolygon());
                 aOutline.transform(aNew2DTransform);
-                rContainer.push_back(new 
PolygonHairlinePrimitive2D(std::move(aOutline), basegfx::BColor(1.0, 0.0, 
0.0)));
+                aContainer.push_back(new 
PolygonHairlinePrimitive2D(std::move(aOutline), basegfx::BColor(1.0, 0.0, 
0.0)));
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         Primitive2DContainer ScenePrimitive2D::getGeometry2D() const
@@ -684,7 +687,7 @@ namespace drawinglayer::primitive2d
             bool bNeedNewDecomposition(false);
             bool bDiscreteSizesAreCalculated(false);
 
-            if(!getBuffered2DDecomposition().empty())
+            if(getBuffered2DDecomposition())
             {
                 basegfx::B2DRange aVisibleDiscreteRange;
                 calculateDiscreteSizes(rViewInformation, aDiscreteRange, 
aVisibleDiscreteRange, aUnitVisibleRange);
@@ -712,10 +715,10 @@ namespace drawinglayer::primitive2d
             if(bNeedNewDecomposition)
             {
                 // conditions of last local decomposition have changed, delete
-                const_cast< ScenePrimitive2D* 
>(this)->setBuffered2DDecomposition(Primitive2DContainer());
+                const_cast< ScenePrimitive2D* 
>(this)->setBuffered2DDecomposition(nullptr);
             }
 
-            if(getBuffered2DDecomposition().empty())
+            if(!getBuffered2DDecomposition())
             {
                 if(!bDiscreteSizesAreCalculated)
                 {
diff --git a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx 
b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
index 6670ba22b5c3..1bf263a50f71 100644
--- a/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
@@ -63,7 +63,7 @@ namespace
 
 namespace drawinglayer::primitive2d
 {
-        void 
SvgGradientHelper::createSingleGradientEntryFill(Primitive2DContainer& 
rContainer) const
+        Primitive2DReference 
SvgGradientHelper::createSingleGradientEntryFill() const
         {
             const SvgGradientEntryVector& rEntries = getGradientEntries();
             const sal_uInt32 nCount(rEntries.size());
@@ -90,13 +90,14 @@ namespace drawinglayer::primitive2d
                                 1.0 - fOpacity);
                     }
 
-                    rContainer.push_back(xRef);
+                    return xRef;
                 }
             }
             else
             {
                 OSL_ENSURE(false, "Single gradient entry construction without 
entry (!)");
             }
+            return nullptr;
         }
 
         void SvgGradientHelper::checkPreconditions()
@@ -305,8 +306,7 @@ namespace drawinglayer::primitive2d
             }
         }
 
-        void SvgGradientHelper::createResult(
-            Primitive2DContainer& rContainer,
+        Primitive2DReference SvgGradientHelper::createResult(
             Primitive2DContainer aTargetColor,
             Primitive2DContainer aTargetOpacity,
             const basegfx::B2DHomMatrix& rUnitGradientToObject,
@@ -316,7 +316,7 @@ namespace drawinglayer::primitive2d
             Primitive2DContainer 
aTargetOpacityEntries(aTargetOpacity.maybeInvert(bInvert));
 
             if(aTargetColorEntries.empty())
-                return;
+                return nullptr;
 
             Primitive2DReference xRefContent;
 
@@ -337,9 +337,9 @@ namespace drawinglayer::primitive2d
                     std::move(aTargetColorEntries));
             }
 
-            rContainer.push_back(new MaskPrimitive2D(
+            return new MaskPrimitive2D(
                 getPolyPolygon(),
-                Primitive2DContainer { xRefContent }));
+                Primitive2DContainer { xRefContent });
         }
 
         SvgGradientHelper::SvgGradientHelper(
@@ -466,7 +466,7 @@ namespace drawinglayer::primitive2d
             }
         }
 
-        void 
SvgLinearGradientPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
SvgLinearGradientPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             if(!getPreconditionsChecked())
             {
@@ -476,7 +476,7 @@ namespace drawinglayer::primitive2d
             if(getSingleEntry())
             {
                 // fill with last existing color
-                createSingleGradientEntryFill(rContainer);
+                return createSingleGradientEntryFill();
             }
             else if(getCreatesContent())
             {
@@ -556,8 +556,9 @@ namespace drawinglayer::primitive2d
                         aUnitRange.getMaxX());
                 }
 
-                createResult(rContainer, std::move(aTargetColor), 
std::move(aTargetOpacity), aUnitGradientToObject);
+                return createResult(std::move(aTargetColor), 
std::move(aTargetOpacity), aUnitGradientToObject);
             }
+            return nullptr;
         }
 
         SvgLinearGradientPrimitive2D::SvgLinearGradientPrimitive2D(
@@ -688,7 +689,7 @@ namespace drawinglayer::primitive2d
             }
         }
 
-        void 
SvgRadialGradientPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
SvgRadialGradientPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             if(!getPreconditionsChecked())
             {
@@ -698,7 +699,7 @@ namespace drawinglayer::primitive2d
             if(getSingleEntry())
             {
                 // fill with last existing color
-                createSingleGradientEntryFill(rContainer);
+                return createSingleGradientEntryFill();
             }
             else if(getCreatesContent())
             {
@@ -782,8 +783,9 @@ namespace drawinglayer::primitive2d
                         fMax);
                 }
 
-                createResult(rContainer, std::move(aTargetColor), 
std::move(aTargetOpacity), aUnitGradientToObject, true);
+                return createResult(std::move(aTargetColor), 
std::move(aTargetOpacity), aUnitGradientToObject, true);
             }
+            return nullptr;
         }
 
         SvgRadialGradientPrimitive2D::SvgRadialGradientPrimitive2D(
@@ -860,12 +862,12 @@ namespace drawinglayer::primitive2d
 
 namespace drawinglayer::primitive2d
 {
-        void 
SvgLinearAtomPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
SvgLinearAtomPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             const double fDelta(getOffsetB() - getOffsetA());
 
             if(basegfx::fTools::equalZero(fDelta))
-                return;
+                return nullptr;
 
             // use one discrete unit for overlap (one pixel)
             const double fDiscreteUnit(getDiscreteUnit());
@@ -899,15 +901,18 @@ namespace drawinglayer::primitive2d
             double fUnitScale(0.0);
             const double fUnitStep(1.0 / nSteps);
 
+            Primitive2DContainer aContainer;
+            aContainer.resize(nSteps);
             for(sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep)
             {
                 basegfx::B2DPolygon aNew(aPolygon);
 
                 
aNew.transform(basegfx::utils::createTranslateB2DHomMatrix(fDelta * fUnitScale, 
0.0));
-                rContainer.push_back(new PolyPolygonColorPrimitive2D(
+                aContainer[a] = new PolyPolygonColorPrimitive2D(
                     basegfx::B2DPolyPolygon(aNew),
-                    basegfx::interpolate(getColorA(), getColorB(), 
fUnitScale)));
+                    basegfx::interpolate(getColorA(), getColorB(), 
fUnitScale));
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         SvgLinearAtomPrimitive2D::SvgLinearAtomPrimitive2D(
@@ -953,12 +958,12 @@ namespace drawinglayer::primitive2d
 
 namespace drawinglayer::primitive2d
 {
-        void 
SvgRadialAtomPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
SvgRadialAtomPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             const double fDeltaScale(getScaleB() - getScaleA());
 
             if(basegfx::fTools::equalZero(fDeltaScale))
-                return;
+                return nullptr;
 
             // use one discrete unit for overlap (one pixel)
             const double fDiscreteUnit(getDiscreteUnit());
@@ -970,6 +975,8 @@ namespace drawinglayer::primitive2d
             double fUnitScale(0.0);
             const double fUnitStep(1.0 / nSteps);
 
+            Primitive2DContainer aContainer;
+            aContainer.resize(nSteps);
             for(sal_uInt32 a(0); a < nSteps; a++, fUnitScale += fUnitStep)
             {
                 basegfx::B2DHomMatrix aTransform;
@@ -999,10 +1006,11 @@ namespace drawinglayer::primitive2d
                 basegfx::B2DPolygon 
aNew(basegfx::utils::createPolygonFromUnitCircle());
 
                 aNew.transform(aTransform);
-                rContainer.push_back(new PolyPolygonColorPrimitive2D(
+                aContainer[a] = new PolyPolygonColorPrimitive2D(
                     basegfx::B2DPolyPolygon(aNew),
-                    basegfx::interpolate(getColorB(), getColorA(), 
fUnitScale)));
+                    basegfx::interpolate(getColorB(), getColorA(), 
fUnitScale));
             }
+            return new GroupPrimitive2D(std::move(aContainer));
         }
 
         SvgRadialAtomPrimitive2D::SvgRadialAtomPrimitive2D(
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx 
b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
index 5498b2124bc9..07181bbf2a17 100644
--- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -164,7 +164,7 @@ namespace drawinglayer::primitive2d
             // TODO: Handle Font Emphasis Above/Below
         }
 
-        void 
TextDecoratedPortionPrimitive2D::create2DDecomposition(Primitive2DContainer& 
rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
+        Primitive2DReference 
TextDecoratedPortionPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& /*rViewInformation*/) const
         {
             if(getWordLineMode())
             {
@@ -176,8 +176,7 @@ namespace drawinglayer::primitive2d
                 if(!aBroken.empty())
                 {
                     // was indeed split to several words, use as result
-                    rContainer.append(std::move(aBroken));
-                    return;
+                    return new GroupPrimitive2D(std::move(aBroken));
                 }
                 else
                 {
@@ -207,68 +206,57 @@ namespace drawinglayer::primitive2d
             impCreateGeometryContent(aRetval, aDecTrans, getText(), 
getTextPosition(), getTextLength(), getDXArray(), getKashidaArray(), 
aNewFontAttribute);
 
             // Handle Shadow, Outline and TextRelief
-            if(!aRetval.empty())
+            if(aRetval.empty())
+                return nullptr;
+
+            // outline AND shadow depend on NO TextRelief (see dialog)
+            const bool bHasTextRelief(TEXT_RELIEF_NONE != getTextRelief());
+            const bool bHasShadow(!bHasTextRelief && getShadow());
+            const bool bHasOutline(!bHasTextRelief && 
getFontAttribute().getOutline());
+
+            if(bHasShadow || bHasTextRelief || bHasOutline)
             {
-                // outline AND shadow depend on NO TextRelief (see dialog)
-                const bool bHasTextRelief(TEXT_RELIEF_NONE != getTextRelief());
-                const bool bHasShadow(!bHasTextRelief && getShadow());
-                const bool bHasOutline(!bHasTextRelief && 
getFontAttribute().getOutline());
+                Primitive2DReference aShadow;
 
-                if(bHasShadow || bHasTextRelief || bHasOutline)
+                if(bHasShadow)
                 {
-                    Primitive2DReference aShadow;
+                    // create shadow with current content (in aRetval). Text 
shadow
+                    // is constant, relative to font size, rotated with the 
text and has a
+                    // constant color.
+                    // shadow parameter values
+                    static const double fFactor(1.0 / 24.0);
+                    const double fTextShadowOffset(aDecTrans.getScale().getY() 
* fFactor);
+                    static basegfx::BColor aShadowColor(0.3, 0.3, 0.3);
+
+                    // prepare shadow transform matrix
+                    const basegfx::B2DHomMatrix 
aShadowTransform(basegfx::utils::createTranslateB2DHomMatrix(
+                        fTextShadowOffset, fTextShadowOffset));
+
+                    // create shadow primitive
+                    aShadow = new ShadowPrimitive2D(
+                        aShadowTransform,
+                        aShadowColor,
+                        0,          // fShadowBlur = 0, there's no blur for 
text shadow yet.
+                        Primitive2DContainer(aRetval));
+                }
 
-                    if(bHasShadow)
-                    {
-                        // create shadow with current content (in aRetval). 
Text shadow
-                        // is constant, relative to font size, rotated with 
the text and has a
-                        // constant color.
-                        // shadow parameter values
-                        static const double fFactor(1.0 / 24.0);
-                        const double 
fTextShadowOffset(aDecTrans.getScale().getY() * fFactor);
-                        static basegfx::BColor aShadowColor(0.3, 0.3, 0.3);
-
-                        // prepare shadow transform matrix
-                        const basegfx::B2DHomMatrix 
aShadowTransform(basegfx::utils::createTranslateB2DHomMatrix(
-                            fTextShadowOffset, fTextShadowOffset));
-
-                        // create shadow primitive
-                        aShadow = new ShadowPrimitive2D(
-                            aShadowTransform,
-                            aShadowColor,
-                            0,          // fShadowBlur = 0, there's no blur 
for text shadow yet.
-                            Primitive2DContainer(aRetval));
-                    }
+                if(bHasTextRelief)
+                {
+                    // create emboss using an own helper primitive since this 
will
+                    // be view-dependent
+                    const basegfx::BColor aBBlack(0.0, 0.0, 0.0);
+                    const bool bDefaultTextColor(aBBlack == getFontColor());
+                    TextEffectStyle2D 
aTextEffectStyle2D(TextEffectStyle2D::ReliefEmbossed);
 
-                    if(bHasTextRelief)
+                    if(bDefaultTextColor)
                     {
-                        // create emboss using an own helper primitive since 
this will
-                        // be view-dependent
-                        const basegfx::BColor aBBlack(0.0, 0.0, 0.0);
-                        const bool bDefaultTextColor(aBBlack == 
getFontColor());
-                        TextEffectStyle2D 
aTextEffectStyle2D(TextEffectStyle2D::ReliefEmbossed);
-
-                        if(bDefaultTextColor)
+                        if(TEXT_RELIEF_ENGRAVED == getTextRelief())
                         {
-                            if(TEXT_RELIEF_ENGRAVED == getTextRelief())
-                            {
-                                aTextEffectStyle2D = 
TextEffectStyle2D::ReliefEngravedDefault;
-                            }
-                            else
-                            {
-                                aTextEffectStyle2D = 
TextEffectStyle2D::ReliefEmbossedDefault;
-                            }
+                            aTextEffectStyle2D = 
TextEffectStyle2D::ReliefEngravedDefault;
                         }
                         else
                         {
-                            if(TEXT_RELIEF_ENGRAVED == getTextRelief())
-                            {
-                                aTextEffectStyle2D = 
TextEffectStyle2D::ReliefEngraved;
-                            }
-                            else
-                            {
-                                aTextEffectStyle2D = 
TextEffectStyle2D::ReliefEmbossed;
-                            }
+                            aTextEffectStyle2D = 
TextEffectStyle2D::ReliefEmbossedDefault;
                         }
 
                         aRetval = Primitive2DContainer {
@@ -279,7 +267,7 @@ namespace drawinglayer::primitive2d
                                 aTextEffectStyle2D)
                          };
                     }
-                    else if(bHasOutline)
+                    else
                     {
                         // create outline using an own helper primitive since 
this will
-e 
... etc. - the rest is truncated

Reply via email to