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>
32 #include <svx/sdrpaintwindow.hxx>
35 #include <com/sun/star/rendering/XSpriteCanvas.hpp>
38 #include <svx/unoapi.hxx>
39 #include <unotools/configmgr.hxx>
40 #include <vcl/canvastools.hxx>
41 #include <comphelper/lok.hxx>
42 
43 #include <eventhandler.hxx>
44 #include <memory>
45 
46 using namespace com::sun::star;
47 
48 namespace sdr
49 {
50  namespace contact
51  {
52  // internal access to SdrPage of SdrPageView
53  SdrPage* ObjectContactOfPageView::GetSdrPage() const
54  {
55  return GetPageWindow().GetPageView().GetPage();
56  }
57 
58  ObjectContactOfPageView::ObjectContactOfPageView(
59  SdrPageWindow& rPageWindow, const sal_Char *pDebugName)
60  : ObjectContact()
61  , Idle(pDebugName)
62  , mrPageWindow(rPageWindow)
63  {
64  // init PreviewRenderer flag
65  setPreviewRenderer(static_cast<SdrPaintView&>(rPageWindow.GetPageView().GetView()).IsPreviewRenderer());
66 
67  // init timer
68  SetPriority(TaskPriority::HIGH_IDLE);
69  Stop();
70  }
71 
73  {
74  // execute missing LazyInvalidates and stop timer
75  Invoke();
76  }
77 
78  // LazyInvalidate request. Take action.
80  {
81  // do NOT call parent, but remember that something is to do by
82  // starting the LazyInvalidateTimer
83  Start();
84  }
85 
86  // call this to support evtl. preparations for repaint
88  {
89  if(IsActive())
90  // there are still non-triggered LazyInvalidate events, trigger these
91  Invoke();
92  }
93 
94  // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
96  {
97  // stop the timer
98  Stop();
99 
100  // invalidate all LazyInvalidate VOCs new situations
101  const sal_uInt32 nVOCCount(getViewObjectContactCount());
102 
103  for(sal_uInt32 a(0); a < nVOCCount; a++)
104  {
106  pCandidate->triggerLazyInvalidate();
107  }
108  }
109 
110  // Process the whole displaying
112  {
113  const SdrPage* pStartPage = GetSdrPage();
114 
115  if(pStartPage && !rDisplayInfo.GetProcessLayers().IsEmpty())
116  {
117  const ViewContact& rDrawPageVC = pStartPage->GetViewContact();
118 
119  if(rDrawPageVC.GetObjectCount())
120  {
121  DoProcessDisplay(rDisplayInfo);
122  }
123  }
124  }
125 
126  // Process the whole displaying. Only use given DisplayInfo, do not access other
127  // OutputDevices then the given ones.
129  {
131  const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel());
132  if (!isOutputToRecordingMetaFile() // do those have outdev too?
133  && (0 == aOutputSizePixel.getWidth() ||
134  0 == aOutputSizePixel.getHeight()))
135  {
136  return;
137  }
138 
139  // visualize entered group when that feature is switched on and it's not
140  // a print output. #i29129# No ghosted display for printing.
141  bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter());
142 
143  // Visualize entered groups: Set to ghosted as default
144  // start. Do this only for the DrawPage, not for MasterPages
145  if(bVisualizeEnteredGroup)
146  {
147  rDisplayInfo.SetGhostedDrawMode();
148  }
149 
150  // #114359# save old and set clip region
151  OutputDevice* pOutDev = TryToGetOutputDevice();
152  OSL_ENSURE(nullptr != pOutDev, "ObjectContactOfPageView without OutDev, someone has overridden TryToGetOutputDevice wrong (!)");
153  bool bClipRegionPushed(false);
154  const vcl::Region& rRedrawArea(rDisplayInfo.GetRedrawArea());
155 
156  if(!rRedrawArea.IsEmpty() && !comphelper::LibreOfficeKit::isActive())
157  {
158  bClipRegionPushed = true;
159  pOutDev->Push(PushFlags::CLIPREGION);
160  pOutDev->IntersectClipRegion(rRedrawArea);
161  }
162 
163  // Get start node and process DrawPage contents
164  const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this);
165 
166  // update current ViewInformation2D at the ObjectContact
167  const double fCurrentTime(getPrimitiveAnimator().GetTime());
168  basegfx::B2DRange aViewRange;
169 
170  // create ViewRange
172  {
173  if (!rDisplayInfo.GetRedrawArea().IsEmpty())
174  {
175  // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is
176  // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this,
177  // all existing objects will be collected as primitives and processed.
178  // OD 2009-03-05 #i99876# perform the same also for SW on printing.
179  // fdo#78149 same thing also needed for plain MetaFile
180  // export, so why not do it always
181  const tools::Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
182 
183  aViewRange = vcl::unotools::b2DRectangleFromRectangle(aLogicClipRectangle);
184  }
185  }
186  else
187  {
188  // use visible pixels, but transform to world coordinates
189  aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
190  // if a clip region is set, use it
191  if(!rDisplayInfo.GetRedrawArea().IsEmpty())
192  {
193  // get logic clip range and create discrete one
194  const tools::Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
195  basegfx::B2DRange aLogicClipRange = vcl::unotools::b2DRectangleFromRectangle(aLogicClipRectangle);
196  basegfx::B2DRange aDiscreteClipRange(aLogicClipRange);
197  aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation());
198 
199  // align the discrete one to discrete boundaries (pixel bounds). Also
200  // expand X and Y max by one due to Rectangle definition source
201  aDiscreteClipRange.expand(basegfx::B2DTuple(
202  floor(aDiscreteClipRange.getMinX()),
203  floor(aDiscreteClipRange.getMinY())));
204  aDiscreteClipRange.expand(basegfx::B2DTuple(
205  1.0 + ceil(aDiscreteClipRange.getMaxX()),
206  1.0 + ceil(aDiscreteClipRange.getMaxY())));
207 
208  // intersect current ViewRange with ClipRange
209  aViewRange.intersect(aDiscreteClipRange);
210  }
211 
212  // transform to world coordinates
213  aViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
214  }
215 
216  // update local ViewInformation2D
217  const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D(
219  rTargetOutDev.GetViewTransformation(),
220  aViewRange,
222  fCurrentTime,
223  uno::Sequence<beans::PropertyValue>());
224  updateViewInformation2D(aNewViewInformation2D);
225 
227 #if HAVE_FEATURE_DESKTOP || defined( ANDROID )
228  // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D
229  // and may use the MapMode from the Target OutDev in the DisplayInfo
230  xPrimitiveSequence = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo);
231 #else
232  // Hmm, !HAVE_FEATURE_DESKTOP && !ANDROID means iOS,
233  // right? But does it makes sense to use a different code
234  // path for iOS than for Android; both use tiled rendering
235  // etc now.
236 
237  // HACK: this only works when we are drawing sdr shapes via
238  // drawinglayer; but it can happen that the hierarchy contains
239  // more than just the shapes, and then it fails.
240  //
241  // This is good enough for the tiled rendering for the moment, but
242  // we need to come up with the real solution shortly.
243 
244  // Only get the expensive hierarchy if we can be sure that the
245  // returned sequence won't be empty anyway.
246  bool bGetHierarchy = rRedrawArea.IsEmpty();
247  if (!bGetHierarchy)
248  {
249  // Not empty? Then not doing a full redraw, check if
250  // getPrimitive2DSequenceHierarchy() is still needed.
251  sal_Int32 nObjCount = GetSdrPage()->GetObjCount();
252  for (sal_Int32 i = 0; i < nObjCount; ++i)
253  {
255  if (rRedrawArea.IsOver(pObject->GetCurrentBoundRect()))
256  {
257  bGetHierarchy = true;
258  break;
259  }
260  }
261  }
262 
263  if (bGetHierarchy)
264  // get whole Primitive2DContainer; this will already make use of updated ViewInformation2D
265  // and may use the MapMode from the Target OutDev in the DisplayInfo
266  xPrimitiveSequence = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo);
267 #endif
268 
269  // if there is something to show, use a primitive processor to render it. There
270  // is a choice between VCL and Canvas processors currently. The decision is made in
271  // createProcessor2DFromOutputDevice and takes into account things like the
272  // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered
273  // currently using the shown boolean. Canvas is not yet the default.
274  if(!xPrimitiveSequence.empty())
275  {
276  // prepare OutputDevice (historical stuff, maybe soon removed)
277  rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing
278  pOutDev->SetLayoutMode(ComplexTextLayoutFlags::Default); // reset, default is no BiDi/RTL
279 
280  // Save the map-mode since creating the 2D processor will replace it.
281  const MapMode aOrigMapMode = pOutDev->GetMapMode();
282 
283  // create renderer
284  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
286  rTargetOutDev, getViewInformation2D()));
287 
288  if(pProcessor2D)
289  {
290  pProcessor2D->process(xPrimitiveSequence);
291  }
292  }
293 
294  // #114359# restore old ClipReghion
295  if(bClipRegionPushed)
296  {
297  pOutDev->Pop();
298  }
299 
300  // Visualize entered groups: Reset to original DrawMode
301  if(bVisualizeEnteredGroup)
302  {
303  rDisplayInfo.ClearGhostedDrawMode();
304  }
305  }
306 
307  // test if visualizing of entered groups is switched on at all
309  {
310  return true;
311  }
312 
313  // get active group's (the entered group) ViewContact
315  {
316  SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList();
317 
318  if(pActiveGroupList)
319  {
320  if(nullptr != pActiveGroupList->getSdrPageFromSdrObjList())
321  {
322  // It's a Page itself
323  return &(pActiveGroupList->getSdrPageFromSdrObjList()->GetViewContact());
324  }
325  else if(pActiveGroupList->getSdrObjectFromSdrObjList())
326  {
327  // Group object
328  return &(pActiveGroupList->getSdrObjectFromSdrObjList()->GetViewContact());
329  }
330  }
331  else if(GetSdrPage())
332  {
333  // use page of associated SdrPageView
334  return &(GetSdrPage()->GetViewContact());
335  }
336 
337  return nullptr;
338  }
339 
340  // Invalidate given rectangle at the window/output which is represented by
341  // this ObjectContact.
343  {
344  // invalidate at associated PageWindow
346  }
347 
348  // Get info about the need to visualize GluePoints
350  {
352  }
353 
354  // check if text animation is allowed.
356  {
358  return true;
359  SdrView& rView = GetPageWindow().GetPageView().GetView();
360  const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions();
361  return rOpt.GetIsAllowAnimatedText();
362  }
363 
364  // check if graphic animation is allowed.
366  {
368  return true;
369  SdrView& rView = GetPageWindow().GetPageView().GetView();
370  const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions();
371  return rOpt.GetIsAllowAnimatedGraphics();
372  }
373 
374  // print?
376  {
378  }
379 
380  // recording MetaFile?
382  {
384  return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
385  }
386 
387  // pdf export?
389  {
391  }
392 
393  // gray display mode
395  {
397  return (nDrawMode == (DrawModeFlags::GrayLine|DrawModeFlags::GrayFill|DrawModeFlags::BlackText|DrawModeFlags::GrayBitmap|DrawModeFlags::GrayGradient));
398  }
399 
400  // high contrast display mode
402  {
404  return (nDrawMode == (DrawModeFlags::SettingsLine|DrawModeFlags::SettingsFill|DrawModeFlags::SettingsText|DrawModeFlags::SettingsGradient));
405  }
406 
407  // access to SdrPageView
409  {
410  return &(mrPageWindow.GetPageView());
411  }
412 
413 
414  // access to OutputDevice
416  {
418 
419  if(pPreRenderDevice)
420  {
421  return &(pPreRenderDevice->GetPreRenderDevice());
422  }
423  else
424  {
426  }
427  }
428 
429  // set all UNO controls displayed in the view to design/alive mode
431  {
432  const sal_uInt32 nCount(getViewObjectContactCount());
433 
434  for(sal_uInt32 a(0); a < nCount; a++)
435  {
437  const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC);
438 
439  if(pUnoObjectVOC)
440  {
441  pUnoObjectVOC->setControlDesignMode(_bDesignMode);
442  }
443  }
444  }
445  } // end of namespace contact
446 } // end of namespace sdr
447 
448 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
basegfx::B2DHomMatrix GetInverseViewTransformation() const
OutDevType GetOutDevType() const
void expand(const B2DTuple &rTuple)
SdrPreRenderDevice * GetPreRenderDevice() const
const vcl::Region & GetRedrawArea() const
Definition: displayinfo.hxx:79
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:881
DrawModeFlags
virtual bool AreGluePointsVisible() const override
void setControlDesignMode(bool _bDesignMode) const
sets the design/alive mode of the control
SdrView & GetView()
Definition: svdpagv.hxx:137
OutputDevice & GetPreRenderDevice()
virtual bool isDrawModeHighContrast() const override
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:773
Any GetTime(const OUString &val)
virtual drawinglayer::primitive2d::Primitive2DContainer getPrimitive2DSequenceHierarchy(DisplayInfo &rDisplayInfo) const
size_t GetObjCount() const
Definition: svdpage.cxx:767
bool IsEmpty() const
Definition: svdlayer.cxx:27
const MapMode & GetMapMode() const
ViewObjectContact & GetViewObjectContact(ObjectContact &rObjectContact)
Definition: viewcontact.cxx:73
void SetLayoutMode(ComplexTextLayoutFlags nTextLayoutMode)
void IntersectClipRegion(const tools::Rectangle &rRect)
GDIMetaFile * GetConnectMetaFile() const
bool IsRecord() const
virtual bool isOutputToPDFFile() const override
tools::Rectangle GetBoundRect() const
EmbeddedObjectRef * pObject
double getMaxX() const
void setPreviewRenderer(bool bNew)
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:271
bool IsActive() const
void updateViewInformation2D(const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix &rMatrix)
OutputDevice & GetTargetOutputDevice()
char sal_Char
static bool IsFuzzing()
int nCount
virtual void Start() override
const SdrLayerIDSet & GetProcessLayers() const
Definition: displayinfo.hxx:75
double getMaxY() const
void SetUNOControlsDesignMode(bool _bDesignMode) const
sets all UNO controls which are associated with this ObjectContact to design or alive mode...
virtual bool IsGraphicAnimationAllowed() const override
bool GetIsAllowAnimatedGraphics() const
sdr::animation::primitiveAnimator & getPrimitiveAnimator()
SdrObjList * GetObjList() const
Return current List.
Definition: svdpagv.hxx:176
OUTDEV_PRINTER
bool IsEmpty() const
virtual void setLazyInvalidate(ViewObjectContact &rVOC) override
uno_Any a
const drawinglayer::geometry::ViewInformation2D & getViewInformation2D() const
bool ImpIsGlueVisible()
Definition: svdpntv.hxx:250
OUTDEV_PDF
int i
virtual bool DoVisualizeEnteredGroup() const override
virtual SdrPageView * TryToGetSdrPageView() const override
access to SdrPageView. May return 0L like the default implementations do. Override as needed...
virtual void InvalidatePartOfView(const basegfx::B2DRange &rRange) const override
ViewObjectContact * getViewObjectContact(sal_uInt32 a) const
Size GetOutputSizePixel() const
DrawModeFlags GetDrawMode() const
Abstract DrawObject.
Definition: svdobj.hxx:312
void DoProcessDisplay(DisplayInfo &rDisplayInfo)
void intersect(const B2DRange &rRange)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
bool IsPause() const
virtual sal_uInt32 GetObjectCount() const
double getMinY() const
void Stop()
sal_uInt32 getViewObjectContactCount() const
const sdr::contact::ViewContact & GetViewContact() const
Definition: svdpage.cxx:1124
virtual bool isOutputToRecordingMetaFile() const override
SdrPaintWindow & GetPaintWindow() const
bool GetIsAllowAnimatedText() const
virtual void ProcessDisplay(DisplayInfo &rDisplayInfo) override
void InvalidatePageWindow(const basegfx::B2DRange &rRange)
virtual OutputDevice * TryToGetOutputDevice() const override
access to OutputDevice. May return 0L like the default implementations do. Override as needed...
virtual SdrPage * getSdrPageFromSdrObjList() const
Definition: svdpage.cxx:146
uno::Reference< drawing::XDrawPage > GetXDrawPageForSdrPage(SdrPage *pPage)
returns a StarOffice API wrapper for the given SdrPage
Definition: unopage.cxx:885
virtual bool isOutputToPrinter() const override
virtual bool IsTextAnimationAllowed() const override
virtual const ViewContact * getActiveViewContact() const override
double getMinX() const
void SetPriority(TaskPriority ePriority)
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:366
virtual bool isDrawModeGray() const override
SvtAccessibilityOptions & getAccessibilityOptions()
Definition: svdview.hxx:235
void Push(PushFlags nFlags=PushFlags::ALL)
basegfx::B2DHomMatrix GetViewTransformation() const
virtual SdrObject * getSdrObjectFromSdrObjList() const
Definition: svdpage.cxx:152
OutputDevice & GetOutputDevice() const
SdrPageView & GetPageView() const