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