LibreOffice Module svx (master) 1
objectcontactofpageview.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_feature_desktop.h>
21
24#include <svx/svdpagv.hxx>
25#include <svx/svdpage.hxx>
28#include <svx/svdview.hxx>
31#include <svx/sdrpagewindow.hxx>
36#include <osl/diagnose.h>
37#include <svx/unoapi.hxx>
39#include <vcl/canvastools.hxx>
41#include <comphelper/lok.hxx>
42
43#include <memory>
44
45using namespace com::sun::star;
46
47namespace sdr::contact
48{
49 // internal access to SdrPage of SdrPageView
51 {
53 }
54
56 SdrPageWindow& rPageWindow, const char *pDebugName)
57 : Idle(pDebugName)
58 , mrPageWindow(rPageWindow)
59 {
60 // init PreviewRenderer flag
62
63 // init timer
64 SetPriority(TaskPriority::HIGH_IDLE);
65 Stop();
66 }
67
69 {
70 // execute missing LazyInvalidates and stop timer
71 Invoke();
72 }
73
74 // LazyInvalidate request. Take action.
76 {
77 // do NOT call parent, but remember that something is to do by
78 // starting the LazyInvalidateTimer
79 Start();
80 }
81
82 // call this to support evtl. preparations for repaint
84 {
85 if(IsActive())
86 // there are still non-triggered LazyInvalidate events, trigger these
87 Invoke();
88 }
89
90 // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
92 {
93 // stop the timer
94 Stop();
95
96 // invalidate all LazyInvalidate VOCs new situations
97 const sal_uInt32 nVOCCount(getViewObjectContactCount());
98
99 for(sal_uInt32 a(0); a < nVOCCount; a++)
100 {
102 pCandidate->triggerLazyInvalidate();
103 }
104 }
105
106 // Process the whole displaying
108 {
109 const SdrPage* pStartPage = GetSdrPage();
110
111 if(pStartPage && !rDisplayInfo.GetProcessLayers().IsEmpty())
112 {
113 const ViewContact& rDrawPageVC = pStartPage->GetViewContact();
114
115 if(rDrawPageVC.GetObjectCount())
116 {
117 DoProcessDisplay(rDisplayInfo);
118 }
119 }
120 }
121
122 // Process the whole displaying. Only use given DisplayInfo, do not access other
123 // OutputDevices then the given ones.
125 {
127 const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel());
128 if (!isOutputToRecordingMetaFile() // do those have outdev too?
129 && (0 == aOutputSizePixel.getWidth() ||
130 0 == aOutputSizePixel.getHeight()))
131 {
132 return;
133 }
134
135 // visualize entered group when that feature is switched on and it's not
136 // a print output. #i29129# No ghosted display for printing.
137 bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter());
138
139 // Visualize entered groups: Set to ghosted as default
140 // start. Do this only for the DrawPage, not for MasterPages
141 if(bVisualizeEnteredGroup)
142 {
143 rDisplayInfo.SetGhostedDrawMode();
144 }
145
146 // #114359# save old and set clip region
148 OSL_ENSURE(nullptr != pOutDev, "ObjectContactOfPageView without OutDev, someone has overridden TryToGetOutputDevice wrong (!)");
149 bool bClipRegionPushed(false);
150 const vcl::Region& rRedrawArea(rDisplayInfo.GetRedrawArea());
151
152 if(!rRedrawArea.IsEmpty() && !comphelper::LibreOfficeKit::isActive())
153 {
154 bClipRegionPushed = true;
156 pOutDev->IntersectClipRegion(rRedrawArea);
157 }
158
159 // Get start node and process DrawPage contents
160 const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this);
161
162 // update current ViewInformation2D at the ObjectContact
163 const double fCurrentTime(getPrimitiveAnimator().GetTime());
164 basegfx::B2DRange aViewRange;
165
166 // create ViewRange
168 {
169 if (!rDisplayInfo.GetRedrawArea().IsEmpty())
170 {
171 // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is
172 // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this,
173 // all existing objects will be collected as primitives and processed.
174 // OD 2009-03-05 #i99876# perform the same also for SW on printing.
175 // fdo#78149 same thing also needed for plain MetaFile
176 // export, so why not do it always
177 const tools::Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
178
179 aViewRange = vcl::unotools::b2DRectangleFromRectangle(aLogicClipRectangle);
180 }
181 }
182 else
183 {
184 // use visible pixels, but transform to world coordinates
185 aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
186 // if a clip region is set, use it
187 if(!rDisplayInfo.GetRedrawArea().IsEmpty())
188 {
189 // get logic clip range and create discrete one
190 const tools::Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
191 basegfx::B2DRange aDiscreteClipRange = vcl::unotools::b2DRectangleFromRectangle(aLogicClipRectangle);
192 aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation());
193
194 // align the discrete one to discrete boundaries (pixel bounds). Also
195 // expand X and Y max by one due to Rectangle definition source
196 aDiscreteClipRange.expand(basegfx::B2DTuple(
197 floor(aDiscreteClipRange.getMinX()),
198 floor(aDiscreteClipRange.getMinY())));
199 aDiscreteClipRange.expand(basegfx::B2DTuple(
200 1.0 + ceil(aDiscreteClipRange.getMaxX()),
201 1.0 + ceil(aDiscreteClipRange.getMaxY())));
202
203 // intersect current ViewRange with ClipRange
204 aViewRange.intersect(aDiscreteClipRange);
205 }
206
207 // transform to world coordinates
208 aViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
209 }
210
211 // update local ViewInformation2D
212 drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
213 aNewViewInformation2D.setViewTransformation(rTargetOutDev.GetViewTransformation());
214 aNewViewInformation2D.setViewport(aViewRange);
215 aNewViewInformation2D.setVisualizedPage(GetXDrawPageForSdrPage(GetSdrPage()));
216 aNewViewInformation2D.setViewTime(fCurrentTime);
217 updateViewInformation2D(aNewViewInformation2D);
218
220
221#if HAVE_FEATURE_DESKTOP || defined( ANDROID )
222 // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D
223 // and may use the MapMode from the Target OutDev in the DisplayInfo
224 rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo, xPrimitiveSequence);
225#else
226 // Hmm, !HAVE_FEATURE_DESKTOP && !ANDROID means iOS,
227 // right? But does it makes sense to use a different code
228 // path for iOS than for Android; both use tiled rendering
229 // etc now.
230
231 // HACK: this only works when we are drawing sdr shapes via
232 // drawinglayer; but it can happen that the hierarchy contains
233 // more than just the shapes, and then it fails.
234 //
235 // This is good enough for the tiled rendering for the moment, but
236 // we need to come up with the real solution shortly.
237
238 // Only get the expensive hierarchy if we can be sure that the
239 // returned sequence won't be empty anyway.
240 bool bGetHierarchy = rRedrawArea.IsEmpty();
241 if (!bGetHierarchy)
242 {
243 // Not empty? Then not doing a full redraw, check if
244 // getPrimitive2DSequenceHierarchy() is still needed.
245 sal_Int32 nObjCount = GetSdrPage()->GetObjCount();
246 for (sal_Int32 i = 0; i < nObjCount; ++i)
247 {
249 if (rRedrawArea.Overlaps(pObject->GetCurrentBoundRect()))
250 {
251 bGetHierarchy = true;
252 break;
253 }
254 }
255 }
256
257 if (bGetHierarchy)
258 // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D
259 // and may use the MapMode from the Target OutDev in the DisplayInfo
260 rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo, xPrimitiveSequence);
261#endif
262
263 // if there is something to show, use a primitive processor to render it. There
264 // is a choice between VCL and Canvas processors currently. The decision is made in
265 // createProcessor2DFromOutputDevice and takes into account things like the
266 // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered
267 // currently using the shown boolean. Canvas is not yet the default.
268 if(!xPrimitiveSequence.empty())
269 {
270 // prepare OutputDevice (historical stuff, maybe soon removed)
271 rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing
272 pOutDev->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::Default); // reset, default is no BiDi/RTL
273 // create renderer
274 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
276 rTargetOutDev, getViewInformation2D()));
277 pProcessor2D->process(xPrimitiveSequence);
278 }
279
280 // #114359# restore old ClipReghion
281 if(bClipRegionPushed)
282 {
283 pOutDev->Pop();
284 }
285
286 // Visualize entered groups: Reset to original DrawMode
287 if(bVisualizeEnteredGroup)
288 {
289 rDisplayInfo.ClearGhostedDrawMode();
290 }
291 }
292
293 // test if visualizing of entered groups is switched on at all
295 {
296 return true;
297 }
298
299 // get active group's (the entered group) ViewContact
301 {
302 SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList();
303
304 if(pActiveGroupList)
305 {
306 // tdf#122735
307 // Here it is necessary to check for SdrObject 1st, that may
308 // return nullptr if it is not a SdrObject/SdrObjGroup.
309 // Checking for SrPage OTOH will *always* try to return
310 // something useful due to SdrObjGroup::getSdrPageFromSdrObjList
311 // using getSdrPageFromSdrObject which will recursively go up the
312 // hierarchy to get the SdrPage the SdrObject belongs to, so
313 // this will *not* be nullptr for e.g. a SdrObjGroup if the
314 // SdrObjGroup is inserted to a SdrPage.
315 // NOTE: It is also possible to use dynamic_cast<SdrObjGroup*>
316 // here, but getSdrObjectFromSdrObjList and
317 // getSdrPageFromSdrObjListexist to not need to do that
318 SdrObject* pSdrObject(pActiveGroupList->getSdrObjectFromSdrObjList());
319
320 if(nullptr != pSdrObject)
321 {
322 // It is a group object
323 return &(pSdrObject->GetViewContact());
324 }
325 else
326 {
327 SdrPage* pSdrPage(pActiveGroupList->getSdrPageFromSdrObjList());
328
329 if(nullptr != pSdrPage)
330 {
331 // It's a Page itself
332 return &(pSdrPage->GetViewContact());
333 }
334 }
335 }
336 else if(GetSdrPage())
337 {
338 // use page of associated SdrPageView
339 return &(GetSdrPage()->GetViewContact());
340 }
341
342 return nullptr;
343 }
344
345 // Invalidate given rectangle at the window/output which is represented by
346 // this ObjectContact.
348 {
349 // invalidate at associated PageWindow
351 }
352
353 // Get info about the need to visualize GluePoints
355 {
356 bool bTiledRendering = comphelper::LibreOfficeKit::isActive();
357 return !bTiledRendering && GetPageWindow().GetPageView().GetView().ImpIsGlueVisible();
358 }
359
360 // check if text animation is allowed.
362 {
364 return true;
366 }
367
368 // check if graphic animation is allowed.
370 {
372 return true;
374 }
375
376 // print?
378 {
380 }
381
382 // display page decoration? Default is true
384 {
386 }
387
388 // display mster page content (ViewContactOfMasterPage)? Default is true
390 {
392 }
393
394 // recording MetaFile?
396 {
398 return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
399 }
400
401 // pdf export?
403 {
405 }
406
408 {
409 if (isOutputToPDFFile())
410 {
411 vcl::PDFExtOutDevData* pPDFExtOutDevData(dynamic_cast<vcl::PDFExtOutDevData*>(
413
414 if (nullptr != pPDFExtOutDevData)
415 {
416 return pPDFExtOutDevData->GetIsExportTaggedPDF();
417 }
418 }
419 return false;
420 }
421
423 {
424 if (!isOutputToPDFFile())
425 {
426 return nullptr;
427 }
428 vcl::PDFExtOutDevData* pPDFExtOutDevData(dynamic_cast<vcl::PDFExtOutDevData*>(
430 return pPDFExtOutDevData;
431 }
432
433 // gray display mode
435 {
437 return (nDrawMode == (DrawModeFlags::GrayLine|DrawModeFlags::GrayFill|DrawModeFlags::BlackText|DrawModeFlags::GrayBitmap|DrawModeFlags::GrayGradient));
438 }
439
440 // high contrast display mode
442 {
444 return (nDrawMode == (DrawModeFlags::SettingsLine|DrawModeFlags::SettingsFill|DrawModeFlags::SettingsText|DrawModeFlags::SettingsGradient));
445 }
446
447 // access to SdrPageView
449 {
450 return &(mrPageWindow.GetPageView());
451 }
452
453
454 // access to OutputDevice
456 {
458
459 if(pPreRenderDevice)
460 {
461 return &(pPreRenderDevice->GetPreRenderDevice());
462 }
463 else
464 {
466 }
467 }
468
469 // set all UNO controls displayed in the view to design/alive mode
471 {
472 const sal_uInt32 nCount(getViewObjectContactCount());
473
474 for(sal_uInt32 a(0); a < nCount; a++)
475 {
477 const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC);
478
479 if(pUnoObjectVOC)
480 {
481 pUnoObjectVOC->setControlDesignMode(_bDesignMode);
482 }
483 }
484 }
485
486} // end of namespace
487
488/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawModeFlags
bool IsPause() const
bool IsRecord() const
virtual void Start(bool bStartTimer=true) override
GDIMetaFile * GetConnectMetaFile() const
basegfx::B2DHomMatrix GetViewTransformation() const
basegfx::B2DHomMatrix GetInverseViewTransformation() const
Size GetOutputSizePixel() const
vcl::ExtOutDevData * GetExtOutDevData() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
OutDevType GetOutDevType() const
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
DrawModeFlags GetDrawMode() const
void IntersectClipRegion(const tools::Rectangle &rRect)
bool IsEmpty() const
Definition: svdlayer.cxx:28
virtual SdrPage * getSdrPageFromSdrObjList() const
Definition: svdpage.cxx:122
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:785
size_t GetObjCount() const
Definition: svdpage.cxx:779
virtual SdrObject * getSdrObjectFromSdrObjList() const
Definition: svdpage.cxx:128
Abstract DrawObject.
Definition: svdobj.hxx:260
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:261
SdrObjList * GetObjList() const
Return current List.
Definition: svdpagv.hxx:169
SdrView & GetView()
Definition: svdpagv.hxx:130
SdrPage * GetPage() const
Definition: svdpagv.hxx:166
void InvalidatePageWindow(const basegfx::B2DRange &rRange)
SdrPaintWindow & GetPaintWindow() const
SdrPageView & GetPageView() const
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:379
const sdr::contact::ViewContact & GetViewContact() const
Definition: svdpage.cxx:1139
bool IsMasterPageVisualizationAllowed() const
Definition: svdpntv.hxx:226
bool IsPreviewRenderer() const
Definition: svdpntv.hxx:412
bool IsPageDecorationAllowed() const
Definition: svdpntv.hxx:222
bool ImpIsGlueVisible() const
Definition: svdpntv.hxx:262
OutputDevice & GetTargetOutputDevice()
OutputDevice & GetOutputDevice() const
SdrPreRenderDevice * GetPreRenderDevice() const
OutputDevice & GetPreRenderDevice()
constexpr tools::Long getHeight() const
constexpr tools::Long getWidth() const
static bool GetIsAllowAnimatedGraphics()
static bool GetIsAllowAnimatedText()
bool IsActive() const
void SetPriority(TaskPriority ePriority)
void Stop()
BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix &rMatrix)
TYPE getMaxX() const
TYPE getMinX() const
TYPE getMinY() const
void expand(const Tuple2D< TYPE > &rTuple)
TYPE getMaxY() const
void intersect(const Range2D &rRange)
void setViewport(const basegfx::B2DRange &rNew)
void setViewTransformation(const basegfx::B2DHomMatrix &rNew)
void setVisualizedPage(const css::uno::Reference< css::drawing::XDrawPage > &rNew)
const vcl::Region & GetRedrawArea() const
Definition: displayinfo.hxx:70
const SdrLayerIDSet & GetProcessLayers() const
Definition: displayinfo.hxx:66
virtual bool isExportTaggedPDF() const override
virtual const ViewContact * getActiveViewContact() const override
virtual bool IsTextAnimationAllowed() const override
virtual bool isMasterPageActive() const override
virtual OutputDevice * TryToGetOutputDevice() const override
access to OutputDevice. May return 0L like the default implementations do. Override as needed.
virtual ::vcl::PDFExtOutDevData const * GetPDFExtOutDevData() const override
virtual SdrPageView * TryToGetSdrPageView() const override
access to SdrPageView. May return 0L like the default implementations do. Override as needed.
virtual bool isOutputToPDFFile() const override
virtual bool IsGraphicAnimationAllowed() const override
virtual bool isOutputToPrinter() const override
virtual bool isOutputToRecordingMetaFile() const override
virtual bool AreGluePointsVisible() const override
ObjectContactOfPageView(SdrPageWindow &rPageWindow, const char *pDebugName)
virtual bool isPageDecorationActive() const override
virtual void InvalidatePartOfView(const basegfx::B2DRange &rRange) const override
void SetUNOControlsDesignMode(bool _bDesignMode) const
sets all UNO controls which are associated with this ObjectContact to design or alive mode.
virtual bool DoVisualizeEnteredGroup() const override
virtual void ProcessDisplay(DisplayInfo &rDisplayInfo) override
virtual bool isDrawModeHighContrast() const override
virtual bool isDrawModeGray() const override
void DoProcessDisplay(DisplayInfo &rDisplayInfo)
virtual void setLazyInvalidate(ViewObjectContact &rVOC) override
ViewObjectContact * getViewObjectContact(sal_uInt32 a) const
void updateViewInformation2D(const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
sdr::animation::primitiveAnimator & getPrimitiveAnimator()
const drawinglayer::geometry::ViewInformation2D & getViewInformation2D() const
sal_uInt32 getViewObjectContactCount() const
void setPreviewRenderer(bool bNew)
virtual sal_uInt32 GetObjectCount() const
ViewObjectContact & GetViewObjectContact(ObjectContact &rObjectContact)
Definition: viewcontact.cxx:65
void setControlDesignMode(bool _bDesignMode) const
sets the design/alive mode of the control
virtual void getPrimitive2DSequenceHierarchy(DisplayInfo &rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
static bool IsFuzzing()
bool GetIsExportTaggedPDF() const
bool IsEmpty() const
bool Overlaps(const tools::Rectangle &rRect) const
tools::Rectangle GetBoundRect() const
int nCount
EmbeddedObjectRef * pObject
uno_Any a
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
int i
Any GetTime(const OUString &val)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
OUTDEV_PDF
OUTDEV_PRINTER
uno::Reference< drawing::XDrawPage > GetXDrawPageForSdrPage(SdrPage *pPage) noexcept
returns a StarOffice API wrapper for the given SdrPage
Definition: unopage.cxx:873