summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorArmin Le Grand (Collabora) <armin.le.grand@me.com>2020-02-21 16:58:17 +0100
committerMiklos Vajna <vmiklos@collabora.com>2020-02-24 13:10:29 +0100
commitef6f94e93bbe55a26b67b55b2aecda67d406ab85 (patch)
tree271d344f997e520ecf406a5b102edaf059542d1d /sw
parent59edfb81f05da304b49609a239961607db6f6900 (diff)
tdf#130768 speedup huge pixel graphics Cairo
For more information/documentation please refer to the bugzilla task Fixed a crash in CppunitTest_desktop_lib which led to a missing test of mpGraphics in OutputDevice::DrawTransformedBitmapEx. Other public methods test that and one of the goals of the cange was to use that method more often, so this may have never been detected before Change-Id: I10e57bd05db0c8cf868ff98d63f5af3d116a3015 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89230 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89252 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/doc/notxtfrm.cxx198
-rw-r--r--sw/source/core/inc/frmtool.hxx6
-rw-r--r--sw/source/core/inc/notxtfrm.hxx6
3 files changed, 198 insertions, 12 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 04e556277738..f2b148361994 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -82,6 +82,14 @@
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
+// MM02 needed for VOC mechanism and getting the OC - may be moved to an own file
+#include <svx/sdrpagewindow.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+
using namespace com::sun::star;
static bool GetRealURL( const SwGrfNode& rNd, OUString& rText )
@@ -148,7 +156,9 @@ static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText,
SwNoTextFrame::SwNoTextFrame(SwNoTextNode * const pNode, SwFrame* pSib )
: SwContentFrame( pNode, pSib ),
// RotateFlyFrame3
- mpTransformableSwFrame()
+ mpTransformableSwFrame(),
+ // MM02
+ mpViewContact()
{
mnFrameType = SwFrameType::NoTxt;
}
@@ -925,6 +935,7 @@ static bool paintUsingPrimitivesHelper(
return false;
}
+// MM02 original using falölback to VOC and primitive-based version
void paintGraphicUsingPrimitivesHelper(
vcl::RenderContext & rOutputDevice,
GraphicObject const& rGrfObj,
@@ -936,12 +947,24 @@ void paintGraphicUsingPrimitivesHelper(
// -> the primitive renderer will create the needed pdf export data
// -> if bitmap content, it will be cached system-dependent
drawinglayer::primitive2d::Primitive2DContainer aContent(1);
-
aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
rGraphicTransform,
rGrfObj,
rGraphicAttr);
+ // MM02 use primitive-based version for visualization
+ paintGraphicUsingPrimitivesHelper(
+ rOutputDevice,
+ aContent,
+ rGraphicTransform);
+}
+
+// MM02 new VOC and primitive-based version
+void paintGraphicUsingPrimitivesHelper(
+ vcl::RenderContext & rOutputDevice,
+ drawinglayer::primitive2d::Primitive2DContainer& rContent,
+ const basegfx::B2DHomMatrix& rGraphicTransform)
+{
// RotateFlyFrame3: If ClipRegion is set at OutputDevice, we
// need to use that. Usually the renderer would be a VCL-based
// PrimitiveRenderer, but there are system-specific shortcuts that
@@ -1008,9 +1031,12 @@ void paintGraphicUsingPrimitivesHelper(
aTarget.append(aClip);
}
- aContent[0] = new drawinglayer::primitive2d::MaskPrimitive2D(
- aTarget,
- aContent);
+ drawinglayer::primitive2d::MaskPrimitive2D* pNew(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ aTarget,
+ rContent));
+ rContent.resize(1);
+ rContent[0] = pNew;
}
}
@@ -1019,11 +1045,111 @@ void paintGraphicUsingPrimitivesHelper(
paintUsingPrimitivesHelper(
rOutputDevice,
- aContent,
+ rContent,
aTargetRange,
aTargetRange);
}
+// DrawContact section
+namespace { // anonymous namespace
+class ViewObjectContactOfSwNoTextFrame : public sdr::contact::ViewObjectContact
+{
+protected:
+ virtual drawinglayer::primitive2d::Primitive2DContainer createPrimitive2DSequence(
+ const sdr::contact::DisplayInfo& rDisplayInfo) const override;
+
+public:
+ ViewObjectContactOfSwNoTextFrame(
+ sdr::contact::ObjectContact& rObjectContact,
+ sdr::contact::ViewContact& rViewContact);
+};
+
+class ViewContactOfSwNoTextFrame : public sdr::contact::ViewContact
+{
+private:
+ // owner
+ const SwNoTextFrame& mrSwNoTextFrame;
+
+protected:
+ // Create an Object-Specific ViewObjectContact, set ViewContact and
+ // ObjectContact. Always needs to return something.
+ virtual sdr::contact::ViewObjectContact& CreateObjectSpecificViewObjectContact(
+ sdr::contact::ObjectContact& rObjectContact) override;
+
+public:
+ // read-access to owner
+ const SwNoTextFrame& getSwNoTextFrame() const { return mrSwNoTextFrame; }
+
+ // basic constructor, used from SwNoTextFrame.
+ explicit ViewContactOfSwNoTextFrame(const SwNoTextFrame& rSwNoTextFrame);
+};
+
+drawinglayer::primitive2d::Primitive2DContainer ViewObjectContactOfSwNoTextFrame::createPrimitive2DSequence(
+ const sdr::contact::DisplayInfo& /*rDisplayInfo*/) const
+{
+ // MM02 get all the parameters formally used in paintGraphicUsingPrimitivesHelper
+ ViewContactOfSwNoTextFrame& rVCOfNTF(static_cast<ViewContactOfSwNoTextFrame&>(GetViewContact()));
+ const SwNoTextFrame& rSwNoTextFrame(rVCOfNTF.getSwNoTextFrame());
+ SwNoTextNode& rNoTNd(const_cast<SwNoTextNode&>(*static_cast<const SwNoTextNode*>(rSwNoTextFrame.GetNode())));
+ SwGrfNode* pGrfNd(rNoTNd.GetGrfNode());
+
+ if(nullptr != pGrfNd)
+ {
+ const bool bPrn(GetObjectContact().isOutputToPrinter() || GetObjectContact().isOutputToRecordingMetaFile());
+ const GraphicObject& rGrfObj(pGrfNd->GetGrfObj(bPrn));
+ GraphicAttr aGraphicAttr;
+ pGrfNd->GetGraphicAttr(aGraphicAttr, &rSwNoTextFrame);
+ const basegfx::B2DHomMatrix aGraphicTransform(rSwNoTextFrame.getFrameAreaTransformation());
+
+ // MM02 this is the right place in the VOC-Mechanism to create
+ // the primitives for visualization - these will be automatically
+ // buffered and reused
+ drawinglayer::primitive2d::Primitive2DContainer aContent(1);
+ aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D(
+ aGraphicTransform,
+ rGrfObj,
+ aGraphicAttr);
+
+ return aContent;
+ }
+
+ return drawinglayer::primitive2d::Primitive2DContainer();
+}
+
+ViewObjectContactOfSwNoTextFrame::ViewObjectContactOfSwNoTextFrame(
+ sdr::contact::ObjectContact& rObjectContact,
+ sdr::contact::ViewContact& rViewContact)
+: sdr::contact::ViewObjectContact(rObjectContact, rViewContact)
+{
+}
+
+sdr::contact::ViewObjectContact& ViewContactOfSwNoTextFrame::CreateObjectSpecificViewObjectContact(
+ sdr::contact::ObjectContact& rObjectContact)
+{
+ sdr::contact::ViewObjectContact* pRetval = new ViewObjectContactOfSwNoTextFrame(rObjectContact, *this);
+ return *pRetval;
+}
+
+ViewContactOfSwNoTextFrame::ViewContactOfSwNoTextFrame(
+ const SwNoTextFrame& rSwNoTextFrame
+)
+: sdr::contact::ViewContact(),
+ mrSwNoTextFrame(rSwNoTextFrame)
+{
+}
+} // end of anonymous namespace
+
+sdr::contact::ViewContact& SwNoTextFrame::GetViewContact() const
+{
+ if(!mpViewContact)
+ {
+ const_cast< SwNoTextFrame* >(this)->mpViewContact =
+ std::make_unique<ViewContactOfSwNoTextFrame>(*this);
+ }
+
+ return *mpViewContact;
+}
+
/** Paint the graphic.
We require either a QuickDraw-Bitmap or a graphic here. If we do not have
@@ -1149,13 +1275,61 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr
}
else
{
- const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation());
+ // MM02 To allow system-dependent buffering of the involved
+ // bitmaps it is necessary to re-use the involved primitives
+ // and their already executed decomposition (also for
+ // performance reasons). This is usually done in DrawingLayer
+ // by using the VOC-Mechanism (see descriptions elsewhere).
+ // To get that here, make the involved SwNoTextFrame (this)
+ // a sdr::contact::ViewContact supplier by supporing
+ // a GetViewContact() - call. For ObjectContact we can use
+ // the already exising ObjectContact from the involved
+ // DrawingLayer. For tis, the helper classes
+ // ViewObjectContactOfSwNoTextFrame
+ // ViewContactOfSwNoTextFrame
+ // are created which support the VOC-mechanism in it's minimal
+ // form. This allows automatic and view-dependent (multiple edit
+ // windows, print, etc.) re-use of the created primitives.
+ // Also: Will be very useful when completely changing the Writer
+ // repaint to VOC and Primitives, too.
+ static const char* pDisableMM02Goodies(getenv("SAL_DISABLE_MM02_GOODIES"));
+ static bool bUseViewObjectContactMechanism(nullptr == pDisableMM02Goodies);
+
+ if(bUseViewObjectContactMechanism)
+ {
+ // MM02 use VOC-mechanism and buffer primitives
+ SwViewShellImp* pImp(pShell->Imp());
+ SdrPageView* pPageView(nullptr != pImp ? pImp->GetPageView() : nullptr);
+ SdrPageWindow* pPageWindow(nullptr != pPageView ? pPageView->FindPageWindow(*pShell->GetOut()) : nullptr);
- paintGraphicUsingPrimitivesHelper(
- *pOut,
- rGrfObj,
- aGrfAttr,
- aGraphicTransform);
+ if(nullptr != pPageWindow)
+ {
+ sdr::contact::ObjectContact& rOC(pPageWindow->GetObjectContact());
+ sdr::contact::ViewContact& rVC(GetViewContact());
+ sdr::contact::ViewObjectContact& rVOC(rVC.GetViewObjectContact(rOC));
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rVOC.getPrimitive2DSequence(aDisplayInfo));
+ const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation());
+
+ paintGraphicUsingPrimitivesHelper(
+ *pOut,
+ aPrimitives,
+ aGraphicTransform);
+ }
+ }
+ else
+ {
+ // MM02 fallback to direct paint with primitive-recreation
+ // which will block reusage of system-dependent bitmap data
+ const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation());
+
+ paintGraphicUsingPrimitivesHelper(
+ *pOut,
+ rGrfObj,
+ aGrfAttr,
+ aGraphicTransform);
+ }
}
}
else
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index 5ffcd20083f7..54c1c9231e28 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -97,6 +97,12 @@ void paintGraphicUsingPrimitivesHelper(
GraphicAttr const& rGraphicAttr,
const basegfx::B2DHomMatrix& rGraphicTransform);
+// MM02 new VOC and primitive-based version
+void paintGraphicUsingPrimitivesHelper(
+ vcl::RenderContext & rOutputDevice,
+ drawinglayer::primitive2d::Primitive2DContainer& rContent,
+ const basegfx::B2DHomMatrix& rGraphicTransform);
+
// method to align rectangle.
// Created declaration here to avoid <extern> declarations
void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext* pRenderContext );
diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx
index fad416c27d8f..6c168041d244 100644
--- a/sw/source/core/inc/notxtfrm.hxx
+++ b/sw/source/core/inc/notxtfrm.hxx
@@ -20,6 +20,8 @@
#define INCLUDED_SW_SOURCE_CORE_INC_NOTXTFRM_HXX
#include "cntfrm.hxx"
+// MM02
+#include <svx/sdr/contact/viewcontact.hxx>
class SwNoTextNode;
class OutputDevice;
@@ -49,6 +51,10 @@ private:
void ClearCache();
+ // MM02
+ std::unique_ptr<sdr::contact::ViewContact> mpViewContact;
+ sdr::contact::ViewContact& GetViewContact() const;
+
protected:
virtual void MakeAll(vcl::RenderContext* pRenderContext) override;
virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override;