nss: upgrade to release 3.73
[LibreOffice.git] / vcl / source / window / clipping.cxx
blob1fb8e0d77e784e7784cb6341d142859582204de0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/window.hxx>
21 #include <vcl/virdev.hxx>
23 #include <tools/debug.hxx>
25 #include <salobj.hxx>
26 #include <window.h>
28 namespace vcl {
30 vcl::Region Window::GetOutputBoundsClipRegion() const
32 vcl::Region aClip(GetClipRegion());
33 aClip.Intersect(tools::Rectangle(Point(), GetOutputSize()));
35 return aClip;
38 void Window::InitClipRegion()
40 DBG_TESTSOLARMUTEX();
42 vcl::Region aRegion;
44 if ( mpWindowImpl->mbInPaint )
45 aRegion = *(mpWindowImpl->mpPaintRegion);
46 else
48 aRegion = *(ImplGetWinChildClipRegion());
49 // only this region is in frame coordinates, so re-mirror it
50 // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
51 if( ImplIsAntiparallel() )
52 ReMirror ( aRegion );
54 if ( mbClipRegion )
55 aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
56 if ( aRegion.IsEmpty() )
57 mbOutputClipped = true;
58 else
60 mbOutputClipped = false;
61 SelectClipRegion( aRegion );
63 mbClipRegionSet = true;
65 mbInitClipRegion = false;
68 void Window::SetParentClipMode( ParentClipMode nMode )
70 if ( mpWindowImpl->mpBorderWindow )
71 mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode );
72 else
74 if ( !ImplIsOverlapWindow() )
76 mpWindowImpl->mnParentClipMode = nMode;
77 if ( nMode & ParentClipMode::Clip )
78 mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = true;
83 ParentClipMode Window::GetParentClipMode() const
85 if ( mpWindowImpl->mpBorderWindow )
86 return mpWindowImpl->mpBorderWindow->GetParentClipMode();
87 else
88 return mpWindowImpl->mnParentClipMode;
91 void Window::ExpandPaintClipRegion( const vcl::Region& rRegion )
93 if( !mpWindowImpl->mpPaintRegion )
94 return;
96 vcl::Region aPixRegion = LogicToPixel( rRegion );
97 vcl::Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion );
99 vcl::Region aWinChildRegion = *ImplGetWinChildClipRegion();
100 // only this region is in frame coordinates, so re-mirror it
101 if( ImplIsAntiparallel() )
103 const OutputDevice *pOutDev = GetOutDev();
104 pOutDev->ReMirror( aWinChildRegion );
107 aDevPixRegion.Intersect( aWinChildRegion );
108 if( ! aDevPixRegion.IsEmpty() )
110 mpWindowImpl->mpPaintRegion->Union( aDevPixRegion );
111 mbInitClipRegion = true;
115 vcl::Region Window::GetWindowClipRegionPixel() const
117 vcl::Region aWinClipRegion;
119 if ( mpWindowImpl->mbInitWinClipRegion )
120 const_cast<vcl::Window*>(this)->ImplInitWinClipRegion();
121 aWinClipRegion = mpWindowImpl->maWinClipRegion;
123 tools::Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
124 vcl::Region aWinRegion( aWinRect );
126 if ( aWinRegion == aWinClipRegion )
127 aWinClipRegion.SetNull();
129 aWinClipRegion.Move( -mnOutOffX, -mnOutOffY );
131 return aWinClipRegion;
135 vcl::Region Window::GetActiveClipRegion() const
137 vcl::Region aRegion(true);
139 if ( mpWindowImpl->mbInPaint )
141 aRegion = *(mpWindowImpl->mpPaintRegion);
142 aRegion.Move( -mnOutOffX, -mnOutOffY );
145 if ( mbClipRegion )
146 aRegion.Intersect( maRegion );
148 return PixelToLogic( aRegion );
151 void Window::ClipToPaintRegion(tools::Rectangle& rDstRect)
153 const vcl::Region aPaintRgn(GetPaintRegion());
155 if (!aPaintRgn.IsNull())
156 rDstRect.Intersection(LogicToPixel(aPaintRgn.GetBoundRect()));
159 void Window::EnableClipSiblings( bool bClipSiblings )
162 if ( mpWindowImpl->mpBorderWindow )
163 mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings );
165 mpWindowImpl->mbClipSiblings = bClipSiblings;
168 void Window::ImplClipBoundaries( vcl::Region& rRegion, bool bThis, bool bOverlaps )
170 if ( bThis )
171 ImplIntersectWindowClipRegion( rRegion );
172 else if ( ImplIsOverlapWindow() )
174 // clip to frame if required
175 if ( !mpWindowImpl->mbFrame )
176 rRegion.Intersect( tools::Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
178 if ( bOverlaps && !rRegion.IsEmpty() )
180 // Clip Overlap Siblings
181 vcl::Window* pStartOverlapWindow = this;
182 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
184 vcl::Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
185 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
187 pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
188 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
190 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
193 // Clip Child Overlap Windows
194 ImplExcludeOverlapWindows( rRegion );
197 else
198 ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
201 bool Window::ImplClipChildren( vcl::Region& rRegion ) const
203 bool bOtherClip = false;
204 vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
205 while ( pWindow )
207 if ( pWindow->mpWindowImpl->mbReallyVisible )
209 // read-out ParentClipMode-Flags
210 ParentClipMode nClipMode = pWindow->GetParentClipMode();
211 if ( !(nClipMode & ParentClipMode::NoClip) &&
212 ((nClipMode & ParentClipMode::Clip) || (GetStyle() & WB_CLIPCHILDREN)) )
213 pWindow->ImplExcludeWindowRegion( rRegion );
214 else
215 bOtherClip = true;
218 pWindow = pWindow->mpWindowImpl->mpNext;
221 return bOtherClip;
224 void Window::ImplClipAllChildren( vcl::Region& rRegion ) const
226 vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
227 while ( pWindow )
229 if ( pWindow->mpWindowImpl->mbReallyVisible )
230 pWindow->ImplExcludeWindowRegion( rRegion );
231 pWindow = pWindow->mpWindowImpl->mpNext;
235 void Window::ImplClipSiblings( vcl::Region& rRegion ) const
237 vcl::Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
238 while ( pWindow )
240 if ( pWindow == this )
241 break;
243 if ( pWindow->mpWindowImpl->mbReallyVisible )
244 pWindow->ImplExcludeWindowRegion( rRegion );
246 pWindow = pWindow->mpWindowImpl->mpNext;
250 void Window::ImplInitWinClipRegion()
252 // Build Window Region
253 mpWindowImpl->maWinClipRegion = tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
254 Size( mnOutWidth, mnOutHeight ) );
255 if ( mpWindowImpl->mbWinRegion )
256 mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
258 // ClipSiblings
259 if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() )
260 ImplClipSiblings( mpWindowImpl->maWinClipRegion );
262 // Clip Parent Boundaries
263 ImplClipBoundaries( mpWindowImpl->maWinClipRegion, false, true );
265 // Clip Children
266 if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren )
267 mpWindowImpl->mbInitChildRegion = true;
269 mpWindowImpl->mbInitWinClipRegion = false;
272 void Window::ImplInitWinChildClipRegion()
274 if ( !mpWindowImpl->mpFirstChild )
276 mpWindowImpl->mpChildClipRegion.reset();
278 else
280 if ( !mpWindowImpl->mpChildClipRegion )
281 mpWindowImpl->mpChildClipRegion.reset( new vcl::Region( mpWindowImpl->maWinClipRegion ) );
282 else
283 *mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion;
285 ImplClipChildren( *mpWindowImpl->mpChildClipRegion );
288 mpWindowImpl->mbInitChildRegion = false;
291 Region* Window::ImplGetWinChildClipRegion()
293 if ( mpWindowImpl->mbInitWinClipRegion )
294 ImplInitWinClipRegion();
295 if ( mpWindowImpl->mbInitChildRegion )
296 ImplInitWinChildClipRegion();
297 if ( mpWindowImpl->mpChildClipRegion )
298 return mpWindowImpl->mpChildClipRegion.get();
299 else
300 return &mpWindowImpl->maWinClipRegion;
304 bool Window::ImplSysObjClip( const vcl::Region* pOldRegion )
306 bool bUpdate = true;
308 if ( mpWindowImpl->mpSysObj )
310 bool bVisibleState = mpWindowImpl->mbReallyVisible;
312 if ( bVisibleState )
314 vcl::Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
316 if ( !pWinChildClipRegion->IsEmpty() )
318 if ( pOldRegion )
320 vcl::Region aNewRegion = *pWinChildClipRegion;
321 pWinChildClipRegion->Intersect( *pOldRegion );
322 bUpdate = aNewRegion == *pWinChildClipRegion;
325 vcl::Region aRegion = *pWinChildClipRegion;
326 tools::Rectangle aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
327 vcl::Region aWinRectRegion( aWinRect );
329 if ( aRegion == aWinRectRegion )
330 mpWindowImpl->mpSysObj->ResetClipRegion();
331 else
333 aRegion.Move( -mnOutOffX, -mnOutOffY );
335 // set/update clip region
336 RectangleVector aRectangles;
337 aRegion.GetRegionRectangles(aRectangles);
338 mpWindowImpl->mpSysObj->BeginSetClipRegion(aRectangles.size());
340 for (auto const& rectangle : aRectangles)
342 mpWindowImpl->mpSysObj->UnionClipRegion(
343 rectangle.Left(),
344 rectangle.Top(),
345 rectangle.GetWidth(), // orig nWidth was ((R - L) + 1), same as GetWidth does
346 rectangle.GetHeight()); // same for height
349 mpWindowImpl->mpSysObj->EndSetClipRegion();
352 else
353 bVisibleState = false;
356 // update visible status
357 mpWindowImpl->mpSysObj->Show( bVisibleState );
360 return bUpdate;
363 void Window::ImplUpdateSysObjChildrenClip()
365 if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion )
366 ImplSysObjClip( nullptr );
368 vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
369 while ( pWindow )
371 pWindow->ImplUpdateSysObjChildrenClip();
372 pWindow = pWindow->mpWindowImpl->mpNext;
376 void Window::ImplUpdateSysObjOverlapsClip()
378 ImplUpdateSysObjChildrenClip();
380 vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
381 while ( pWindow )
383 pWindow->ImplUpdateSysObjOverlapsClip();
384 pWindow = pWindow->mpWindowImpl->mpNext;
388 void Window::ImplUpdateSysObjClip()
390 if ( !ImplIsOverlapWindow() )
392 ImplUpdateSysObjChildrenClip();
394 // siblings should recalculate their clip region
395 if ( mpWindowImpl->mbClipSiblings )
397 vcl::Window* pWindow = mpWindowImpl->mpNext;
398 while ( pWindow )
400 pWindow->ImplUpdateSysObjChildrenClip();
401 pWindow = pWindow->mpWindowImpl->mpNext;
405 else
406 mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip();
409 bool Window::ImplSetClipFlagChildren( bool bSysObjOnlySmaller )
411 bool bUpdate = true;
412 if ( mpWindowImpl->mpSysObj )
414 std::unique_ptr<vcl::Region> pOldRegion;
415 if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion )
416 pOldRegion.reset(new vcl::Region( mpWindowImpl->maWinClipRegion ));
418 mbInitClipRegion = true;
419 mpWindowImpl->mbInitWinClipRegion = true;
421 vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
422 while ( pWindow )
424 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
425 bUpdate = false;
426 pWindow = pWindow->mpWindowImpl->mpNext;
429 if ( !ImplSysObjClip( pOldRegion.get() ) )
431 mbInitClipRegion = true;
432 mpWindowImpl->mbInitWinClipRegion = true;
433 bUpdate = false;
436 else
438 mbInitClipRegion = true;
439 mpWindowImpl->mbInitWinClipRegion = true;
441 vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
442 while ( pWindow )
444 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
445 bUpdate = false;
446 pWindow = pWindow->mpWindowImpl->mpNext;
449 return bUpdate;
452 bool Window::ImplSetClipFlagOverlapWindows( bool bSysObjOnlySmaller )
454 bool bUpdate = ImplSetClipFlagChildren( bSysObjOnlySmaller );
456 vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
457 while ( pWindow )
459 if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
460 bUpdate = false;
461 pWindow = pWindow->mpWindowImpl->mpNext;
464 return bUpdate;
467 bool Window::ImplSetClipFlag( bool bSysObjOnlySmaller )
469 if ( !ImplIsOverlapWindow() )
471 bool bUpdate = ImplSetClipFlagChildren( bSysObjOnlySmaller );
473 vcl::Window* pParent = ImplGetParent();
474 if ( pParent &&
475 ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & ParentClipMode::Clip)) )
477 pParent->mbInitClipRegion = true;
478 pParent->mpWindowImpl->mbInitChildRegion = true;
481 // siblings should recalculate their clip region
482 if ( mpWindowImpl->mbClipSiblings )
484 vcl::Window* pWindow = mpWindowImpl->mpNext;
485 while ( pWindow )
487 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
488 bUpdate = false;
489 pWindow = pWindow->mpWindowImpl->mpNext;
493 return bUpdate;
495 else
496 return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
499 void Window::ImplIntersectWindowClipRegion( vcl::Region& rRegion )
501 if ( mpWindowImpl->mbInitWinClipRegion )
502 ImplInitWinClipRegion();
504 rRegion.Intersect( mpWindowImpl->maWinClipRegion );
507 void Window::ImplIntersectWindowRegion( vcl::Region& rRegion )
509 rRegion.Intersect( tools::Rectangle( Point( mnOutOffX, mnOutOffY ),
510 Size( mnOutWidth, mnOutHeight ) ) );
511 if ( mpWindowImpl->mbWinRegion )
512 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
515 void Window::ImplExcludeWindowRegion( vcl::Region& rRegion )
517 if ( mpWindowImpl->mbWinRegion )
519 Point aPoint( mnOutOffX, mnOutOffY );
520 vcl::Region aRegion( tools::Rectangle( aPoint,
521 Size( mnOutWidth, mnOutHeight ) ) );
522 aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
523 rRegion.Exclude( aRegion );
525 else
527 Point aPoint( mnOutOffX, mnOutOffY );
528 rRegion.Exclude( tools::Rectangle( aPoint,
529 Size( mnOutWidth, mnOutHeight ) ) );
533 void Window::ImplExcludeOverlapWindows( vcl::Region& rRegion ) const
535 vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
536 while ( pWindow )
538 if ( pWindow->mpWindowImpl->mbReallyVisible )
540 pWindow->ImplExcludeWindowRegion( rRegion );
541 pWindow->ImplExcludeOverlapWindows( rRegion );
544 pWindow = pWindow->mpWindowImpl->mpNext;
548 void Window::ImplExcludeOverlapWindows2( vcl::Region& rRegion )
550 if ( mpWindowImpl->mbReallyVisible )
551 ImplExcludeWindowRegion( rRegion );
553 ImplExcludeOverlapWindows( rRegion );
556 void Window::ImplIntersectAndUnionOverlapWindows( const vcl::Region& rInterRegion, vcl::Region& rRegion ) const
558 vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
559 while ( pWindow )
561 if ( pWindow->mpWindowImpl->mbReallyVisible )
563 vcl::Region aTempRegion( rInterRegion );
564 pWindow->ImplIntersectWindowRegion( aTempRegion );
565 rRegion.Union( aTempRegion );
566 pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
569 pWindow = pWindow->mpWindowImpl->mpNext;
573 void Window::ImplIntersectAndUnionOverlapWindows2( const vcl::Region& rInterRegion, vcl::Region& rRegion )
575 if ( mpWindowImpl->mbReallyVisible )
577 vcl::Region aTempRegion( rInterRegion );
578 ImplIntersectWindowRegion( aTempRegion );
579 rRegion.Union( aTempRegion );
582 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
585 void Window::ImplCalcOverlapRegionOverlaps( const vcl::Region& rInterRegion, vcl::Region& rRegion ) const
587 // Clip Overlap Siblings
588 vcl::Window const * pStartOverlapWindow;
589 if ( !ImplIsOverlapWindow() )
590 pStartOverlapWindow = mpWindowImpl->mpOverlapWindow;
591 else
592 pStartOverlapWindow = this;
593 while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
595 vcl::Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
596 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
598 pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
599 pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
601 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
604 // Clip Child Overlap Windows
605 if ( !ImplIsOverlapWindow() )
606 mpWindowImpl->mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
607 else
608 ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
611 void Window::ImplCalcOverlapRegion( const tools::Rectangle& rSourceRect, vcl::Region& rRegion,
612 bool bChildren, bool bSiblings )
614 vcl::Region aRegion( rSourceRect );
615 if ( mpWindowImpl->mbWinRegion )
616 rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
617 vcl::Region aTempRegion;
618 vcl::Window* pWindow;
620 ImplCalcOverlapRegionOverlaps( aRegion, rRegion );
622 // Parent-Boundaries
623 pWindow = this;
624 if ( !ImplIsOverlapWindow() )
626 pWindow = ImplGetParent();
629 aTempRegion = aRegion;
630 pWindow->ImplExcludeWindowRegion( aTempRegion );
631 rRegion.Union( aTempRegion );
632 if ( pWindow->ImplIsOverlapWindow() )
633 break;
634 pWindow = pWindow->ImplGetParent();
636 while ( pWindow );
638 if ( pWindow && !pWindow->mpWindowImpl->mbFrame )
640 aTempRegion = aRegion;
641 aTempRegion.Exclude( tools::Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
642 rRegion.Union( aTempRegion );
645 // Siblings
646 if ( bSiblings && !ImplIsOverlapWindow() )
648 pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
651 if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) )
653 aTempRegion = aRegion;
654 pWindow->ImplIntersectWindowRegion( aTempRegion );
655 rRegion.Union( aTempRegion );
657 pWindow = pWindow->mpWindowImpl->mpNext;
659 while ( pWindow );
662 if ( !bChildren )
663 return;
665 pWindow = mpWindowImpl->mpFirstChild;
666 while ( pWindow )
668 if ( pWindow->mpWindowImpl->mbReallyVisible )
670 aTempRegion = aRegion;
671 pWindow->ImplIntersectWindowRegion( aTempRegion );
672 rRegion.Union( aTempRegion );
674 pWindow = pWindow->mpWindowImpl->mpNext;
678 void Window::SaveBackground(VirtualDevice& rSaveDevice, const Point& rPos, const Size& rSize, const Size&) const
680 MapMode aTempMap(GetMapMode());
681 aTempMap.SetOrigin(Point());
682 rSaveDevice.SetMapMode(aTempMap);
684 if ( mpWindowImpl->mpPaintRegion )
686 vcl::Region aClip( *mpWindowImpl->mpPaintRegion );
687 const Point aPixPos( LogicToPixel( rPos ) );
689 aClip.Move( -mnOutOffX, -mnOutOffY );
690 aClip.Intersect( tools::Rectangle( aPixPos, LogicToPixel( rSize ) ) );
692 if ( !aClip.IsEmpty() )
694 const vcl::Region aOldClip( rSaveDevice.GetClipRegion() );
695 const Point aPixOffset( rSaveDevice.LogicToPixel( Point() ) );
696 const bool bMap = rSaveDevice.IsMapModeEnabled();
698 // move clip region to have the same distance to DestOffset
699 aClip.Move( aPixOffset.X() - aPixPos.X(), aPixOffset.Y() - aPixPos.Y() );
701 // set pixel clip region
702 rSaveDevice.EnableMapMode( false );
703 rSaveDevice.SetClipRegion( aClip );
704 rSaveDevice.EnableMapMode( bMap );
705 rSaveDevice.DrawOutDev( Point(), rSize, rPos, rSize, *this );
706 rSaveDevice.SetClipRegion( aOldClip );
709 else
711 rSaveDevice.DrawOutDev( Point(), rSize, rPos, rSize, *this );
714 rSaveDevice.SetMapMode(MapMode());
717 } /* namespace vcl */
719 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */