summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2021-12-17 10:54:59 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-12-17 11:21:25 +0100
commitb33a4d3c4acc37b9284c611caaaa661d2fe34db8 (patch)
tree704d0479b19146e207852693da4ba521f13ee3c6 /svx
parent793d4596d0facf5fc361fe2170bb73e01c60c9c7 (diff)
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>
Diffstat (limited to 'svx')
-rw-r--r--svx/source/sdr/contact/viewobjectcontact.cxx18
1 files changed, 14 insertions, 4 deletions
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx
index 9dcac9eb153c..8b8f0c3250d7 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