summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2021-12-06 15:58:19 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-12-06 19:46:10 +0100
commitd2b03c4bfa284efbb45cb4904122e97439d3ee06 (patch)
tree87696527bc43ba676ff03fadf7a90f918a4a057c
parent1c9a40299d328c78c035ca63ccdf22c5c669a03b (diff)
Revert "lose the caching in ViewObjectContact" because it breaks...
bitmap caching. Added some notes for future would-be optimizers. This reverts commit 7f02cb80ac2075b65ee1adee4e29d1d5c4819424. Change-Id: I39c41ea95d23d4a65edd3cef46a5d86fab48a044 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126425 Reviewed-by: Luboš Luňák <l.lunak@collabora.com> Tested-by: Jenkins
-rw-r--r--include/svx/sdr/contact/viewobjectcontact.hxx12
-rw-r--r--svx/source/sdr/contact/viewobjectcontact.cxx32
-rw-r--r--svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx6
3 files changed, 39 insertions, 11 deletions
diff --git a/include/svx/sdr/contact/viewobjectcontact.hxx b/include/svx/sdr/contact/viewobjectcontact.hxx
index 56deadd59afe..f13f247e55c2 100644
--- a/include/svx/sdr/contact/viewobjectcontact.hxx
+++ b/include/svx/sdr/contact/viewobjectcontact.hxx
@@ -48,6 +48,11 @@ private:
// This range defines the object's BoundRect
basegfx::B2DRange maObjectRange;
+ // PrimitiveSequence of the ViewContact. This contains all necessary information
+ // for the graphical visualisation and needs to be supported by all VCs which
+ // can be visualized.
+ drawinglayer::primitive2d::Primitive2DContainer mxPrimitive2DSequence;
+
// the PrimitiveAnimation if Primitive2DContainer contains animations
std::unique_ptr<sdr::animation::PrimitiveAnimation> mpPrimitiveAnimation;
@@ -64,7 +69,7 @@ protected:
// Called from getPrimitive2DSequence() when vector has changed. Evaluate object animation
// and setup accordingly
- void checkForPrimitive2DAnimations(const drawinglayer::primitive2d::Primitive2DContainer& );
+ void checkForPrimitive2DAnimations();
// This method is responsible for creating the graphical visualisation data which is
// stored/cached in the local primitive. Default gets view-independent Primitive
@@ -73,6 +78,9 @@ protected:
// This method will not handle included hierarchies and not check geometric visibility.
virtual void createPrimitive2DSequence(const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const;
+ // method for flushing Primitive2DContainer for VOC implementations
+ void flushPrimitive2DSequence() { mxPrimitive2DSequence.clear(); }
+
public:
// basic constructor.
ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact);
@@ -103,7 +111,7 @@ public:
// access to the local primitive. This will ensure that the local primitive is
// current in comparing the local one with a fresh created incarnation
// This method will not handle included hierarchies and not check visibility.
- drawinglayer::primitive2d::Primitive2DContainer getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const;
+ drawinglayer::primitive2d::Primitive2DContainer const & getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const;
// test this VOC for visibility concerning model-view stuff like e.g. Layer
virtual bool isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const;
diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx
index c72c34dfaccb..1dd8fef29415 100644
--- a/svx/source/sdr/contact/viewobjectcontact.cxx
+++ b/svx/source/sdr/contact/viewobjectcontact.cxx
@@ -263,13 +263,13 @@ void ViewObjectContact::ActionChildInserted(ViewContact& rChild)
// GetObjectContact().InvalidatePartOfView(rChildVOC.getObjectRange());
}
-void ViewObjectContact::checkForPrimitive2DAnimations(const drawinglayer::primitive2d::Primitive2DContainer& xPrimitive2DSequence)
+void ViewObjectContact::checkForPrimitive2DAnimations()
{
// remove old one
mpPrimitiveAnimation.reset();
// check for animated primitives
- if(xPrimitive2DSequence.empty())
+ if(mxPrimitive2DSequence.empty())
return;
const bool bTextAnimationAllowed(GetObjectContact().IsTextAnimationAllowed());
@@ -279,7 +279,7 @@ void ViewObjectContact::checkForPrimitive2DAnimations(const drawinglayer::primit
{
AnimatedExtractingProcessor2D aAnimatedExtractor(GetObjectContact().getViewInformation2D(),
bTextAnimationAllowed, bGraphicAnimationAllowed);
- aAnimatedExtractor.process(xPrimitive2DSequence);
+ aAnimatedExtractor.process(mxPrimitive2DSequence);
if(!aAnimatedExtractor.getPrimitive2DSequence().empty())
{
@@ -328,8 +328,14 @@ void ViewObjectContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInf
rVisitor.visit(xRetval);
}
-drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
+drawinglayer::primitive2d::Primitive2DContainer const & ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
{
+ /**
+ This method is weird because
+ (1) we have to re-walk the primitive tree because the flushing is unreliable
+ (2) we cannot just always use the new data because the old data has cached bitmaps in it e.g. see the documents in tdf#104878
+ */
+
drawinglayer::primitive2d::Primitive2DContainer xNewPrimitiveSequence;
// take care of redirectors and create new list
@@ -344,12 +350,19 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2
createPrimitive2DSequence(rDisplayInfo, xNewPrimitiveSequence);
}
+ // local up-to-date checks. New list different from local one?
+ if(mxPrimitive2DSequence == xNewPrimitiveSequence)
+ return mxPrimitive2DSequence;
+
+ // has changed, copy content
+ const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = std::move(xNewPrimitiveSequence);
+
// check for animated stuff
- const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations(xNewPrimitiveSequence);
+ const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations();
// always update object range when PrimitiveSequence changes
const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D());
- const_cast< ViewObjectContact* >(this)->maObjectRange = xNewPrimitiveSequence.getB2DRange(rViewInformation2D);
+ const_cast< ViewObjectContact* >(this)->maObjectRange = mxPrimitive2DSequence.getB2DRange(rViewInformation2D);
// check and eventually embed to GridOffset transform primitive
if(GetObjectContact().supportsGridOffsets())
@@ -364,7 +377,7 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2
drawinglayer::primitive2d::Primitive2DReference aEmbed(
new drawinglayer::primitive2d::TransformPrimitive2D(
aTranslateGridOffset,
- std::move(xNewPrimitiveSequence)));
+ std::move(const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence)));
// Set values at local data. So for now, the mechanism is to reset some of the
// defining things (mxPrimitive2DSequence, maGridOffset) and re-create the
@@ -375,13 +388,13 @@ drawinglayer::primitive2d::Primitive2DContainer ViewObjectContact::getPrimitive2
// just allow re-creation of the PrimitiveSequence (and removing buffered
// decomposed content of it). May be optimized, though. OTOH it only happens
// in calc which traditionally does not have a huge amount of DrawObjects anyways.
- xNewPrimitiveSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed };
+ const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed };
const_cast< ViewObjectContact* >(this)->maObjectRange.transform(aTranslateGridOffset);
}
}
// return current Primitive2DContainer
- return xNewPrimitiveSequence;
+ return mxPrimitive2DSequence;
}
bool ViewObjectContact::isPrimitiveVisible(const DisplayInfo& /*rDisplayInfo*/) const
@@ -452,6 +465,7 @@ void ViewObjectContact::resetGridOffset()
maGridOffset.setY(0.0);
// also reset sequence to get a re-calculation when GridOffset changes
+ mxPrimitive2DSequence.clear();
maObjectRange.reset();
}
diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
index 4881954b2eb1..4c0f54d93b1f 100644
--- a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx
@@ -1747,6 +1747,12 @@ namespace sdr::contact {
{
// graphical invalidate at all views
ActionChanged();
+
+ // #i93318# flush Primitive2DContainer to force recreation with updated XControlModel
+ // since e.g. background color has changed and existing decompositions are possibly no
+ // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator==
+ // since it only has a uno reference to the XControlModel
+ flushPrimitive2DSequence();
}
UnoControlPrintOrPreviewContact::UnoControlPrintOrPreviewContact( ObjectContactOfPageView& _rObjectContact, ViewContactOfUnoControl& _rViewContact )