Line data Source code
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 <svx/sdr/contact/objectcontactofpageview.hxx>
21 : #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx>
22 : #include <svx/svdpagv.hxx>
23 : #include <svx/svdpage.hxx>
24 : #include <svx/sdr/contact/displayinfo.hxx>
25 : #include <svx/sdr/contact/viewobjectcontact.hxx>
26 : #include <svx/svdview.hxx>
27 : #include <svx/sdr/contact/viewcontact.hxx>
28 : #include <svx/sdr/animation/objectanimator.hxx>
29 : #include <svx/sdr/event/eventhandler.hxx>
30 : #include <svx/sdrpagewindow.hxx>
31 : #include <svx/sdrpaintwindow.hxx>
32 : #include <basegfx/matrix/b2dhommatrix.hxx>
33 : #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
34 : #include <com/sun/star/rendering/XSpriteCanvas.hpp>
35 : #include <drawinglayer/processor2d/processor2dtools.hxx>
36 : #include <svx/unoapi.hxx>
37 :
38 : //////////////////////////////////////////////////////////////////////////////
39 :
40 : using namespace com::sun::star;
41 :
42 : //////////////////////////////////////////////////////////////////////////////
43 :
44 : namespace sdr
45 : {
46 : namespace contact
47 : {
48 : // internal access to SdrPage of SdrPageView
49 69342 : SdrPage* ObjectContactOfPageView::GetSdrPage() const
50 : {
51 69342 : return GetPageWindow().GetPageView().GetPage();
52 : }
53 :
54 1214 : ObjectContactOfPageView::ObjectContactOfPageView(SdrPageWindow& rPageWindow)
55 : : ObjectContact(),
56 1214 : mrPageWindow(rPageWindow)
57 : {
58 : // init PreviewRenderer flag
59 1214 : setPreviewRenderer(((SdrPaintView&)rPageWindow.GetPageView().GetView()).IsPreviewRenderer());
60 :
61 : // init timer
62 1214 : SetTimeout(1);
63 1214 : Stop();
64 1214 : }
65 :
66 3642 : ObjectContactOfPageView::~ObjectContactOfPageView()
67 : {
68 : // execute missing LazyInvalidates and stop timer
69 1214 : Timeout();
70 2428 : }
71 :
72 : // LazyInvalidate request. Take action.
73 5492 : void ObjectContactOfPageView::setLazyInvalidate(ViewObjectContact& /*rVOC*/)
74 : {
75 : // do NOT call parent, but remember that something is to do by
76 : // starting the LazyInvalidateTimer
77 5492 : Start();
78 5492 : }
79 :
80 : // call this to support evtl. preparations for repaint
81 12828 : void ObjectContactOfPageView::PrepareProcessDisplay()
82 : {
83 12828 : if(IsActive())
84 : {
85 : static bool bInvalidateDuringPaint(true);
86 :
87 1315 : if(bInvalidateDuringPaint)
88 : {
89 : // there are still non-triggered LazyInvalidate events, trigger these
90 1315 : Timeout();
91 : }
92 : }
93 12828 : }
94 :
95 : // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism
96 4590 : void ObjectContactOfPageView::Timeout()
97 : {
98 : // stop the timer
99 4590 : Stop();
100 :
101 : // invalidate all LazyInvalidate VOCs new situations
102 4590 : const sal_uInt32 nVOCCount(getViewObjectContactCount());
103 :
104 95034 : for(sal_uInt32 a(0); a < nVOCCount; a++)
105 : {
106 90444 : ViewObjectContact* pCandidate = getViewObjectContact(a);
107 90444 : pCandidate->triggerLazyInvalidate();
108 : }
109 4590 : }
110 :
111 : // Process the whole displaying
112 23114 : void ObjectContactOfPageView::ProcessDisplay(DisplayInfo& rDisplayInfo)
113 : {
114 23114 : const SdrPage* pStartPage = GetSdrPage();
115 :
116 23114 : if(pStartPage && !rDisplayInfo.GetProcessLayers().IsEmpty())
117 : {
118 23114 : const ViewContact& rDrawPageVC = pStartPage->GetViewContact();
119 :
120 23114 : if(rDrawPageVC.GetObjectCount())
121 : {
122 23114 : DoProcessDisplay(rDisplayInfo);
123 : }
124 : }
125 :
126 : // after paint take care of the evtl. scheduled asynchronious commands.
127 : // Do this by resetting the timer contained there. Thus, after the paint
128 : // that timer will be triggered and the events will be executed.
129 23114 : if(HasEventHandler())
130 : {
131 0 : sdr::event::TimerEventHandler& rEventHandler = GetEventHandler();
132 :
133 0 : if(!rEventHandler.IsEmpty())
134 : {
135 0 : rEventHandler.Restart();
136 : }
137 : }
138 23114 : }
139 :
140 : // Process the whole displaying. Only use given DsiplayInfo, do not access other
141 : // OutputDevices then the given ones.
142 23114 : void ObjectContactOfPageView::DoProcessDisplay(DisplayInfo& rDisplayInfo)
143 : {
144 : // visualize entered group when that feature is switched on and it's not
145 : // a print output. #i29129# No ghosted display for printing.
146 23114 : bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter());
147 :
148 : // Visualize entered groups: Set to ghosted as default
149 : // start. Do this only for the DrawPage, not for MasterPages
150 23114 : if(bVisualizeEnteredGroup)
151 : {
152 23114 : rDisplayInfo.SetGhostedDrawMode();
153 : }
154 :
155 : // #114359# save old and set clip region
156 23114 : OutputDevice* pOutDev = TryToGetOutputDevice();
157 : OSL_ENSURE(0 != pOutDev, "ObjectContactOfPageView without OutDev, someone has overloaded TryToGetOutputDevice wrong (!)");
158 23114 : bool bClipRegionPushed(false);
159 23114 : const Region& rRedrawArea(rDisplayInfo.GetRedrawArea());
160 :
161 23114 : if(!rRedrawArea.IsEmpty())
162 : {
163 23114 : bClipRegionPushed = true;
164 23114 : pOutDev->Push(PUSH_CLIPREGION);
165 23114 : pOutDev->IntersectClipRegion(rRedrawArea);
166 : }
167 :
168 : // Get start node and process DrawPage contents
169 23114 : const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this);
170 :
171 : // update current ViewInformation2D at the ObjectContact
172 23114 : const double fCurrentTime(getPrimitiveAnimator().GetTime());
173 23114 : OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice();
174 23114 : basegfx::B2DRange aViewRange;
175 :
176 : // create ViewRange
177 23114 : if(isOutputToRecordingMetaFile())
178 : {
179 65 : if(isOutputToPDFFile() || isOutputToPrinter())
180 : {
181 : // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is
182 : // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this,
183 : // all existing objects will be collected as primitives and processed.
184 : // OD 2009-03-05 #i99876# perform the same also for SW on printing.
185 0 : const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
186 :
187 : aViewRange = basegfx::B2DRange(
188 0 : aLogicClipRectangle.Left(), aLogicClipRectangle.Top(),
189 0 : aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom());
190 : }
191 : }
192 : else
193 : {
194 : // use visible pixels, but transform to world coordinates
195 23049 : const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel());
196 23049 : aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
197 :
198 : // if a clip region is set, use it
199 23049 : if(!rDisplayInfo.GetRedrawArea().IsEmpty())
200 : {
201 : // get logic clip range and create discrete one
202 23049 : const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect());
203 : basegfx::B2DRange aLogicClipRange(
204 46098 : aLogicClipRectangle.Left(), aLogicClipRectangle.Top(),
205 69147 : aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom());
206 23049 : basegfx::B2DRange aDiscreteClipRange(aLogicClipRange);
207 23049 : aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation());
208 :
209 : // align the discrete one to discrete boundaries (pixel bounds). Also
210 : // expand X and Y max by one due to Rectangle definition source
211 : aDiscreteClipRange.expand(basegfx::B2DTuple(
212 : floor(aDiscreteClipRange.getMinX()),
213 23049 : floor(aDiscreteClipRange.getMinY())));
214 : aDiscreteClipRange.expand(basegfx::B2DTuple(
215 23049 : 1.0 + ceil(aDiscreteClipRange.getMaxX()),
216 46098 : 1.0 + ceil(aDiscreteClipRange.getMaxY())));
217 :
218 : // intersect current ViewRange with ClipRange
219 23049 : aViewRange.intersect(aDiscreteClipRange);
220 : }
221 :
222 : // transform to world coordinates
223 23049 : aViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
224 : }
225 :
226 : // update local ViewInformation2D
227 : const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D(
228 : basegfx::B2DHomMatrix(),
229 : rTargetOutDev.GetViewTransformation(),
230 : aViewRange,
231 : GetXDrawPageForSdrPage(GetSdrPage()),
232 : fCurrentTime,
233 23114 : uno::Sequence<beans::PropertyValue>());
234 23114 : updateViewInformation2D(aNewViewInformation2D);
235 :
236 : // get whole Primitive2DSequence; this will already make use of updated ViewInformation2D
237 : // and may use the MapMode from the Target OutDev in the DisplayInfo
238 46228 : drawinglayer::primitive2d::Primitive2DSequence xPrimitiveSequence(rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo));
239 :
240 : // if there is something to show, use a primitive processor to render it. There
241 : // is a choice between VCL and Canvas processors currently. The decision is made in
242 : // createProcessor2DFromOutputDevice and takes into accout things like the
243 : // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered
244 : // currently using the shown boolean. Canvas is not yet the default.
245 23114 : if(xPrimitiveSequence.hasElements())
246 : {
247 : // prepare OutputDevice (historical stuff, maybe soon removed)
248 2915 : rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing
249 2915 : pOutDev->SetLayoutMode(0); // reset, default is no BiDi/RTL
250 :
251 : // create renderer
252 : drawinglayer::processor2d::BaseProcessor2D* pProcessor2D =
253 : drawinglayer::processor2d::createProcessor2DFromOutputDevice(
254 2915 : rTargetOutDev, getViewInformation2D());
255 :
256 2915 : if(pProcessor2D)
257 : {
258 2915 : pProcessor2D->process(xPrimitiveSequence);
259 2915 : delete pProcessor2D;
260 : }
261 : }
262 :
263 : // #114359# restore old ClipReghion
264 23114 : if(bClipRegionPushed)
265 : {
266 23114 : pOutDev->Pop();
267 : }
268 :
269 : // Visualize entered groups: Reset to original DrawMode
270 23114 : if(bVisualizeEnteredGroup)
271 : {
272 23114 : rDisplayInfo.ClearGhostedDrawMode();
273 23114 : }
274 23114 : }
275 :
276 : // test if visualizing of entered groups is switched on at all
277 70258 : bool ObjectContactOfPageView::DoVisualizeEnteredGroup() const
278 : {
279 70258 : SdrView& rView = GetPageWindow().GetPageView().GetView();
280 70258 : return rView.DoVisualizeEnteredGroup();
281 : }
282 :
283 : // get active group's (the entered group) ViewContact
284 31589 : const ViewContact* ObjectContactOfPageView::getActiveViewContact() const
285 : {
286 31589 : SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList();
287 :
288 31589 : if(pActiveGroupList)
289 : {
290 31589 : if(pActiveGroupList->ISA(SdrPage))
291 : {
292 : // It's a Page itself
293 31589 : return &(((SdrPage*)pActiveGroupList)->GetViewContact());
294 : }
295 0 : else if(pActiveGroupList->GetOwnerObj())
296 : {
297 : // Group object
298 0 : return &(pActiveGroupList->GetOwnerObj()->GetViewContact());
299 : }
300 : }
301 0 : else if(GetSdrPage())
302 : {
303 : // use page of associated SdrPageView
304 0 : return &(GetSdrPage()->GetViewContact());
305 : }
306 :
307 0 : return 0;
308 : }
309 :
310 : // Invalidate given rectangle at the window/output which is represented by
311 : // this ObjectContact.
312 9986 : void ObjectContactOfPageView::InvalidatePartOfView(const basegfx::B2DRange& rRange) const
313 : {
314 : // invalidate at associated PageWindow
315 9986 : GetPageWindow().InvalidatePageWindow(rRange);
316 9986 : }
317 :
318 : // Get info if given Rectangle is visible in this view
319 0 : bool ObjectContactOfPageView::IsAreaVisible(const basegfx::B2DRange& rRange) const
320 : {
321 : // compare with the visible rectangle
322 0 : if(rRange.isEmpty())
323 : {
324 : // no range -> not visible
325 0 : return false;
326 : }
327 : else
328 : {
329 0 : const OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice();
330 0 : const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel());
331 0 : basegfx::B2DRange aLogicViewRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
332 :
333 0 : aLogicViewRange.transform(rTargetOutDev.GetInverseViewTransformation());
334 :
335 0 : if(!aLogicViewRange.isEmpty() && !aLogicViewRange.overlaps(rRange))
336 : {
337 0 : return false;
338 : }
339 : }
340 :
341 : // call parent
342 0 : return ObjectContact::IsAreaVisible(rRange);
343 : }
344 :
345 : // Get info about the need to visualize GluePoints
346 18056 : bool ObjectContactOfPageView::AreGluePointsVisible() const
347 : {
348 18056 : return GetPageWindow().GetPageView().GetView().ImpIsGlueVisible();
349 : }
350 :
351 : // check if text animation is allowed.
352 18240 : bool ObjectContactOfPageView::IsTextAnimationAllowed() const
353 : {
354 18240 : SdrView& rView = GetPageWindow().GetPageView().GetView();
355 18240 : const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions();
356 18240 : return rOpt.GetIsAllowAnimatedText();
357 : }
358 :
359 : // check if graphic animation is allowed.
360 18240 : bool ObjectContactOfPageView::IsGraphicAnimationAllowed() const
361 : {
362 18240 : SdrView& rView = GetPageWindow().GetPageView().GetView();
363 18240 : const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions();
364 18240 : return rOpt.GetIsAllowAnimatedGraphics();
365 : }
366 :
367 : // check if asynchronious graphis loading is allowed. Default is sal_False.
368 0 : bool ObjectContactOfPageView::IsAsynchronGraphicsLoadingAllowed() const
369 : {
370 0 : SdrView& rView = GetPageWindow().GetPageView().GetView();
371 0 : return rView.IsSwapAsynchron();
372 : }
373 :
374 : // check if buffering of MasterPages is allowed. Default is sal_False.
375 0 : bool ObjectContactOfPageView::IsMasterPageBufferingAllowed() const
376 : {
377 0 : SdrView& rView = GetPageWindow().GetPageView().GetView();
378 0 : return rView.IsMasterPagePaintCaching();
379 : }
380 :
381 : // print?
382 125666 : bool ObjectContactOfPageView::isOutputToPrinter() const
383 : {
384 125666 : return (OUTDEV_PRINTER == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType());
385 : }
386 :
387 : // window?
388 0 : bool ObjectContactOfPageView::isOutputToWindow() const
389 : {
390 0 : return (OUTDEV_WINDOW == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType());
391 : }
392 :
393 : // VirtualDevice?
394 0 : bool ObjectContactOfPageView::isOutputToVirtualDevice() const
395 : {
396 0 : return (OUTDEV_VIRDEV == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType());
397 : }
398 :
399 : // recording MetaFile?
400 23114 : bool ObjectContactOfPageView::isOutputToRecordingMetaFile() const
401 : {
402 23114 : GDIMetaFile* pMetaFile = mrPageWindow.GetPaintWindow().GetOutputDevice().GetConnectMetaFile();
403 23114 : return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
404 : }
405 :
406 : // pdf export?
407 1230 : bool ObjectContactOfPageView::isOutputToPDFFile() const
408 : {
409 1230 : return (0 != mrPageWindow.GetPaintWindow().GetOutputDevice().GetPDFWriter());
410 : }
411 :
412 : // gray display mode
413 618 : bool ObjectContactOfPageView::isDrawModeGray() const
414 : {
415 618 : const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode());
416 618 : return (nDrawMode == (DRAWMODE_GRAYLINE|DRAWMODE_GRAYFILL|DRAWMODE_BLACKTEXT|DRAWMODE_GRAYBITMAP|DRAWMODE_GRAYGRADIENT));
417 : }
418 :
419 : // gray display mode
420 0 : bool ObjectContactOfPageView::isDrawModeBlackWhite() const
421 : {
422 0 : const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode());
423 0 : return (nDrawMode == (DRAWMODE_BLACKLINE|DRAWMODE_BLACKTEXT|DRAWMODE_WHITEFILL|DRAWMODE_GRAYBITMAP|DRAWMODE_WHITEGRADIENT));
424 : }
425 :
426 : // high contrast display mode
427 1100 : bool ObjectContactOfPageView::isDrawModeHighContrast() const
428 : {
429 1100 : const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode());
430 1100 : return (nDrawMode == (DRAWMODE_SETTINGSLINE|DRAWMODE_SETTINGSFILL|DRAWMODE_SETTINGSTEXT|DRAWMODE_SETTINGSGRADIENT));
431 : }
432 :
433 : // access to SdrPageView
434 48058 : SdrPageView* ObjectContactOfPageView::TryToGetSdrPageView() const
435 : {
436 48058 : return &(mrPageWindow.GetPageView());
437 : }
438 :
439 :
440 : // access to OutputDevice
441 23389 : OutputDevice* ObjectContactOfPageView::TryToGetOutputDevice() const
442 : {
443 23389 : SdrPreRenderDevice* pPreRenderDevice = mrPageWindow.GetPaintWindow().GetPreRenderDevice();
444 :
445 23389 : if(pPreRenderDevice)
446 : {
447 1044 : return &(pPreRenderDevice->GetPreRenderDevice());
448 : }
449 : else
450 : {
451 22345 : return &(mrPageWindow.GetPaintWindow().GetOutputDevice());
452 : }
453 : }
454 :
455 : // set all UNO controls displayed in the view to design/alive mode
456 6 : void ObjectContactOfPageView::SetUNOControlsDesignMode( bool _bDesignMode ) const
457 : {
458 6 : const sal_uInt32 nCount(getViewObjectContactCount());
459 :
460 33 : for(sal_uInt32 a(0); a < nCount; a++)
461 : {
462 27 : const ViewObjectContact* pVOC = getViewObjectContact(a);
463 27 : const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC);
464 :
465 27 : if(pUnoObjectVOC)
466 : {
467 3 : pUnoObjectVOC->setControlDesignMode(_bDesignMode);
468 : }
469 : }
470 6 : }
471 : } // end of namespace contact
472 258 : } // end of namespace sdr
473 :
474 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|