LCOV - code coverage report
Current view: top level - vcl/source/window - clipping.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 215 501 42.9 %
Date: 2015-06-13 12:38:46 Functions: 23 37 62.2 %
Legend: Lines: hit not hit

          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 <vcl/window.hxx>
      21             : #include <vcl/virdev.hxx>
      22             : 
      23             : #include <sal/types.h>
      24             : 
      25             : #include <salobj.hxx>
      26             : #include <window.h>
      27             : 
      28             : #define IMPL_MAXSAVEBACKSIZE    (640*480)
      29             : #define IMPL_MAXALLSAVEBACKSIZE (800*600*2)
      30             : 
      31             : namespace vcl {
      32             : 
      33      568949 : void Window::InitClipRegion()
      34             : {
      35             :     DBG_TESTSOLARMUTEX();
      36             : 
      37      568949 :     vcl::Region  aRegion;
      38             : 
      39             :     // Put back backed up background
      40      568949 :     if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
      41           0 :         ImplInvalidateAllOverlapBackgrounds();
      42      568949 :     if ( mpWindowImpl->mbInPaint )
      43      544668 :         aRegion = *(mpWindowImpl->mpPaintRegion);
      44             :     else
      45             :     {
      46       24281 :         aRegion = *(ImplGetWinChildClipRegion());
      47             :         // --- RTL -- only this region is in frame coordinates, so re-mirror it
      48             :         // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
      49       24281 :         if( ImplIsAntiparallel() )
      50        1405 :             ReMirror ( aRegion );
      51             :     }
      52      568949 :     if ( mbClipRegion )
      53      342124 :         aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
      54      568949 :     if ( aRegion.IsEmpty() )
      55       96511 :         mbOutputClipped = true;
      56             :     else
      57             :     {
      58      472438 :         mbOutputClipped = false;
      59      472438 :         SelectClipRegion( aRegion );
      60             :     }
      61      568949 :     mbClipRegionSet = true;
      62             : 
      63      568949 :     mbInitClipRegion = false;
      64      568949 : }
      65             : 
      66       93864 : void Window::SetParentClipMode( ParentClipMode nMode )
      67             : {
      68       93864 :     if ( mpWindowImpl->mpBorderWindow )
      69         170 :         mpWindowImpl->mpBorderWindow->SetParentClipMode( nMode );
      70             :     else
      71             :     {
      72       93694 :         if ( !ImplIsOverlapWindow() )
      73             :         {
      74       93689 :             mpWindowImpl->mnParentClipMode = nMode;
      75       93689 :             if ( nMode & ParentClipMode::Clip )
      76          17 :                 mpWindowImpl->mpParent->mpWindowImpl->mbClipChildren = true;
      77             :         }
      78             :     }
      79       93864 : }
      80             : 
      81      190251 : ParentClipMode Window::GetParentClipMode() const
      82             : {
      83      190251 :     if ( mpWindowImpl->mpBorderWindow )
      84        2349 :         return mpWindowImpl->mpBorderWindow->GetParentClipMode();
      85             :     else
      86      187902 :         return mpWindowImpl->mnParentClipMode;
      87             : }
      88             : 
      89           0 : void Window::ExpandPaintClipRegion( const vcl::Region& rRegion )
      90             : {
      91           0 :     if( mpWindowImpl->mpPaintRegion )
      92             :     {
      93           0 :         vcl::Region aPixRegion = LogicToPixel( rRegion );
      94           0 :         vcl::Region aDevPixRegion = ImplPixelToDevicePixel( aPixRegion );
      95             : 
      96           0 :         vcl::Region aWinChildRegion = *ImplGetWinChildClipRegion();
      97             :         // --- RTL -- only this region is in frame coordinates, so re-mirror it
      98           0 :         if( ImplIsAntiparallel() )
      99             :         {
     100           0 :             const OutputDevice *pOutDev = GetOutDev();
     101           0 :             pOutDev->ReMirror( aWinChildRegion );
     102             :         }
     103             : 
     104           0 :         aDevPixRegion.Intersect( aWinChildRegion );
     105           0 :         if( ! aDevPixRegion.IsEmpty() )
     106             :         {
     107           0 :             mpWindowImpl->mpPaintRegion->Union( aDevPixRegion );
     108           0 :             mbInitClipRegion = true;
     109           0 :         }
     110             :     }
     111           0 : }
     112             : 
     113         275 : vcl::Region Window::GetWindowClipRegionPixel() const
     114             : {
     115         275 :     vcl::Region aWinClipRegion;
     116             : 
     117         275 :     if ( mpWindowImpl->mbInitWinClipRegion )
     118           0 :         const_cast<vcl::Window*>(this)->ImplInitWinClipRegion();
     119         275 :     aWinClipRegion = mpWindowImpl->maWinClipRegion;
     120             : 
     121         275 :     Rectangle     aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     122         550 :     vcl::Region   aWinRegion( aWinRect );
     123             : 
     124         275 :     if ( aWinRegion == aWinClipRegion )
     125         275 :         aWinClipRegion.SetNull();
     126             : 
     127         275 :     aWinClipRegion.Move( -mnOutOffX, -mnOutOffY );
     128             : 
     129         550 :     return aWinClipRegion;
     130             : }
     131             : 
     132             : 
     133       86377 : vcl::Region Window::GetActiveClipRegion() const
     134             : {
     135       86377 :     vcl::Region aRegion(true);
     136             : 
     137       86377 :     if ( mpWindowImpl->mbInPaint )
     138             :     {
     139       86377 :         aRegion = *(mpWindowImpl->mpPaintRegion);
     140       86377 :         aRegion.Move( -mnOutOffX, -mnOutOffY );
     141             :     }
     142             : 
     143       86377 :     if ( mbClipRegion )
     144           0 :         aRegion.Intersect( maRegion );
     145             : 
     146       86377 :     return PixelToLogic( aRegion );
     147             : }
     148             : 
     149       62870 : void Window::ClipToPaintRegion(Rectangle& rDstRect)
     150             : {
     151       62870 :     const vcl::Region aPaintRgn(GetPaintRegion());
     152             : 
     153       62870 :     if (!aPaintRgn.IsNull())
     154       62870 :         rDstRect.Intersection(LogicToPixel(aPaintRgn.GetBoundRect()));
     155       62870 : }
     156             : 
     157           0 : void Window::EnableClipSiblings( bool bClipSiblings )
     158             : {
     159             : 
     160           0 :     if ( mpWindowImpl->mpBorderWindow )
     161           0 :         mpWindowImpl->mpBorderWindow->EnableClipSiblings( bClipSiblings );
     162             : 
     163           0 :     mpWindowImpl->mbClipSiblings = bClipSiblings;
     164           0 : }
     165             : 
     166      507070 : void Window::ImplClipBoundaries( vcl::Region& rRegion, bool bThis, bool bOverlaps )
     167             : {
     168      507070 :     if ( bThis )
     169       84631 :         ImplIntersectWindowClipRegion( rRegion );
     170      422439 :     else if ( ImplIsOverlapWindow() )
     171             :     {
     172             :         // clip to frame if required
     173        4003 :         if ( !mpWindowImpl->mbFrame )
     174           0 :             rRegion.Intersect( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
     175             : 
     176        4003 :         if ( bOverlaps && !rRegion.IsEmpty() )
     177             :         {
     178             :             // Clip Overlap Siblings
     179        3964 :             vcl::Window* pStartOverlapWindow = this;
     180        7928 :             while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
     181             :             {
     182           0 :                 vcl::Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
     183           0 :                 while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
     184             :                 {
     185           0 :                     pOverlapWindow->ImplExcludeOverlapWindows2( rRegion );
     186           0 :                     pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
     187             :                 }
     188           0 :                 pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
     189             :             }
     190             : 
     191             :             // Clip Child Overlap Windows
     192        3964 :             ImplExcludeOverlapWindows( rRegion );
     193             :         }
     194             :     }
     195             :     else
     196      418436 :         ImplGetParent()->ImplIntersectWindowClipRegion( rRegion );
     197      507070 : }
     198             : 
     199       99073 : bool Window::ImplClipChildren( vcl::Region& rRegion )
     200             : {
     201       99073 :     bool    bOtherClip = false;
     202       99073 :     vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     203      559442 :     while ( pWindow )
     204             :     {
     205      361296 :         if ( pWindow->mpWindowImpl->mbReallyVisible )
     206             :         {
     207             :             // read-out ParentClipMode-Flags
     208      182011 :             ParentClipMode nClipMode = pWindow->GetParentClipMode();
     209      892679 :             if ( !(nClipMode & ParentClipMode::NoClip) &&
     210      710668 :                  ((nClipMode & ParentClipMode::Clip) || (GetStyle() & WB_CLIPCHILDREN)) )
     211      176219 :                 pWindow->ImplExcludeWindowRegion( rRegion );
     212             :             else
     213        5792 :                 bOtherClip = true;
     214             :         }
     215             : 
     216      361296 :         pWindow = pWindow->mpWindowImpl->mpNext;
     217             :     }
     218             : 
     219       99073 :     return bOtherClip;
     220             : }
     221             : 
     222         930 : void Window::ImplClipAllChildren( vcl::Region& rRegion )
     223             : {
     224         930 :     vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     225        2850 :     while ( pWindow )
     226             :     {
     227         990 :         if ( pWindow->mpWindowImpl->mbReallyVisible )
     228         704 :             pWindow->ImplExcludeWindowRegion( rRegion );
     229         990 :         pWindow = pWindow->mpWindowImpl->mpNext;
     230             :     }
     231         930 : }
     232             : 
     233           0 : void Window::ImplClipSiblings( vcl::Region& rRegion )
     234             : {
     235           0 :     vcl::Window* pWindow = ImplGetParent()->mpWindowImpl->mpFirstChild;
     236           0 :     while ( pWindow )
     237             :     {
     238           0 :         if ( pWindow == this )
     239           0 :             break;
     240             : 
     241           0 :         if ( pWindow->mpWindowImpl->mbReallyVisible )
     242           0 :             pWindow->ImplExcludeWindowRegion( rRegion );
     243             : 
     244           0 :         pWindow = pWindow->mpWindowImpl->mpNext;
     245             :     }
     246           0 : }
     247             : 
     248      269247 : void Window::ImplInitWinClipRegion()
     249             : {
     250             :     // Build Window Region
     251      538494 :     mpWindowImpl->maWinClipRegion = Rectangle( Point( mnOutOffX, mnOutOffY ),
     252      269247 :                                  Size( mnOutWidth, mnOutHeight ) );
     253      269247 :     if ( mpWindowImpl->mbWinRegion )
     254           0 :         mpWindowImpl->maWinClipRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
     255             : 
     256             :     // ClipSiblings
     257      269247 :     if ( mpWindowImpl->mbClipSiblings && !ImplIsOverlapWindow() )
     258           0 :         ImplClipSiblings( mpWindowImpl->maWinClipRegion );
     259             : 
     260             :     // Clip Parent Boundaries
     261      269247 :     ImplClipBoundaries( mpWindowImpl->maWinClipRegion, false, true );
     262             : 
     263             :     // Clip Children
     264      269247 :     if ( (GetStyle() & WB_CLIPCHILDREN) || mpWindowImpl->mbClipChildren )
     265      113850 :         mpWindowImpl->mbInitChildRegion = true;
     266             : 
     267      269247 :     mpWindowImpl->mbInitWinClipRegion = false;
     268      269247 : }
     269             : 
     270       80525 : void Window::ImplInitWinChildClipRegion()
     271             : {
     272       80525 :     if ( !mpWindowImpl->mpFirstChild )
     273             :     {
     274       27141 :         if ( mpWindowImpl->mpChildClipRegion )
     275             :         {
     276          31 :             delete mpWindowImpl->mpChildClipRegion;
     277          31 :             mpWindowImpl->mpChildClipRegion = NULL;
     278             :         }
     279             :     }
     280             :     else
     281             :     {
     282       53384 :         if ( !mpWindowImpl->mpChildClipRegion )
     283       18282 :             mpWindowImpl->mpChildClipRegion = new vcl::Region( mpWindowImpl->maWinClipRegion );
     284             :         else
     285       35102 :             *mpWindowImpl->mpChildClipRegion = mpWindowImpl->maWinClipRegion;
     286             : 
     287       53384 :         ImplClipChildren( *mpWindowImpl->mpChildClipRegion );
     288             :     }
     289             : 
     290       80525 :     mpWindowImpl->mbInitChildRegion = false;
     291       80525 : }
     292             : 
     293      263851 : Region* Window::ImplGetWinChildClipRegion()
     294             : {
     295      263851 :     if ( mpWindowImpl->mbInitWinClipRegion )
     296      143401 :         ImplInitWinClipRegion();
     297      263851 :     if ( mpWindowImpl->mbInitChildRegion )
     298       80525 :         ImplInitWinChildClipRegion();
     299      263851 :     if ( mpWindowImpl->mpChildClipRegion )
     300       58146 :         return mpWindowImpl->mpChildClipRegion;
     301             :     else
     302      205705 :         return &mpWindowImpl->maWinClipRegion;
     303             : }
     304             : 
     305             : 
     306          56 : bool Window::ImplSysObjClip( const vcl::Region* pOldRegion )
     307             : {
     308          56 :     bool bUpdate = true;
     309             : 
     310          56 :     if ( mpWindowImpl->mpSysObj )
     311             :     {
     312          56 :         bool bVisibleState = mpWindowImpl->mbReallyVisible;
     313             : 
     314          56 :         if ( bVisibleState )
     315             :         {
     316           0 :             vcl::Region* pWinChildClipRegion = ImplGetWinChildClipRegion();
     317             : 
     318           0 :             if ( !pWinChildClipRegion->IsEmpty() )
     319             :             {
     320           0 :                 if ( pOldRegion )
     321             :                 {
     322           0 :                     vcl::Region aNewRegion = *pWinChildClipRegion;
     323           0 :                     pWinChildClipRegion->Intersect( *pOldRegion );
     324           0 :                     bUpdate = aNewRegion == *pWinChildClipRegion;
     325             :                 }
     326             : 
     327           0 :                 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
     328           0 :                     ImplInvalidateAllOverlapBackgrounds();
     329             : 
     330           0 :                 vcl::Region      aRegion = *pWinChildClipRegion;
     331           0 :                 Rectangle   aWinRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     332           0 :                 vcl::Region      aWinRectRegion( aWinRect );
     333           0 :                 sal_uInt16      nClipFlags = mpWindowImpl->mpSysObj->GetClipRegionType();
     334             : 
     335           0 :                 if ( aRegion == aWinRectRegion )
     336           0 :                     mpWindowImpl->mpSysObj->ResetClipRegion();
     337             :                 else
     338             :                 {
     339           0 :                     if ( nClipFlags & SAL_OBJECT_CLIP_EXCLUDERECTS )
     340             :                     {
     341           0 :                         aWinRectRegion.Exclude( aRegion );
     342           0 :                         aRegion = aWinRectRegion;
     343             :                     }
     344           0 :                     if ( !(nClipFlags & SAL_OBJECT_CLIP_ABSOLUTE) )
     345           0 :                         aRegion.Move( -mnOutOffX, -mnOutOffY );
     346             : 
     347             :                     // set/update clip region
     348           0 :                     RectangleVector aRectangles;
     349           0 :                     aRegion.GetRegionRectangles(aRectangles);
     350           0 :                     mpWindowImpl->mpSysObj->BeginSetClipRegion(aRectangles.size());
     351             : 
     352           0 :                     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     353             :                     {
     354             :                         mpWindowImpl->mpSysObj->UnionClipRegion(
     355             :                             aRectIter->Left(),
     356             :                             aRectIter->Top(),
     357             :                             aRectIter->GetWidth(),   // orig nWidth was ((R - L) + 1), same as GetWidth does
     358           0 :                             aRectIter->GetHeight()); // same for height
     359             :                     }
     360             : 
     361           0 :                     mpWindowImpl->mpSysObj->EndSetClipRegion();
     362           0 :                 }
     363             :             }
     364             :             else
     365           0 :                 bVisibleState = false;
     366             :         }
     367             : 
     368             :         // update visible status
     369          56 :         mpWindowImpl->mpSysObj->Show( bVisibleState );
     370             :     }
     371             : 
     372          56 :     return bUpdate;
     373             : }
     374             : 
     375           0 : void Window::ImplUpdateSysObjChildrenClip()
     376             : {
     377           0 :     if ( mpWindowImpl->mpSysObj && mpWindowImpl->mbInitWinClipRegion )
     378           0 :         ImplSysObjClip( NULL );
     379             : 
     380           0 :     vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     381           0 :     while ( pWindow )
     382             :     {
     383           0 :         pWindow->ImplUpdateSysObjChildrenClip();
     384           0 :         pWindow = pWindow->mpWindowImpl->mpNext;
     385             :     }
     386           0 : }
     387             : 
     388           0 : void Window::ImplUpdateSysObjOverlapsClip()
     389             : {
     390           0 :     ImplUpdateSysObjChildrenClip();
     391             : 
     392           0 :     vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
     393           0 :     while ( pWindow )
     394             :     {
     395           0 :         pWindow->ImplUpdateSysObjOverlapsClip();
     396           0 :         pWindow = pWindow->mpWindowImpl->mpNext;
     397             :     }
     398           0 : }
     399             : 
     400           0 : void Window::ImplUpdateSysObjClip()
     401             : {
     402           0 :     if ( !ImplIsOverlapWindow() )
     403             :     {
     404           0 :         ImplUpdateSysObjChildrenClip();
     405             : 
     406             :         // siblings should recalculate their clip region
     407           0 :         if ( mpWindowImpl->mbClipSiblings )
     408             :         {
     409           0 :             vcl::Window* pWindow = mpWindowImpl->mpNext;
     410           0 :             while ( pWindow )
     411             :             {
     412           0 :                 pWindow->ImplUpdateSysObjChildrenClip();
     413           0 :                 pWindow = pWindow->mpWindowImpl->mpNext;
     414             :             }
     415             :         }
     416             :     }
     417             :     else
     418           0 :         mpWindowImpl->mpFrameWindow->ImplUpdateSysObjOverlapsClip();
     419           0 : }
     420             : 
     421     1799568 : bool Window::ImplSetClipFlagChildren( bool bSysObjOnlySmaller )
     422             : {
     423     1799568 :     bool bUpdate = true;
     424     1799568 :     if ( mpWindowImpl->mpSysObj )
     425             :     {
     426          56 :         vcl::Region* pOldRegion = NULL;
     427          56 :         if ( bSysObjOnlySmaller && !mpWindowImpl->mbInitWinClipRegion )
     428           0 :             pOldRegion = new vcl::Region( mpWindowImpl->maWinClipRegion );
     429             : 
     430          56 :         mbInitClipRegion = true;
     431          56 :         mpWindowImpl->mbInitWinClipRegion = true;
     432             : 
     433          56 :         vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     434         112 :         while ( pWindow )
     435             :         {
     436           0 :             if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
     437           0 :                 bUpdate = false;
     438           0 :             pWindow = pWindow->mpWindowImpl->mpNext;
     439             :         }
     440             : 
     441          56 :         if ( !ImplSysObjClip( pOldRegion ) )
     442             :         {
     443           0 :             mbInitClipRegion = true;
     444           0 :             mpWindowImpl->mbInitWinClipRegion = true;
     445           0 :             bUpdate = false;
     446             :         }
     447             : 
     448          56 :         delete pOldRegion;
     449             :     }
     450             :     else
     451             :     {
     452     1799512 :     mbInitClipRegion = true;
     453     1799512 :     mpWindowImpl->mbInitWinClipRegion = true;
     454             : 
     455     1799512 :     vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     456     5127128 :     while ( pWindow )
     457             :     {
     458     1528104 :         if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
     459           0 :             bUpdate = false;
     460     1528104 :         pWindow = pWindow->mpWindowImpl->mpNext;
     461             :     }
     462             :     }
     463     1799568 :     return bUpdate;
     464             : }
     465             : 
     466        6462 : bool Window::ImplSetClipFlagOverlapWindows( bool bSysObjOnlySmaller )
     467             : {
     468        6462 :     bool bUpdate = ImplSetClipFlagChildren( bSysObjOnlySmaller );
     469             : 
     470        6462 :     vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
     471       12924 :     while ( pWindow )
     472             :     {
     473           0 :         if ( !pWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller ) )
     474           0 :             bUpdate = false;
     475           0 :         pWindow = pWindow->mpWindowImpl->mpNext;
     476             :     }
     477             : 
     478        6462 :     return bUpdate;
     479             : }
     480             : 
     481      271464 : bool Window::ImplSetClipFlag( bool bSysObjOnlySmaller )
     482             : {
     483      271464 :     if ( !ImplIsOverlapWindow() )
     484             :     {
     485      265002 :         bool bUpdate = ImplSetClipFlagChildren( bSysObjOnlySmaller );
     486             : 
     487      265002 :         vcl::Window* pParent = ImplGetParent();
     488     1223976 :         if ( pParent &&
     489      631038 :              ((pParent->GetStyle() & WB_CLIPCHILDREN) || (mpWindowImpl->mnParentClipMode & ParentClipMode::Clip)) )
     490             :         {
     491      214485 :             pParent->mbInitClipRegion = true;
     492      214485 :             pParent->mpWindowImpl->mbInitChildRegion = true;
     493             :         }
     494             : 
     495             :         // siblings should recalculate their clip region
     496      265002 :         if ( mpWindowImpl->mbClipSiblings )
     497             :         {
     498           0 :             vcl::Window* pWindow = mpWindowImpl->mpNext;
     499           0 :             while ( pWindow )
     500             :             {
     501           0 :                 if ( !pWindow->ImplSetClipFlagChildren( bSysObjOnlySmaller ) )
     502           0 :                     bUpdate = false;
     503           0 :                 pWindow = pWindow->mpWindowImpl->mpNext;
     504             :             }
     505             :         }
     506             : 
     507      265002 :         return bUpdate;
     508             :     }
     509             :     else
     510        6462 :         return mpWindowImpl->mpFrameWindow->ImplSetClipFlagOverlapWindows( bSysObjOnlySmaller );
     511             : }
     512             : 
     513      503067 : void Window::ImplIntersectWindowClipRegion( vcl::Region& rRegion )
     514             : {
     515      503067 :     if ( mpWindowImpl->mbInitWinClipRegion )
     516       98369 :         ImplInitWinClipRegion();
     517             : 
     518      503067 :     rRegion.Intersect( mpWindowImpl->maWinClipRegion );
     519      503067 : }
     520             : 
     521          22 : void Window::ImplIntersectWindowRegion( vcl::Region& rRegion )
     522             : {
     523             :     rRegion.Intersect( Rectangle( Point( mnOutOffX, mnOutOffY ),
     524          22 :                                   Size( mnOutWidth, mnOutHeight ) ) );
     525          22 :     if ( mpWindowImpl->mbWinRegion )
     526           0 :         rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
     527          22 : }
     528             : 
     529      321834 : void Window::ImplExcludeWindowRegion( vcl::Region& rRegion )
     530             : {
     531      321834 :     if ( mpWindowImpl->mbWinRegion )
     532             :     {
     533           0 :         Point aPoint( mnOutOffX, mnOutOffY );
     534             :         vcl::Region aRegion( Rectangle( aPoint,
     535           0 :                                    Size( mnOutWidth, mnOutHeight ) ) );
     536           0 :         aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
     537           0 :         rRegion.Exclude( aRegion );
     538             :     }
     539             :     else
     540             :     {
     541      321834 :         Point aPoint( mnOutOffX, mnOutOffY );
     542             :         rRegion.Exclude( Rectangle( aPoint,
     543      321834 :                                     Size( mnOutWidth, mnOutHeight ) ) );
     544             :     }
     545      321834 : }
     546             : 
     547        3964 : void Window::ImplExcludeOverlapWindows( vcl::Region& rRegion )
     548             : {
     549        3964 :     vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
     550        7928 :     while ( pWindow )
     551             :     {
     552           0 :         if ( pWindow->mpWindowImpl->mbReallyVisible )
     553             :         {
     554           0 :             pWindow->ImplExcludeWindowRegion( rRegion );
     555           0 :             pWindow->ImplExcludeOverlapWindows( rRegion );
     556             :         }
     557             : 
     558           0 :         pWindow = pWindow->mpWindowImpl->mpNext;
     559             :     }
     560        3964 : }
     561             : 
     562           0 : void Window::ImplExcludeOverlapWindows2( vcl::Region& rRegion )
     563             : {
     564           0 :     if ( mpWindowImpl->mbReallyVisible )
     565           0 :         ImplExcludeWindowRegion( rRegion );
     566             : 
     567           0 :     ImplExcludeOverlapWindows( rRegion );
     568           0 : }
     569             : 
     570         460 : void Window::ImplIntersectAndUnionOverlapWindows( const vcl::Region& rInterRegion, vcl::Region& rRegion )
     571             : {
     572         460 :     vcl::Window* pWindow = mpWindowImpl->mpFirstOverlap;
     573         920 :     while ( pWindow )
     574             :     {
     575           0 :         if ( pWindow->mpWindowImpl->mbReallyVisible )
     576             :         {
     577           0 :             vcl::Region aTempRegion( rInterRegion );
     578           0 :             pWindow->ImplIntersectWindowRegion( aTempRegion );
     579           0 :             rRegion.Union( aTempRegion );
     580           0 :             pWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
     581             :         }
     582             : 
     583           0 :         pWindow = pWindow->mpWindowImpl->mpNext;
     584             :     }
     585         460 : }
     586             : 
     587           0 : void Window::ImplIntersectAndUnionOverlapWindows2( const vcl::Region& rInterRegion, vcl::Region& rRegion )
     588             : {
     589           0 :     if ( mpWindowImpl->mbReallyVisible )
     590             :     {
     591           0 :         vcl::Region aTempRegion( rInterRegion );
     592           0 :         ImplIntersectWindowRegion( aTempRegion );
     593           0 :         rRegion.Union( aTempRegion );
     594             :     }
     595             : 
     596           0 :     ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
     597           0 : }
     598             : 
     599         460 : void Window::ImplCalcOverlapRegionOverlaps( const vcl::Region& rInterRegion, vcl::Region& rRegion )
     600             : {
     601             :     // Clip Overlap Siblings
     602             :     vcl::Window* pStartOverlapWindow;
     603         460 :     if ( !ImplIsOverlapWindow() )
     604         460 :         pStartOverlapWindow = mpWindowImpl->mpOverlapWindow;
     605             :     else
     606           0 :         pStartOverlapWindow = this;
     607         920 :     while ( !pStartOverlapWindow->mpWindowImpl->mbFrame )
     608             :     {
     609           0 :         vcl::Window* pOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow->mpWindowImpl->mpFirstOverlap;
     610           0 :         while ( pOverlapWindow && (pOverlapWindow != pStartOverlapWindow) )
     611             :         {
     612           0 :             pOverlapWindow->ImplIntersectAndUnionOverlapWindows2( rInterRegion, rRegion );
     613           0 :             pOverlapWindow = pOverlapWindow->mpWindowImpl->mpNext;
     614             :         }
     615           0 :         pStartOverlapWindow = pStartOverlapWindow->mpWindowImpl->mpOverlapWindow;
     616             :     }
     617             : 
     618             :     // Clip Child Overlap Windows
     619         460 :     if ( !ImplIsOverlapWindow() )
     620         460 :         mpWindowImpl->mpOverlapWindow->ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
     621             :     else
     622           0 :         ImplIntersectAndUnionOverlapWindows( rInterRegion, rRegion );
     623         460 : }
     624             : 
     625         460 : void Window::ImplCalcOverlapRegion( const Rectangle& rSourceRect, vcl::Region& rRegion,
     626             :                                     bool bChildren, bool bParent, bool bSiblings )
     627             : {
     628         460 :     vcl::Region  aRegion( rSourceRect );
     629         460 :     if ( mpWindowImpl->mbWinRegion )
     630           0 :         rRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
     631         920 :     vcl::Region  aTempRegion;
     632             :     vcl::Window* pWindow;
     633             : 
     634         460 :     ImplCalcOverlapRegionOverlaps( aRegion, rRegion );
     635             : 
     636             :     // Parent-Boundaries
     637         460 :     if ( bParent )
     638             :     {
     639         460 :         pWindow = this;
     640         460 :         if ( !ImplIsOverlapWindow() )
     641             :         {
     642         460 :             pWindow = ImplGetParent();
     643        1829 :             do
     644             :             {
     645        2289 :                 aTempRegion = aRegion;
     646        2289 :                 pWindow->ImplExcludeWindowRegion( aTempRegion );
     647        2289 :                 rRegion.Union( aTempRegion );
     648        2289 :                 if ( pWindow->ImplIsOverlapWindow() )
     649         460 :                     break;
     650        1829 :                 pWindow = pWindow->ImplGetParent();
     651             :             }
     652             :             while ( pWindow );
     653             :         }
     654         460 :         if ( pWindow && !pWindow->mpWindowImpl->mbFrame )
     655             :         {
     656           0 :             aTempRegion = aRegion;
     657           0 :             aTempRegion.Exclude( Rectangle( Point( 0, 0 ), Size( mpWindowImpl->mpFrameWindow->mnOutWidth, mpWindowImpl->mpFrameWindow->mnOutHeight ) ) );
     658           0 :             rRegion.Union( aTempRegion );
     659             :         }
     660             :     }
     661             : 
     662             :     // Siblings
     663         460 :     if ( bSiblings && !ImplIsOverlapWindow() )
     664             :     {
     665          11 :         pWindow = mpWindowImpl->mpParent->mpWindowImpl->mpFirstChild;
     666          76 :         do
     667             :         {
     668          76 :             if ( pWindow->mpWindowImpl->mbReallyVisible && (pWindow != this) )
     669             :             {
     670          19 :                 aTempRegion = aRegion;
     671          19 :                 pWindow->ImplIntersectWindowRegion( aTempRegion );
     672          19 :                 rRegion.Union( aTempRegion );
     673             :             }
     674          76 :             pWindow = pWindow->mpWindowImpl->mpNext;
     675             :         }
     676             :         while ( pWindow );
     677             :     }
     678             : 
     679         460 :     if ( bChildren )
     680             :     {
     681         397 :         pWindow = mpWindowImpl->mpFirstChild;
     682         803 :         while ( pWindow )
     683             :         {
     684           9 :             if ( pWindow->mpWindowImpl->mbReallyVisible )
     685             :             {
     686           3 :                 aTempRegion = aRegion;
     687           3 :                 pWindow->ImplIntersectWindowRegion( aTempRegion );
     688           3 :                 rRegion.Union( aTempRegion );
     689             :             }
     690           9 :             pWindow = pWindow->mpWindowImpl->mpNext;
     691             :         }
     692         460 :     }
     693         460 : }
     694             : 
     695           0 : bool Window::ImplIsWindowInFront( const vcl::Window* pTestWindow ) const
     696             : {
     697             :     // check for overlapping window
     698           0 :     pTestWindow = pTestWindow->ImplGetFirstOverlapWindow();
     699           0 :     const vcl::Window* pTempWindow = pTestWindow;
     700           0 :     const vcl::Window* pThisWindow = ImplGetFirstOverlapWindow();
     701           0 :     if ( pTempWindow == pThisWindow )
     702           0 :         return false;
     703           0 :     do
     704             :     {
     705           0 :         if ( pTempWindow == pThisWindow )
     706           0 :             return true;
     707           0 :         if ( pTempWindow->mpWindowImpl->mbFrame )
     708           0 :             break;
     709           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
     710             :     }
     711             :     while ( pTempWindow );
     712           0 :     pTempWindow = pThisWindow;
     713           0 :     do
     714             :     {
     715           0 :         if ( pTempWindow == pTestWindow )
     716           0 :             return false;
     717           0 :         if ( pTempWindow->mpWindowImpl->mbFrame )
     718           0 :             break;
     719           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
     720             :     }
     721             :     while ( pTempWindow );
     722             : 
     723             :     // move window to same level
     724           0 :     if ( pThisWindow->mpWindowImpl->mpOverlapWindow != pTestWindow->mpWindowImpl->mpOverlapWindow )
     725             :     {
     726           0 :         sal_uInt16 nThisLevel = 0;
     727           0 :         sal_uInt16 nTestLevel = 0;
     728           0 :         pTempWindow = pThisWindow;
     729           0 :         do
     730             :         {
     731           0 :             nThisLevel++;
     732           0 :             pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
     733             :         }
     734           0 :         while ( !pTempWindow->mpWindowImpl->mbFrame );
     735           0 :         pTempWindow = pTestWindow;
     736           0 :         do
     737             :         {
     738           0 :             nTestLevel++;
     739           0 :             pTempWindow = pTempWindow->mpWindowImpl->mpOverlapWindow;
     740             :         }
     741           0 :         while ( !pTempWindow->mpWindowImpl->mbFrame );
     742             : 
     743           0 :         if ( nThisLevel < nTestLevel )
     744             :         {
     745           0 :             do
     746             :             {
     747           0 :                 if ( pTestWindow->mpWindowImpl->mpOverlapWindow == pThisWindow->mpWindowImpl->mpOverlapWindow )
     748           0 :                     break;
     749           0 :                 if ( pTestWindow->mpWindowImpl->mbFrame )
     750           0 :                     break;
     751           0 :                 pTestWindow = pTestWindow->mpWindowImpl->mpOverlapWindow;
     752             :             }
     753             :             while ( pTestWindow );
     754             :         }
     755             :         else
     756             :         {
     757           0 :             do
     758             :             {
     759           0 :                 if ( pThisWindow->mpWindowImpl->mpOverlapWindow == pTempWindow->mpWindowImpl->mpOverlapWindow )
     760           0 :                     break;
     761           0 :                 if ( pThisWindow->mpWindowImpl->mbFrame )
     762           0 :                     break;
     763           0 :                 pThisWindow = pThisWindow->mpWindowImpl->mpOverlapWindow;
     764             :             }
     765             :             while ( pThisWindow );
     766             :         }
     767             :     }
     768             : 
     769             :     // if TestWindow is before ThisWindow, it is in front
     770           0 :     pTempWindow = pTestWindow;
     771           0 :     while ( pTempWindow )
     772             :     {
     773           0 :         if ( pTempWindow == pThisWindow )
     774           0 :             return true;
     775           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
     776             :     }
     777             : 
     778           0 :     return false;
     779             : }
     780             : 
     781           0 : void Window::SaveBackground( const Point& rPos, const Size& rSize,
     782             :                              const Point& rDestOff, VirtualDevice& rSaveDevice )
     783             : {
     784           0 :     if ( mpWindowImpl->mpPaintRegion )
     785             :     {
     786           0 :         vcl::Region      aClip( *mpWindowImpl->mpPaintRegion );
     787           0 :         const Point aPixPos( LogicToPixel( rPos ) );
     788             : 
     789           0 :         aClip.Move( -mnOutOffX, -mnOutOffY );
     790           0 :         aClip.Intersect( Rectangle( aPixPos, LogicToPixel( rSize ) ) );
     791             : 
     792           0 :         if ( !aClip.IsEmpty() )
     793             :         {
     794           0 :             const vcl::Region    aOldClip( rSaveDevice.GetClipRegion() );
     795           0 :             const Point     aPixOffset( rSaveDevice.LogicToPixel( rDestOff ) );
     796           0 :             const bool      bMap = rSaveDevice.IsMapModeEnabled();
     797             : 
     798             :             // move clip region to have the same distance to DestOffset
     799           0 :             aClip.Move( aPixOffset.X() - aPixPos.X(), aPixOffset.Y() - aPixPos.Y() );
     800             : 
     801             :             // set pixel clip region
     802           0 :             rSaveDevice.EnableMapMode( false );
     803           0 :             rSaveDevice.SetClipRegion( aClip );
     804           0 :             rSaveDevice.EnableMapMode( bMap );
     805           0 :             rSaveDevice.DrawOutDev( rDestOff, rSize, rPos, rSize, *this );
     806           0 :             rSaveDevice.SetClipRegion( aOldClip );
     807           0 :         }
     808             :     }
     809             :     else
     810           0 :         rSaveDevice.DrawOutDev( rDestOff, rSize, rPos, rSize, *this );
     811           0 : }
     812             : 
     813           0 : void Window::ImplSaveOverlapBackground()
     814             : {
     815             :     DBG_ASSERT( !mpWindowImpl->mpOverlapData->mpSaveBackDev, "Window::ImplSaveOverlapBackground() - Background already saved" );
     816             : 
     817           0 :     if ( !mpWindowImpl->mbFrame )
     818             :     {
     819           0 :         sal_uLong nSaveBackSize = mnOutWidth*mnOutHeight;
     820           0 :         if ( nSaveBackSize <= IMPL_MAXSAVEBACKSIZE )
     821             :         {
     822           0 :             if ( nSaveBackSize+mpWindowImpl->mpFrameData->mnAllSaveBackSize <= IMPL_MAXALLSAVEBACKSIZE )
     823             :             {
     824           0 :                 Size aOutSize( mnOutWidth, mnOutHeight );
     825           0 :                 mpWindowImpl->mpOverlapData->mpSaveBackDev = VclPtr<VirtualDevice>::Create( *mpWindowImpl->mpFrameWindow );
     826           0 :                 if ( mpWindowImpl->mpOverlapData->mpSaveBackDev->SetOutputSizePixel( aOutSize ) )
     827             :                 {
     828           0 :                     mpWindowImpl->mpFrameWindow->ImplUpdateAll();
     829             : 
     830           0 :                     if ( mpWindowImpl->mbInitWinClipRegion )
     831           0 :                         ImplInitWinClipRegion();
     832             : 
     833           0 :                     mpWindowImpl->mpOverlapData->mnSaveBackSize = nSaveBackSize;
     834           0 :                     mpWindowImpl->mpFrameData->mnAllSaveBackSize += nSaveBackSize;
     835           0 :                     Point aDevPt;
     836             : 
     837           0 :                     Window* pWin = mpWindowImpl->mpFrameWindow;
     838             :                     pWin->getFrameDev( Point( mnOutOffX, mnOutOffY ),
     839             :                                            aDevPt, aOutSize,
     840           0 :                                            *(mpWindowImpl->mpOverlapData->mpSaveBackDev) );
     841           0 :                     mpWindowImpl->mpOverlapData->mpNextBackWin = mpWindowImpl->mpFrameData->mpFirstBackWin;
     842           0 :                     mpWindowImpl->mpFrameData->mpFirstBackWin = this;
     843             :                 }
     844             :                 else
     845             :                 {
     846           0 :                     mpWindowImpl->mpOverlapData->mpSaveBackDev.disposeAndClear();
     847             :                 }
     848             :             }
     849             :         }
     850             :     }
     851           0 : }
     852             : 
     853           0 : bool Window::ImplRestoreOverlapBackground( vcl::Region& rInvRegion )
     854             : {
     855           0 :     if ( mpWindowImpl->mpOverlapData->mpSaveBackDev )
     856             :     {
     857           0 :         if ( mpWindowImpl->mbInitWinClipRegion )
     858           0 :             ImplInitWinClipRegion();
     859             : 
     860           0 :         if ( mpWindowImpl->mpOverlapData->mpSaveBackDev )
     861             :         {
     862           0 :             Point   aDevPt;
     863           0 :             Point   aDestPt( mnOutOffX, mnOutOffY );
     864           0 :             Size    aDevSize = mpWindowImpl->mpOverlapData->mpSaveBackDev->GetOutputSizePixel();
     865             : 
     866           0 :             Window *pWin = mpWindowImpl->mpFrameWindow;
     867             : 
     868           0 :             if ( mpWindowImpl->mpOverlapData->mpSaveBackRgn )
     869             :             {
     870           0 :                 mpWindowImpl->mpOverlapData->mpSaveBackRgn->Intersect( mpWindowImpl->maWinClipRegion );
     871           0 :                 rInvRegion = mpWindowImpl->maWinClipRegion;
     872           0 :                 rInvRegion.Exclude( *mpWindowImpl->mpOverlapData->mpSaveBackRgn );
     873             :                 pWin->drawFrameDev( aDestPt, aDevPt, aDevSize,
     874           0 :                                     *(mpWindowImpl->mpOverlapData->mpSaveBackDev),
     875           0 :                                     *mpWindowImpl->mpOverlapData->mpSaveBackRgn );
     876             :             }
     877             :             else
     878             :             {
     879             :                 pWin->drawFrameDev( aDestPt, aDevPt, aDevSize,
     880           0 :                                     *(mpWindowImpl->mpOverlapData->mpSaveBackDev),
     881           0 :                                     mpWindowImpl->maWinClipRegion );
     882             :             }
     883           0 :             ImplDeleteOverlapBackground();
     884             :         }
     885             : 
     886           0 :         return true;
     887             :     }
     888             : 
     889           0 :     return false;
     890             : }
     891             : 
     892           0 : void Window::ImplDeleteOverlapBackground()
     893             : {
     894           0 :     if ( mpWindowImpl->mpOverlapData->mpSaveBackDev )
     895             :     {
     896           0 :         mpWindowImpl->mpFrameData->mnAllSaveBackSize -= mpWindowImpl->mpOverlapData->mnSaveBackSize;
     897           0 :         mpWindowImpl->mpOverlapData->mpSaveBackDev.disposeAndClear();
     898           0 :         if ( mpWindowImpl->mpOverlapData->mpSaveBackRgn )
     899             :         {
     900           0 :             delete mpWindowImpl->mpOverlapData->mpSaveBackRgn;
     901           0 :             mpWindowImpl->mpOverlapData->mpSaveBackRgn = NULL;
     902             :         }
     903             : 
     904             :         // remove window from the list
     905           0 :         if ( mpWindowImpl->mpFrameData->mpFirstBackWin == this )
     906           0 :             mpWindowImpl->mpFrameData->mpFirstBackWin = mpWindowImpl->mpOverlapData->mpNextBackWin;
     907             :         else
     908             :         {
     909           0 :             vcl::Window* pTemp = mpWindowImpl->mpFrameData->mpFirstBackWin;
     910           0 :             while ( pTemp->mpWindowImpl->mpOverlapData->mpNextBackWin.get() != this )
     911           0 :                 pTemp = pTemp->mpWindowImpl->mpOverlapData->mpNextBackWin;
     912           0 :             pTemp->mpWindowImpl->mpOverlapData->mpNextBackWin = mpWindowImpl->mpOverlapData->mpNextBackWin;
     913             :         }
     914           0 :         mpWindowImpl->mpOverlapData->mpNextBackWin = NULL;
     915             :     }
     916           0 : }
     917             : 
     918           0 : void Window::ImplInvalidateAllOverlapBackgrounds()
     919             : {
     920           0 :     vcl::Window* pWindow = mpWindowImpl->mpFrameData->mpFirstBackWin;
     921           0 :     while ( pWindow )
     922             :     {
     923             :         // remember next window here already, as this window could
     924             :         // be removed within the next if clause from the list
     925           0 :         vcl::Window* pNext = pWindow->mpWindowImpl->mpOverlapData->mpNextBackWin;
     926             : 
     927           0 :         if ( ImplIsWindowInFront( pWindow ) )
     928             :         {
     929             :             Rectangle aRect1( Point( mnOutOffX, mnOutOffY ),
     930           0 :                               Size( mnOutWidth, mnOutHeight ) );
     931             :             Rectangle aRect2( Point( pWindow->mnOutOffX, pWindow->mnOutOffY ),
     932           0 :                               Size( pWindow->mnOutWidth, pWindow->mnOutHeight ) );
     933           0 :             aRect1.Intersection( aRect2 );
     934           0 :             if ( !aRect1.IsEmpty() )
     935             :             {
     936           0 :                 if ( !pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn )
     937           0 :                     pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn = new vcl::Region( aRect2 );
     938           0 :                 pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn->Exclude( aRect1 );
     939           0 :                 if ( pWindow->mpWindowImpl->mpOverlapData->mpSaveBackRgn->IsEmpty() )
     940           0 :                     pWindow->ImplDeleteOverlapBackground();
     941             :             }
     942             : 
     943             :         }
     944             : 
     945           0 :         pWindow = pNext;
     946             :     }
     947           0 : }
     948             : 
     949             : } /* namespace vcl */
     950             : 
     951             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11