Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svx/sdr/overlay/overlaymanagerbuffered.hxx>
30 : : #include <vcl/outdev.hxx>
31 : : #include <basegfx/point/b2dpoint.hxx>
32 : : #include <basegfx/range/b2drange.hxx>
33 : : #include <vcl/window.hxx>
34 : : #include <vcl/bitmap.hxx>
35 : : #include <tools/stream.hxx>
36 : : #include <basegfx/matrix/b2dhommatrix.hxx>
37 : : #include <vcl/cursor.hxx>
38 : :
39 : : //////////////////////////////////////////////////////////////////////////////
40 : :
41 : : namespace sdr
42 : : {
43 : : namespace overlay
44 : : {
45 : 15563 : void OverlayManagerBuffered::ImpPrepareBufferDevice()
46 : : {
47 : : // compare size of maBufferDevice with size of visible area
48 [ + + ]: 15563 : if(maBufferDevice.GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel())
49 : : {
50 : : // set new buffer size, copy as much content as possible (use bool parameter for vcl).
51 : : // Newly uncovered regions will be repainted.
52 [ + - ]: 1269 : maBufferDevice.SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false);
53 : : }
54 : :
55 : : // compare the MapModes for zoom/scroll changes
56 [ + + ]: 15563 : if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode())
57 : : {
58 : : const bool bZoomed(
59 : 1692 : maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX()
60 [ + + ][ + + ]: 1692 : || maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY());
61 : :
62 [ + + ]: 1692 : if(!bZoomed)
63 : : {
64 : 1257 : const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin();
65 : 1257 : const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin();
66 : 1257 : const bool bScrolled(rOriginOld != rOriginNew);
67 : :
68 [ + + ]: 1257 : if(bScrolled)
69 : : {
70 : : // get pixel bounds
71 [ + - ]: 425 : const Point aOriginOldPixel(maBufferDevice.LogicToPixel(rOriginOld));
72 [ + - ]: 425 : const Point aOriginNewPixel(maBufferDevice.LogicToPixel(rOriginNew));
73 : 425 : const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel());
74 : :
75 : : // remember and switch off MapMode
76 : 425 : const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled());
77 [ + - ]: 425 : maBufferDevice.EnableMapMode(false);
78 : :
79 : : // scroll internally buffered stuff
80 : 425 : const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel);
81 : : maBufferDevice.DrawOutDev(
82 : : aDestinationOffsetPixel, aOutputSizePixel, // destination
83 [ + - ]: 425 : Point(), aOutputSizePixel); // source
84 : :
85 : : // restore MapMode
86 [ + - ]: 425 : maBufferDevice.EnableMapMode(bMapModeWasEnabled);
87 : :
88 : : // scroll remembered region, too.
89 [ + - ][ + + ]: 425 : if(!maBufferRememberedRangePixel.isEmpty())
90 : : {
91 : 8 : const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y());
92 [ + - ][ + - ]: 8 : const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel);
93 [ + - ][ + - ]: 8 : const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel);
94 [ + - ]: 425 : maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum);
95 : : }
96 : : }
97 : : }
98 : :
99 : : // copy new MapMode
100 : 1692 : maBufferDevice.SetMapMode(getOutputDevice().GetMapMode());
101 : : }
102 : :
103 : : // #i29186#
104 : 15563 : maBufferDevice.SetDrawMode(getOutputDevice().GetDrawMode());
105 : 15563 : maBufferDevice.SetSettings(getOutputDevice().GetSettings());
106 : 15563 : maBufferDevice.SetAntialiasing(getOutputDevice().GetAntialiasing());
107 : 15563 : }
108 : :
109 : 60 : void OverlayManagerBuffered::ImpRestoreBackground() const
110 : : {
111 : : const Rectangle aRegionRectanglePixel(
112 : : maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
113 [ + - ][ + - ]: 60 : maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
[ + - ][ + - ]
[ + - ]
114 [ + - ]: 60 : const Region aRegionPixel(aRegionRectanglePixel);
115 : :
116 [ + - ][ + - ]: 60 : ImpRestoreBackground(aRegionPixel);
117 : 60 : }
118 : :
119 : 60 : void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const
120 : : {
121 : : // local region
122 [ + - ]: 60 : Region aRegionPixel(rRegionPixel);
123 [ + - ]: 60 : RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
124 [ + - ]: 60 : Rectangle aRegionRectanglePixel;
125 : :
126 : : // MapModes off
127 : 60 : const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
128 : 60 : const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
129 [ + - ]: 60 : getOutputDevice().EnableMapMode(false);
130 [ + - ]: 60 : ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false);
131 : :
132 [ + - ][ + + ]: 120 : while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
133 : : {
134 : : #ifdef DBG_UTIL
135 : : // #i72754# possible graphical region test only with non-pro
136 : : static bool bDoPaintForVisualControl(false);
137 : : if(bDoPaintForVisualControl)
138 : : {
139 : : getOutputDevice().SetLineColor(COL_LIGHTGREEN);
140 : : getOutputDevice().SetFillColor();
141 : : getOutputDevice().DrawRect(aRegionRectanglePixel);
142 : : }
143 : : #endif
144 : :
145 : : // restore the area
146 : 60 : const Point aTopLeft(aRegionRectanglePixel.TopLeft());
147 [ + - ]: 60 : const Size aSize(aRegionRectanglePixel.GetSize());
148 : :
149 : 60 : getOutputDevice().DrawOutDev(
150 : : aTopLeft, aSize, // destination
151 : : aTopLeft, aSize, // source
152 [ + - ]: 60 : maBufferDevice);
153 : : }
154 : :
155 [ + - ]: 60 : aRegionPixel.EndEnumRects(aRegionHandle);
156 : :
157 : : // restore MapModes
158 [ + - ]: 60 : getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
159 [ + - ][ + - ]: 60 : ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(bMapModeWasEnabledSource);
160 : 60 : }
161 : :
162 : 15563 : void OverlayManagerBuffered::ImpSaveBackground(const Region& rRegion, OutputDevice* pPreRenderDevice)
163 : : {
164 : : // prepare source
165 [ - + ]: 15563 : OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
166 : :
167 : : // Ensure buffer is valid
168 [ + - ]: 15563 : ImpPrepareBufferDevice();
169 : :
170 : : // build region which needs to be copied
171 [ + - ]: 15563 : Region aRegion(rSource.LogicToPixel(rRegion));
172 : :
173 : : // limit to PaintRegion if it's a window. This will be evtl. the expanded one,
174 : : // but always the exact redraw area
175 [ - + ]: 15563 : if(OUTDEV_WINDOW == rSource.GetOutDevType())
176 : : {
177 : 0 : Window& rWindow = (Window&)rSource;
178 [ # # ][ # # ]: 0 : Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion());
[ # # ]
179 [ # # ]: 0 : aRegion.Intersect(aPaintRegionPixel);
180 : :
181 : : // #i72754# Make sure content is completetly rendered, the window
182 : : // will be used as source of a DrawOutDev soon
183 [ # # ][ # # ]: 0 : rWindow.Flush();
184 : : }
185 : :
186 : : // also limit to buffer size
187 [ + - ]: 15563 : const Rectangle aBufferDeviceRectanglePixel = Rectangle(Point(), maBufferDevice.GetOutputSizePixel());
188 [ + - ]: 15563 : aRegion.Intersect(aBufferDeviceRectanglePixel);
189 : :
190 : : // prepare to iterate over the rectangles from the region in pixels
191 [ + - ]: 15563 : RegionHandle aRegionHandle(aRegion.BeginEnumRects());
192 [ + - ]: 15563 : Rectangle aRegionRectanglePixel;
193 : :
194 : : // MapModes off
195 : 15563 : const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled());
196 : 15563 : const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
197 [ + - ]: 15563 : rSource.EnableMapMode(false);
198 [ + - ]: 15563 : maBufferDevice.EnableMapMode(false);
199 : :
200 [ + - ][ + + ]: 31611 : while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
201 : : {
202 : : // for each rectangle, save the area
203 : 16048 : Point aTopLeft(aRegionRectanglePixel.TopLeft());
204 [ + - ]: 16048 : Size aSize(aRegionRectanglePixel.GetSize());
205 : :
206 : : maBufferDevice.DrawOutDev(
207 : : aTopLeft, aSize, // destination
208 : : aTopLeft, aSize, // source
209 [ + - ]: 16048 : rSource);
210 : : }
211 : :
212 [ + - ]: 15563 : aRegion.EndEnumRects(aRegionHandle);
213 : :
214 : : // restore MapModes
215 [ + - ]: 15563 : rSource.EnableMapMode(bMapModeWasEnabledDest);
216 [ + - ][ + - ]: 15563 : maBufferDevice.EnableMapMode(bMapModeWasEnabledSource);
217 : 15563 : }
218 : :
219 : 1123 : IMPL_LINK(OverlayManagerBuffered, ImpBufferTimerHandler, AutoTimer*, /*pTimer*/)
220 : : {
221 : : //Resolves: fdo#46728 ensure this exists until end of scope
222 [ + - ]: 1123 : rtl::Reference<OverlayManager> xRef(this);
223 : :
224 : : // stop timer
225 [ + - ]: 1123 : maBufferTimer.Stop();
226 : :
227 [ + - ][ + - ]: 1123 : if(!maBufferRememberedRangePixel.isEmpty())
228 : : {
229 : : // logic size for impDrawMember call
230 : : basegfx::B2DRange aBufferRememberedRangeLogic(
231 [ + - ][ + - ]: 1123 : maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
232 [ + - ][ + - ]: 2246 : maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
[ + - ]
233 [ + - ][ + - ]: 1123 : aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation());
[ + - ]
234 : :
235 : : // prepare cursor handling
236 : 1123 : const bool bTargetIsWindow(OUTDEV_WINDOW == rmOutputDevice.GetOutDevType());
237 : 1123 : bool bCursorWasEnabled(false);
238 : :
239 : : // #i80730# switch off VCL cursor during overlay refresh
240 [ + - ]: 1123 : if(bTargetIsWindow)
241 : : {
242 : 1123 : Window& rWindow = static_cast< Window& >(rmOutputDevice);
243 [ + - ]: 1123 : Cursor* pCursor = rWindow.GetCursor();
244 : :
245 [ + + ][ + - ]: 1123 : if(pCursor && pCursor->IsVisible())
[ + + ]
246 : : {
247 [ + - ]: 171 : pCursor->Hide();
248 : 171 : bCursorWasEnabled = true;
249 : : }
250 : : }
251 : :
252 [ + - ]: 1123 : if(DoRefreshWithPreRendering())
253 : : {
254 : : // #i73602# ensure valid and sized maOutputBufferDevice
255 : 1123 : const Size aDestinationSizePixel(maBufferDevice.GetOutputSizePixel());
256 : 1123 : const Size aOutputBufferSizePixel(maOutputBufferDevice.GetOutputSizePixel());
257 : :
258 [ + + ]: 1123 : if(aDestinationSizePixel != aOutputBufferSizePixel)
259 : : {
260 [ + - ]: 134 : maOutputBufferDevice.SetOutputSizePixel(aDestinationSizePixel);
261 : : }
262 : :
263 [ + - ]: 1123 : maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode());
264 [ + - ]: 1123 : maOutputBufferDevice.EnableMapMode(false);
265 [ + - ]: 1123 : maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode());
266 [ + - ]: 1123 : maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings());
267 [ + - ]: 1123 : maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing());
268 : :
269 : : // calculate sizes
270 : : Rectangle aRegionRectanglePixel(
271 : : maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
272 [ + - ][ + - ]: 1123 : maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
[ + - ][ + - ]
[ + - ]
273 : :
274 : : // truncate aRegionRectanglePixel to destination pixel size, more does
275 : : // not need to be prepared since destination is a buffer for a window. So,
276 : : // maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel()
277 [ + + ]: 1123 : if(aRegionRectanglePixel.Left() < 0L)
278 : : {
279 : 948 : aRegionRectanglePixel.Left() = 0L;
280 : : }
281 : :
282 [ + + ]: 1123 : if(aRegionRectanglePixel.Top() < 0L)
283 : : {
284 : 950 : aRegionRectanglePixel.Top() = 0L;
285 : : }
286 : :
287 [ + + ]: 1123 : if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth())
288 : : {
289 : 774 : aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth();
290 : : }
291 : :
292 [ + + ]: 1123 : if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight())
293 : : {
294 : 771 : aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight();
295 : : }
296 : :
297 : : // get sizes
298 : 1123 : const Point aTopLeft(aRegionRectanglePixel.TopLeft());
299 [ + - ]: 1123 : const Size aSize(aRegionRectanglePixel.GetSize());
300 : :
301 : : {
302 : 1123 : const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled());
303 [ + - ]: 1123 : maBufferDevice.EnableMapMode(false);
304 : :
305 : : maOutputBufferDevice.DrawOutDev(
306 : : aTopLeft, aSize, // destination
307 : : aTopLeft, aSize, // source
308 [ + - ]: 1123 : maBufferDevice);
309 : :
310 : : // restore MapModes
311 [ + - ]: 1123 : maBufferDevice.EnableMapMode(bMapModeWasEnabledDest);
312 : : }
313 : :
314 : : // paint overlay content for remembered region, use
315 : : // method from base class directly
316 [ + - ]: 1123 : maOutputBufferDevice.EnableMapMode(true);
317 [ + - ]: 1123 : OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice);
318 [ + - ]: 1123 : maOutputBufferDevice.EnableMapMode(false);
319 : :
320 : : // copy to output
321 : : {
322 : 1123 : const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
323 [ + - ]: 1123 : getOutputDevice().EnableMapMode(false);
324 : :
325 : 1123 : getOutputDevice().DrawOutDev(
326 : : aTopLeft, aSize, // destination
327 : : aTopLeft, aSize, // source
328 [ + - ]: 1123 : maOutputBufferDevice);
329 : :
330 : : // debug
331 : : /*getOutputDevice().SetLineColor(COL_RED);
332 : : getOutputDevice().SetFillColor();
333 : : getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/
334 : :
335 : : // restore MapModes
336 [ + - ]: 1123 : getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
337 : : }
338 : : }
339 : : else
340 : : {
341 : : // Restore all rectangles for remembered region from buffer
342 [ # # ]: 0 : ImpRestoreBackground();
343 : :
344 : : // paint overlay content for remembered region, use
345 : : // method from base class directly
346 [ # # ]: 0 : OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice());
347 : : }
348 : :
349 : : // VCL hack for transparent child windows
350 : : // Problem is e.g. a radiobuttion form control in life mode. The used window
351 : : // is a transparence vcl childwindow. This flag only allows the parent window to
352 : : // paint into the child windows area, but there is no mechanism which takes
353 : : // care for a repaint of the child window. A transparent child window is NOT
354 : : // a window which always keeps it's content consistent over the parent, but it's
355 : : // more like just a paint flag for the parent.
356 : : // To get the update, the windows in question are updated manulally here.
357 [ + - ]: 1123 : if(bTargetIsWindow)
358 : : {
359 : 1123 : Window& rWindow = static_cast< Window& >(rmOutputDevice);
360 : :
361 [ + - ][ + + ]: 1123 : if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount())
[ + - ][ + + ]
[ + + ]
362 : : {
363 : : const Rectangle aRegionRectanglePixel(
364 : : maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
365 [ + - ][ + - ]: 7 : maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
[ + - ][ + - ]
[ + - ]
366 : :
367 [ + - ][ + + ]: 14 : for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++)
368 : : {
369 [ + - ]: 7 : Window* pCandidate = rWindow.GetChild(a);
370 : :
371 [ + - ][ + - ]: 7 : if(pCandidate && pCandidate->IsPaintTransparent())
[ - + ][ - + ]
372 : : {
373 [ # # ][ # # ]: 0 : const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel());
[ # # ]
374 : :
375 [ # # ][ # # ]: 0 : if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel))
376 : : {
377 [ # # ]: 0 : pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN);
378 [ # # ]: 0 : pCandidate->Update();
379 : : }
380 : : }
381 : : }
382 : : }
383 : : }
384 : :
385 : : // #i80730# restore visibility of VCL cursor
386 [ + + ]: 1123 : if(bCursorWasEnabled)
387 : : {
388 : 171 : Window& rWindow = static_cast< Window& >(rmOutputDevice);
389 [ + - ]: 171 : Cursor* pCursor = rWindow.GetCursor();
390 : :
391 [ + - ]: 171 : if(pCursor)
392 : : {
393 : : // check if cursor still exists. It may have been deleted from someone
394 [ + - ]: 171 : pCursor->Show();
395 : : }
396 : : }
397 : :
398 : : // forget remembered Region
399 [ + - ]: 1123 : maBufferRememberedRangePixel.reset();
400 : : }
401 : :
402 [ + - ]: 1123 : return 0;
403 : : }
404 : :
405 : 1260 : OverlayManagerBuffered::OverlayManagerBuffered(
406 : : OutputDevice& rOutputDevice,
407 : : OverlayManager* pOldOverlayManager,
408 : : bool bRefreshWithPreRendering)
409 : : : OverlayManager(rOutputDevice, pOldOverlayManager),
410 [ + - ][ + - ]: 1260 : mbRefreshWithPreRendering(bRefreshWithPreRendering)
[ + - ][ + - ]
411 : : {
412 : : // Init timer
413 [ + - ]: 1260 : maBufferTimer.SetTimeout(1);
414 [ + - ]: 1260 : maBufferTimer.SetTimeoutHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler));
415 : 1260 : }
416 : :
417 : 1260 : rtl::Reference<OverlayManager> OverlayManagerBuffered::create(
418 : : OutputDevice& rOutputDevice,
419 : : OverlayManager* pOldOverlayManager,
420 : : bool bRefreshWithPreRendering)
421 : : {
422 : : return rtl::Reference<OverlayManager>(new OverlayManagerBuffered(rOutputDevice,
423 [ + - ]: 1260 : pOldOverlayManager, bRefreshWithPreRendering));
424 : : }
425 : :
426 [ + - ][ + - ]: 1169 : OverlayManagerBuffered::~OverlayManagerBuffered()
[ + - ]
427 : : {
428 : : // Clear timer
429 [ + - ]: 1169 : maBufferTimer.Stop();
430 : :
431 [ + - ][ + + ]: 1169 : if(!maBufferRememberedRangePixel.isEmpty())
432 : : {
433 : : // Restore all rectangles for remembered region from buffer
434 [ + - ]: 60 : ImpRestoreBackground();
435 : : }
436 [ - + ]: 2338 : }
437 : :
438 : 15563 : void OverlayManagerBuffered::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const
439 : : {
440 [ + - ]: 15563 : if(!rRegion.IsEmpty())
441 : : {
442 : : // save new background
443 : 15563 : ((OverlayManagerBuffered*)this)->ImpSaveBackground(rRegion, pPreRenderDevice);
444 : : }
445 : :
446 : : // call parent
447 : 15563 : OverlayManager::completeRedraw(rRegion, pPreRenderDevice);
448 : 15563 : }
449 : :
450 : 0 : void OverlayManagerBuffered::flush()
451 : : {
452 : : // call timer handler direct
453 : 0 : ImpBufferTimerHandler(0);
454 : 0 : }
455 : :
456 : : // #i68597# part of content gets copied, react on it
457 : 0 : void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize)
458 : : {
459 : : // scroll local buffered area
460 : 0 : maBufferDevice.CopyArea(rDestPt, rSrcPt, rSrcSize);
461 : 0 : }
462 : :
463 : 0 : void OverlayManagerBuffered::restoreBackground(const Region& rRegion) const
464 : : {
465 : : // restore
466 [ # # ]: 0 : const Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion));
467 [ # # ]: 0 : ImpRestoreBackground(aRegionPixel);
468 : :
469 : : // call parent
470 [ # # ][ # # ]: 0 : OverlayManager::restoreBackground(rRegion);
471 : 0 : }
472 : :
473 : 17652 : void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange)
474 : : {
475 [ + - ]: 17652 : if(!rRange.isEmpty())
476 : : {
477 : : // buffered output, do not invalidate but use the timer
478 : : // to trigger a timer event for refresh
479 [ + - ]: 17652 : maBufferTimer.Start();
480 : :
481 : : // add the discrete range to the remembered region
482 : : // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even
483 : : // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel
484 : : // since it just transforms the top left and bottom right points equally without taking
485 : : // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated
486 : : // to an also empty discrete pixel rectangle - what is wrong.
487 : 17652 : basegfx::B2DRange aDiscreteRange(rRange);
488 [ + - ][ + - ]: 17652 : aDiscreteRange.transform(getOutputDevice().GetViewTransformation());
[ + - ]
489 : :
490 [ + - ][ - + ]: 17652 : if(maDrawinglayerOpt.IsAntiAliasing())
491 : : {
492 : : // assume AA needs one pixel more and invalidate one pixel more
493 [ # # ]: 0 : const double fDiscreteOne(getDiscreteOne());
494 : : const basegfx::B2IPoint aTopLeft(
495 [ # # ]: 0 : (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne),
496 [ # # ]: 0 : (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne));
497 : : const basegfx::B2IPoint aBottomRight(
498 [ # # ]: 0 : (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne),
499 [ # # ]: 0 : (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne));
500 : :
501 [ # # ]: 0 : maBufferRememberedRangePixel.expand(aTopLeft);
502 [ # # ]: 0 : maBufferRememberedRangePixel.expand(aBottomRight);
503 : : }
504 : : else
505 : : {
506 [ + - ][ + - ]: 17652 : const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()));
507 [ + - ][ + - ]: 17652 : const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
508 : :
509 [ + - ]: 17652 : maBufferRememberedRangePixel.expand(aTopLeft);
510 [ + - ]: 17652 : maBufferRememberedRangePixel.expand(aBottomRight);
511 : : }
512 : : }
513 : 17652 : }
514 : : } // end of namespace overlay
515 : : } // end of namespace sdr
516 : :
517 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|