1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svx/sdr/overlay/overlaymanagerbuffered.hxx>
27 #include <vcl/outdev.hxx>
28 #include <basegfx/point/b2dpoint.hxx>
29 #include <basegfx/range/b2drange.hxx>
30 #include <vcl/salbtype.hxx>
31 #include <vcl/window.hxx>
32 #include <vcl/bitmap.hxx>
33 #include <tools/stream.hxx>
34 #include <basegfx/matrix/b2dhommatrix.hxx>
35 #include <vcl/cursor.hxx>
36 
37 //////////////////////////////////////////////////////////////////////////////
38 
39 namespace sdr
40 {
41 	namespace overlay
42 	{
43 		void OverlayManagerBuffered::ImpPrepareBufferDevice()
44 		{
45 			// compare size of maBufferDevice with size of visible area
46 			if(maBufferDevice.GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel())
47 			{
48 				// set new buffer size, copy as much content as possible (use bool parameter for vcl).
49 				// Newly uncovered regions will be repainted.
50 				maBufferDevice.SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false);
51 			}
52 
53 			// compare the MapModes for zoom/scroll changes
54 			if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode())
55 			{
56 				const bool bZoomed(
57 					maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX()
58 					|| maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY());
59 
60 				if(!bZoomed)
61 				{
62 					const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin();
63 					const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin();
64 					const bool bScrolled(rOriginOld != rOriginNew);
65 
66 					if(bScrolled)
67 					{
68 						// get pixel bounds
69 						const Point aOriginOldPixel(maBufferDevice.LogicToPixel(rOriginOld));
70 						const Point aOriginNewPixel(maBufferDevice.LogicToPixel(rOriginNew));
71 						const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel());
72 
73 						// remember and switch off MapMode
74 						const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled());
75 						maBufferDevice.EnableMapMode(false);
76 
77 						// scroll internally buffered stuff
78 						const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel);
79 						maBufferDevice.DrawOutDev(
80 							aDestinationOffsetPixel, aOutputSizePixel, // destination
81 							Point(), aOutputSizePixel); // source
82 
83 						// restore MapMode
84 						maBufferDevice.EnableMapMode(bMapModeWasEnabled);
85 
86 						// scroll remembered region, too.
87 						if(!maBufferRememberedRangePixel.isEmpty())
88 						{
89 							const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y());
90 							const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel);
91 							const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel);
92 							maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum);
93 						}
94 					}
95 				}
96 
97 				// copy new MapMode
98 				maBufferDevice.SetMapMode(getOutputDevice().GetMapMode());
99 			}
100 
101 			// #i29186#
102 			maBufferDevice.SetDrawMode(getOutputDevice().GetDrawMode());
103 			maBufferDevice.SetSettings(getOutputDevice().GetSettings());
104 			maBufferDevice.SetAntialiasing(getOutputDevice().GetAntialiasing());
105 		}
106 
107 		void OverlayManagerBuffered::ImpRestoreBackground() const
108 		{
109 			const Rectangle aRegionRectanglePixel(
110 				maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
111 				maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
112 			const Region aRegionPixel(aRegionRectanglePixel);
113 
114 			ImpRestoreBackground(aRegionPixel);
115 		}
116 
117 		void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const
118 		{
119 			// MapModes off
120 			const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
121 			const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
122 			getOutputDevice().EnableMapMode(false);
123 			((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false);
124 
125 			// local region
126             RectangleVector aRectangles;
127             rRegionPixel.GetRegionRectangles(aRectangles);
128 
129             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
130             {
131 #ifdef DBG_UTIL
132                 // #i72754# possible graphical region test only with non-pro
133                 static bool bDoPaintForVisualControl(false);
134 
135                 if(bDoPaintForVisualControl)
136                 {
137                     getOutputDevice().SetLineColor(COL_LIGHTGREEN);
138                     getOutputDevice().SetFillColor();
139                     getOutputDevice().DrawRect(*aRectIter);
140                 }
141 #endif
142 
143                 // restore the area
144                 const Point aTopLeft(aRectIter->TopLeft());
145                 const Size aSize(aRectIter->GetSize());
146 
147                 getOutputDevice().DrawOutDev(
148                     aTopLeft, aSize, // destination
149                     aTopLeft, aSize, // source
150                     maBufferDevice);
151             }
152 
153 			//Region aRegionPixel(rRegionPixel);
154 			//RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
155 			//Rectangle aRegionRectanglePixel;
156 			//
157 			//while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
158 			//{
159 #ifdef DBG_U//TIL
160 			//	// #i72754# possible graphical region test only with non-pro
161 			//	static bool bDoPaintForVisualControl(false);
162 			//	if(bDoPaintForVisualControl)
163 			//	{
164 			//		getOutputDevice().SetLineColor(COL_LIGHTGREEN);
165 			//		getOutputDevice().SetFillColor();
166 			//		getOutputDevice().DrawRect(aRegionRectanglePixel);
167 			//	}
168 #endif      //
169 			//	// restore the area
170 			//	const Point aTopLeft(aRegionRectanglePixel.TopLeft());
171 			//	const Size aSize(aRegionRectanglePixel.GetSize());
172             //
173 			//	getOutputDevice().DrawOutDev(
174 			//		aTopLeft, aSize, // destination
175 			//		aTopLeft, aSize, // source
176 			//		maBufferDevice);
177 			//}
178             //
179 			//aRegionPixel.EndEnumRects(aRegionHandle);
180 
181 			// restore MapModes
182 			getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
183 			((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(bMapModeWasEnabledSource);
184 		}
185 
186 		void OverlayManagerBuffered::ImpSaveBackground(const Region& rRegion, OutputDevice* pPreRenderDevice)
187 		{
188 			// prepare source
189 			OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
190 
191 			// Ensure buffer is valid
192 			ImpPrepareBufferDevice();
193 
194 			// build region which needs to be copied
195 			Region aRegion(rSource.LogicToPixel(rRegion));
196 
197 			// limit to PaintRegion if it's a window. This will be evtl. the expanded one,
198 			// but always the exact redraw area
199 			if(OUTDEV_WINDOW == rSource.GetOutDevType())
200 			{
201 				Window& rWindow = (Window&)rSource;
202 				Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion());
203 				aRegion.Intersect(aPaintRegionPixel);
204 
205 				// #i72754# Make sure content is completetly rendered, the window
206 				// will be used as source of a DrawOutDev soon
207 				rWindow.Flush();
208 			}
209 
210 			// also limit to buffer size
211 			const Rectangle aBufferDeviceRectanglePixel(Point(), maBufferDevice.GetOutputSizePixel());
212 			aRegion.Intersect(aBufferDeviceRectanglePixel);
213 
214 			// MapModes off
215 			const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled());
216 			const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled());
217 			rSource.EnableMapMode(false);
218 			maBufferDevice.EnableMapMode(false);
219 
220 			// prepare to iterate over the rectangles from the region in pixels
221             RectangleVector aRectangles;
222             aRegion.GetRegionRectangles(aRectangles);
223 
224             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
225             {
226                 // for each rectangle, save the area
227                 const Point aTopLeft(aRectIter->TopLeft());
228                 const Size aSize(aRectIter->GetSize());
229 
230                 maBufferDevice.DrawOutDev(
231                     aTopLeft, aSize, // destination
232                     aTopLeft, aSize, // source
233                     rSource);
234 
235 #ifdef DBG_UTIL
236                 // #i72754# possible graphical region test only with non-pro
237                 static bool bDoPaintForVisualControl(false);
238 
239                 if(bDoPaintForVisualControl)
240                 {
241                     const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled());
242 
243                     getOutputDevice().EnableMapMode(false);
244                     getOutputDevice().SetLineColor(COL_LIGHTRED);
245                     getOutputDevice().SetFillColor();
246                     getOutputDevice().DrawRect(*aRectIter);
247                     getOutputDevice().EnableMapMode(bMapModeWasEnabledTest);
248                 }
249 
250                 static bool bDoSaveForVisualControl(false);
251 
252                 if(bDoSaveForVisualControl)
253                 {
254                     const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize));
255                     SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
256                     aNew << aBitmap;
257                 }
258 #endif
259             }
260 
261 			//RegionHandle aRegionHandle(aRegion.BeginEnumRects());
262 			//Rectangle aRegionRectanglePixel;
263             //
264 			//while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
265 			//{
266 			//	// for each rectangle, save the area
267 			//	Point aTopLeft(aRegionRectanglePixel.TopLeft());
268 			//	Size aSize(aRegionRectanglePixel.GetSize());
269             //
270 			//	maBufferDevice.DrawOutDev(
271 			//		aTopLeft, aSize, // destination
272 			//		aTopLeft, aSize, // source
273 			//		rSource);
274             //
275 #ifdef DBG_U//TIL
276 			//	// #i72754# possible graphical region test only with non-pro
277 			//	static bool bDoPaintForVisualControl(false);
278 			//	if(bDoPaintForVisualControl)
279 			//	{
280 			//		const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled());
281 			//		getOutputDevice().EnableMapMode(false);
282 			//		getOutputDevice().SetLineColor(COL_LIGHTRED);
283 			//		getOutputDevice().SetFillColor();
284 			//		getOutputDevice().DrawRect(aRegionRectanglePixel);
285 			//		getOutputDevice().EnableMapMode(bMapModeWasEnabledTest);
286 			//	}
287             //
288 			//	static bool bDoSaveForVisualControl(false);
289 			//	if(bDoSaveForVisualControl)
290 			//	{
291 			//		const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize));
292 			//		SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
293 			//		aNew << aBitmap;
294 			//	}
295 #endif      //
296 			//}
297             //
298 			//aRegion.EndEnumRects(aRegionHandle);
299 
300 			// restore MapModes
301 			rSource.EnableMapMode(bMapModeWasEnabledDest);
302 			maBufferDevice.EnableMapMode(bMapModeWasEnabledSource);
303 		}
304 
305 		IMPL_LINK(OverlayManagerBuffered, ImpBufferTimerHandler, AutoTimer*, /*pTimer*/)
306 		{
307 			// stop timer
308 			maBufferTimer.Stop();
309 
310 			if(!maBufferRememberedRangePixel.isEmpty())
311 			{
312 				// logic size for impDrawMember call
313                 basegfx::B2DRange aBufferRememberedRangeLogic(
314                     maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
315 					maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
316                 aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation());
317 
318                 // prepare cursor handling
319                 const bool bTargetIsWindow(OUTDEV_WINDOW == rmOutputDevice.GetOutDevType());
320                 bool bCursorWasEnabled(false);
321 
322                 // #i80730# switch off VCL cursor during overlay refresh
323 				if(bTargetIsWindow)
324 				{
325 					Window& rWindow = static_cast< Window& >(rmOutputDevice);
326 					Cursor* pCursor = rWindow.GetCursor();
327 
328                     if(pCursor && pCursor->IsVisible())
329                     {
330                         pCursor->Hide();
331                         bCursorWasEnabled = true;
332                     }
333 				}
334 
335 				if(DoRefreshWithPreRendering())
336 				{
337 					// #i73602# ensure valid and sized maOutputBufferDevice
338 					const Size aDestinationSizePixel(maBufferDevice.GetOutputSizePixel());
339 					const Size aOutputBufferSizePixel(maOutputBufferDevice.GetOutputSizePixel());
340 
341 					if(aDestinationSizePixel != aOutputBufferSizePixel)
342 					{
343 						maOutputBufferDevice.SetOutputSizePixel(aDestinationSizePixel);
344 					}
345 
346 					maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode());
347 					maOutputBufferDevice.EnableMapMode(false);
348 					maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode());
349 					maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings());
350 					maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing());
351 
352 					// calculate sizes
353 					Rectangle aRegionRectanglePixel(
354 						maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
355 						maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
356 
357 					// truncate aRegionRectanglePixel to destination pixel size, more does
358 					// not need to be prepared since destination is a buffer for a window. So,
359 					// maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel()
360 					if(aRegionRectanglePixel.Left() < 0L)
361 					{
362 						aRegionRectanglePixel.Left() = 0L;
363 					}
364 
365 					if(aRegionRectanglePixel.Top() < 0L)
366 					{
367 						aRegionRectanglePixel.Top() = 0L;
368 					}
369 
370 					if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth())
371 					{
372 						aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth();
373 					}
374 
375 					if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight())
376 					{
377 						aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight();
378 					}
379 
380 					// get sizes
381 					const Point aTopLeft(aRegionRectanglePixel.TopLeft());
382 					const Size aSize(aRegionRectanglePixel.GetSize());
383 
384 					{
385 						const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled());
386 						maBufferDevice.EnableMapMode(false);
387 
388 						maOutputBufferDevice.DrawOutDev(
389 							aTopLeft, aSize, // destination
390 							aTopLeft, aSize, // source
391 							maBufferDevice);
392 
393 						// restore MapModes
394 						maBufferDevice.EnableMapMode(bMapModeWasEnabledDest);
395 					}
396 
397 					// paint overlay content for remembered region, use
398 					// method from base class directly
399 					maOutputBufferDevice.EnableMapMode(true);
400 					OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice);
401 					maOutputBufferDevice.EnableMapMode(false);
402 
403 					// copy to output
404 					{
405 						const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
406 						getOutputDevice().EnableMapMode(false);
407 
408 						getOutputDevice().DrawOutDev(
409 							aTopLeft, aSize, // destination
410 							aTopLeft, aSize, // source
411 							maOutputBufferDevice);
412 
413 						// debug
414 						/*getOutputDevice().SetLineColor(COL_RED);
415 						getOutputDevice().SetFillColor();
416 						getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/
417 
418 						// restore MapModes
419 						getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
420 					}
421 				}
422 				else
423 				{
424 					// Restore all rectangles for remembered region from buffer
425 					ImpRestoreBackground();
426 
427 					// paint overlay content for remembered region, use
428 					// method from base class directly
429 					OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice());
430 				}
431 
432 				// VCL hack for transparent child windows
433 				// Problem is e.g. a radiobuttion form control in life mode. The used window
434 				// is a transparence vcl childwindow. This flag only allows the parent window to
435 				// paint into the child windows area, but there is no mechanism which takes
436 				// care for a repaint of the child window. A transparent child window is NOT
437 				// a window which always keeps it's content consistent over the parent, but it's
438 				// more like just a paint flag for the parent.
439 				// To get the update, the windows in question are updated manulally here.
440 				if(bTargetIsWindow)
441 				{
442 					Window& rWindow = static_cast< Window& >(rmOutputDevice);
443 
444 					if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount())
445 					{
446 						const Rectangle aRegionRectanglePixel(
447 							maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
448 							maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
449 
450 						for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++)
451 						{
452 							Window* pCandidate = rWindow.GetChild(a);
453 
454 							if(pCandidate && pCandidate->IsPaintTransparent())
455 							{
456 								const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel());
457 
458 								if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel))
459 								{
460 									pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN);
461 									pCandidate->Update();
462 								}
463 							}
464 						}
465 					}
466 				}
467 
468                 // #i80730# restore visibility of VCL cursor
469 				if(bCursorWasEnabled)
470                 {
471 					Window& rWindow = static_cast< Window& >(rmOutputDevice);
472 					Cursor* pCursor = rWindow.GetCursor();
473 
474                     if(pCursor)
475                     {
476                         // check if cursor still exists. It may have been deleted from someone
477                         pCursor->Show();
478                     }
479 				}
480 
481 				// forget remembered Region
482 				maBufferRememberedRangePixel.reset();
483 			}
484 
485 			return 0;
486 		}
487 
488 		OverlayManagerBuffered::OverlayManagerBuffered(
489 			OutputDevice& rOutputDevice,
490 			bool bRefreshWithPreRendering)
491 		:	OverlayManager(rOutputDevice),
492 			mbRefreshWithPreRendering(bRefreshWithPreRendering)
493 		{
494 			// Init timer
495 			maBufferTimer.SetTimeout(1);
496 			maBufferTimer.SetTimeoutHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler));
497 		}
498 
499 		OverlayManagerBuffered::~OverlayManagerBuffered()
500 		{
501 			// Clear timer
502 			maBufferTimer.Stop();
503 
504 			if(!maBufferRememberedRangePixel.isEmpty())
505 			{
506 				// Restore all rectangles for remembered region from buffer
507 				ImpRestoreBackground();
508 			}
509 		}
510 
511 		void OverlayManagerBuffered::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const
512 		{
513 			if(!rRegion.IsEmpty())
514 			{
515 				// save new background
516 				((OverlayManagerBuffered*)this)->ImpSaveBackground(rRegion, pPreRenderDevice);
517 			}
518 
519 			// call parent
520 			OverlayManager::completeRedraw(rRegion, pPreRenderDevice);
521 		}
522 
523 		void OverlayManagerBuffered::flush()
524 		{
525 			// call timer handler direct
526 			ImpBufferTimerHandler(0);
527 		}
528 
529 		// #i68597# part of content gets copied, react on it
530 		void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize)
531 		{
532 			// scroll local buffered area
533 			maBufferDevice.CopyArea(rDestPt, rSrcPt, rSrcSize);
534 		}
535 
536 		void OverlayManagerBuffered::restoreBackground(const Region& rRegion) const
537 		{
538 			// restore
539 			const Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion));
540 			ImpRestoreBackground(aRegionPixel);
541 
542 			// call parent
543 			OverlayManager::restoreBackground(rRegion);
544 		}
545 
546 		void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange)
547 		{
548             if(!rRange.isEmpty())
549             {
550 			    // buffered output, do not invalidate but use the timer
551 			    // to trigger a timer event for refresh
552 			    maBufferTimer.Start();
553 
554 			    // add the discrete range to the remembered region
555 			    // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even
556 			    // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel
557 			    // since it just transforms the top left and bottom right points equally without taking
558 			    // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated
559 			    // to an also empty discrete pixel rectangle - what is wrong.
560 			    basegfx::B2DRange aDiscreteRange(rRange);
561 			    aDiscreteRange.transform(getOutputDevice().GetViewTransformation());
562 
563 			    if(maDrawinglayerOpt.IsAntiAliasing())
564 			    {
565 				    // assume AA needs one pixel more and invalidate one pixel more
566                     const double fDiscreteOne(getDiscreteOne());
567 				    const basegfx::B2IPoint aTopLeft(
568 					    (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne),
569 					    (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne));
570 				    const basegfx::B2IPoint aBottomRight(
571 					    (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne),
572 					    (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne));
573 
574 				    maBufferRememberedRangePixel.expand(aTopLeft);
575 				    maBufferRememberedRangePixel.expand(aBottomRight);
576 			    }
577 			    else
578 			    {
579 				    const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()));
580 				    const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
581 
582 				    maBufferRememberedRangePixel.expand(aTopLeft);
583 				    maBufferRememberedRangePixel.expand(aBottomRight);
584 			    }
585             }
586 		}
587 
588 		void OverlayManagerBuffered::SetRefreshWithPreRendering(bool bNew)
589 		{
590 			if((bool)mbRefreshWithPreRendering != bNew)
591 			{
592 				mbRefreshWithPreRendering = bNew;
593 			}
594 		}
595 	} // end of namespace overlay
596 } // end of namespace sdr
597 
598 //////////////////////////////////////////////////////////////////////////////
599 // eof
600