fix for crash converting ooo31011-1.sxw and tdf#146132

./instdir/program/soffice.bin --headless --convert-to odt
./ooo31011-1.sxw

regression from
    commit 681e10eecf67a1a01bdec2cc9b834e0345e25206
    Author: Noel Grandin <noel.grandin@collabora.co.uk>
    Date:   Thu Dec 9 11:12:49 2021 +0200
    tdf#146137 tdf#146132 image redrawing

It is because we cache high-level primitives, and then during paint, we
decompose those high-level primitives, and that triggers layout,
which triggers an invalidate i.e. an ActionChanged(), which blows
away the cached data we are iterating over.

Change-Id: Id18e47b6c2b71a5404f24b075a43d2040a5e3509
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126995
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/include/svx/sdr/contact/viewobjectcontact.hxx b/include/svx/sdr/contact/viewobjectcontact.hxx
index f13f247..7cee496 100644
--- a/include/svx/sdr/contact/viewobjectcontact.hxx
+++ b/include/svx/sdr/contact/viewobjectcontact.hxx
@@ -59,6 +59,9 @@ private:
    // possible on-demand calculated GridOffset for non-linear ViewToDevice transformation (calc)
    basegfx::B2DVector                              maGridOffset;

    // used to to detect ActionChanged() during primitive construction
    int                                             mnActionChangedCount;

    // This bool gets set when the object gets invalidated by ActionChanged() and
    // can be used from the OC to late-invalidates
    bool                                            mbLazyInvalidate : 1;
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx
index 9dcac9e..8b8f0c3 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -147,6 +147,7 @@ ViewObjectContact::ViewObjectContact(ObjectContact& rObjectContact, ViewContact&
:   mrObjectContact(rObjectContact),
    mrViewContact(rViewContact),
    maGridOffset(0.0, 0.0),
    mnActionChangedCount(0),
    mbLazyInvalidate(false)
{
    // make the ViewContact remember me
@@ -210,6 +211,7 @@ void ViewObjectContact::ActionChanged()
{
    // clear cached primitives
    mxPrimitive2DSequence.clear();
    ++mnActionChangedCount;

    if(mbLazyInvalidate)
        return;
@@ -345,7 +347,7 @@ drawinglayer::primitive2d::Primitive2DContainer const & ViewObjectContact::getPr
    drawinglayer::primitive2d::Primitive2DContainer xNewPrimitiveSequence;

    // take care of redirectors and create new list
    ViewObjectContactRedirector* pRedirector = GetObjectContact().GetViewObjectContactRedirector();
    ViewObjectContactRedirector* pRedirector = GetObjectContact().GetViewObjectContactRedirector();\

    if(pRedirector)
    {
@@ -421,8 +423,8 @@ void ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInf
    if(!isPrimitiveVisible(rDisplayInfo))
        return;

    const drawinglayer::primitive2d::Primitive2DContainer& xRetval = getPrimitive2DSequence(rDisplayInfo);
    if(xRetval.empty())
    getPrimitive2DSequence(rDisplayInfo);
    if(mxPrimitive2DSequence.empty())
        return;

    // get ranges
@@ -434,7 +436,15 @@ void ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInf
    if(!bVisible)
        return;

    rVisitor.visit(xRetval);
    // temporarily take over the mxPrimitive2DSequence, in case it gets invalidated while we want to iterate over it
    auto tmp = std::move(const_cast<ViewObjectContact*>(this)->mxPrimitive2DSequence);
    int nPrevCount = mnActionChangedCount;

    rVisitor.visit(tmp);

    // if we received ActionChanged() calls while walking the primitives, then leave it empty, otherwise move it back
    if (mnActionChangedCount == nPrevCount)
        const_cast<ViewObjectContact*>(this)->mxPrimitive2DSequence = std::move(tmp);
}

void ViewObjectContact::getPrimitive2DSequenceSubHierarchy(DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const