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
219 // if there is something to show, use a primitive processor to render it. There
220 // is a choice between VCL and Canvas processors currently. The decision is made in
221 // createProcessor2DFromOutputDevice and takes into account things like the
222 // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered
223 // currently using the shown boolean. Canvas is not yet the default.
224
225 // prepare OutputDevice (historical stuff, maybe soon removed)
226 rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing
227 pOutDev->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::Default); // reset, default is no BiDi/RTL
228
229 // create renderer
230 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
232 rTargetOutDev, getViewInformation2D()));
233
234#if HAVE_FEATURE_DESKTOP || defined( ANDROID )
235 // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D
236 // and may use the MapMode from the Target OutDev in the DisplayInfo
237 rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo, *pProcessor2D);
238#else
239 // Hmm, !HAVE_FEATURE_DESKTOP && !ANDROID means iOS,
240 // right? But does it makes sense to use a different code
241 // path for iOS than for Android; both use tiled rendering
242 // etc now.
243
244 // HACK: this only works when we are drawing sdr shapes via
245 // drawinglayer; but it can happen that the hierarchy contains
246 // more than just the shapes, and then it fails.
247 //
248 // This is good enough for the tiled rendering for the moment, but
249 // we need to come up with the real solution shortly.
250
251 // Only get the expensive hierarchy if we can be sure that the
252 // returned sequence won't be empty anyway.
253 bool bGetHierarchy = rRedrawArea.IsEmpty();
254 if (!bGetHierarchy)
255 {
256 // Not empty? Then not doing a full redraw, check if
257 // getPrimitive2DSequenceHierarchy() is still needed.
258 sal_Int32 nObjCount = GetSdrPage()->GetObjCount();
259 for (sal_Int32 i = 0; i < nObjCount; ++i)
260 {
262 if (rRedrawArea.Overlaps(pObject->GetCurrentBoundRect()))
263 {
264 bGetHierarchy = true;
265 break;
266 }
267 }
268 }
269
270 if (bGetHierarchy)
271 // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D
272 // and may use the MapMode from the Target OutDev in the DisplayInfo
273 rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo, *pProcessor2D);
274#endif
275
276 // #114359# restore old ClipReghion
277 if(bClipRegionPushed)
278 {
279 pOutDev->Pop();
280 }
281
282 // Visualize entered groups: Reset to original DrawMode
283 if(bVisualizeEnteredGroup)
284 {
285 rDisplayInfo.ClearGhostedDrawMode();
286 }
287 }
288
289 // test if visualizing of entered groups is switched on at all
291 {
292 return true;
293 }
294
295 // get active group's (the entered group) ViewContact
297 {
298 SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList();
299
300 if(pActiveGroupList)
301 {
302 if(nullptr != pActiveGroupList->getSdrPageFromSdrObjList())
303 {
304 // It's a Page itself
305 return &(pActiveGroupList->getSdrPageFromSdrObjList()->GetViewContact());
306 }
307 else if(pActiveGroupList->getSdrObjectFromSdrObjList())
308 {
309 // Group object
310 return &(pActiveGroupList->getSdrObjectFromSdrObjList()->GetViewContact());
311 }
312 }
313 else if(GetSdrPage())
314 {
315 // use page of associated SdrPageView
316 return &(GetSdrPage()->GetViewContact());
317 }
318
319 return nullptr;
320 }
321
322 // Invalidate given rectangle at the window/output which is represented by
323 // this ObjectContact.
325 {
326 // invalidate at associated PageWindow
328 }
329
330 // Get info about the need to visualize GluePoints
332 {
333 bool bTiledRendering = comphelper::LibreOfficeKit::isActive();
334 return !bTiledRendering && GetPageWindow().GetPageView().GetView().ImpIsGlueVisible();
335 }
336
337 // check if text animation is allowed.
339 {
341 return true;
344 return rOpt.GetIsAllowAnimatedText();
345 }
346
347 // check if graphic animation is allowed.
349 {
351 return true;
354 return rOpt.GetIsAllowAnimatedGraphics();
355 }
356
357 // print?
359 {
361 }
362
363 // recording MetaFile?
365 {
367 return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
368 }
369
370 // pdf export?
372 {
374 }
375
377 {
378 if (isOutputToPDFFile())
379 {
380 vcl::PDFExtOutDevData* pPDFExtOutDevData(dynamic_cast<vcl::PDFExtOutDevData*>(
382
383 if (nullptr != pPDFExtOutDevData)
384 {
385 return pPDFExtOutDevData->GetIsExportTaggedPDF();
386 }
387 }
388 return false;
389 }
390
391 // gray display mode
393 {
395 return (nDrawMode == (DrawModeFlags::GrayLine|DrawModeFlags::GrayFill|DrawModeFlags::BlackText|DrawModeFlags::GrayBitmap|DrawModeFlags::GrayGradient));
396 }
397
398 // high contrast display mode
400 {
402 return (nDrawMode == (DrawModeFlags::SettingsLine|DrawModeFlags::SettingsFill|DrawModeFlags::SettingsText|DrawModeFlags::SettingsGradient));
403 }
404
405 // access to SdrPageView
407 {
408 return &(mrPageWindow.GetPageView());
409 }
410
411
412 // access to OutputDevice
414 {
416
417 if(pPreRenderDevice)
418 {
419 return &(pPreRenderDevice->GetPreRenderDevice());
420 }
421 else
422 {
424 }
425 }
426
427 // set all UNO controls displayed in the view to design/alive mode
429 {
430 const sal_uInt32 nCount(getViewObjectContactCount());
431
432 for(sal_uInt32 a(0); a < nCount; a++)
433 {
435 const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC);
436
437 if(pUnoObjectVOC)
438 {
439 pUnoObjectVOC->setControlDesignMode(_bDesignMode);
440 }
441 }
442 }
443
444} // end of namespace
445
446/* 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:822
size_t GetObjCount() const
Definition: svdpage.cxx:816
virtual SdrObject * getSdrObjectFromSdrObjList() const
Definition: svdpage.cxx:128
Abstract DrawObject.
Definition: svdobj.hxx:261
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:377
const sdr::contact::ViewContact & GetViewContact() const
Definition: svdpage.cxx:1165
bool IsPreviewRenderer() const
Definition: svdpntv.hxx:389
bool ImpIsGlueVisible() const
Definition: svdpntv.hxx:240
OutputDevice & GetTargetOutputDevice()
OutputDevice & GetOutputDevice() const
SdrPreRenderDevice * GetPreRenderDevice() const
OutputDevice & GetPreRenderDevice()
SvtAccessibilityOptions & getAccessibilityOptions()
Definition: svdview.hxx:235
constexpr tools::Long getHeight() const
constexpr tools::Long getWidth() const
bool GetIsAllowAnimatedText() const
bool GetIsAllowAnimatedGraphics() const
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:77
const SdrLayerIDSet & GetProcessLayers() const
Definition: displayinfo.hxx:73
virtual bool isExportTaggedPDF() const override
virtual const ViewContact * getActiveViewContact() const override
virtual bool IsTextAnimationAllowed() const override
virtual OutputDevice * TryToGetOutputDevice() const override
access to OutputDevice. May return 0L like the default implementations do. Override as needed.
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 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