LCOV - code coverage report
Current view: top level - vcl/source/window - paint.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 535 719 74.4 %
Date: 2014-11-03 Functions: 42 49 85.7 %
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 <config_features.h>
      21             : 
      22             : #include <vcl/window.hxx>
      23             : #include <vcl/dialog.hxx>
      24             : #include <vcl/virdev.hxx>
      25             : #include <vcl/cursor.hxx>
      26             : #include <vcl/settings.hxx>
      27             : 
      28             : #include <sal/types.h>
      29             : 
      30             : #include <window.h>
      31             : #include <salgdi.hxx>
      32             : #include <salframe.hxx>
      33             : #include <svdata.hxx>
      34             : 
      35             : #define IMPL_PAINT_PAINT            ((sal_uInt16)0x0001)
      36             : #define IMPL_PAINT_PAINTALL         ((sal_uInt16)0x0002)
      37             : #define IMPL_PAINT_PAINTALLCHILDREN   ((sal_uInt16)0x0004)
      38             : #define IMPL_PAINT_PAINTCHILDREN      ((sal_uInt16)0x0008)
      39             : #define IMPL_PAINT_ERASE            ((sal_uInt16)0x0010)
      40             : #define IMPL_PAINT_CHECKRTL         ((sal_uInt16)0x0020)
      41             : 
      42             : 
      43             : class PaintHelper
      44             : {
      45             : private:
      46             :     vcl::Window* m_pWindow;
      47             :     vcl::Region* m_pChildRegion;
      48             :     Rectangle m_aSelectionRect;
      49             :     Rectangle m_aPaintRect;
      50             :     vcl::Region m_aPaintRegion;
      51             :     sal_uInt16 m_nPaintFlags;
      52             :     bool m_bPop;
      53             :     bool m_bRestoreCursor;
      54             : public:
      55             :     PaintHelper(vcl::Window *pWindow, sal_uInt16 nPaintFlags);
      56      389425 :     void SetPop()
      57             :     {
      58      389425 :         m_bPop = true;
      59      389425 :     }
      60      389425 :     void SetPaintRect(const Rectangle& rRect)
      61             :     {
      62      389425 :         m_aPaintRect = rRect;
      63      389425 :     }
      64           0 :     void SetSelectionRect(const Rectangle& rRect)
      65             :     {
      66           0 :         m_aSelectionRect = rRect;
      67           0 :     }
      68       36916 :     void SetRestoreCursor(bool bRestoreCursor)
      69             :     {
      70       36916 :         m_bRestoreCursor = bRestoreCursor;
      71       36916 :     }
      72       37250 :     bool GetRestoreCursor() const
      73             :     {
      74       37250 :         return m_bRestoreCursor;
      75             :     }
      76      389425 :     sal_uInt16 GetPaintFlags() const
      77             :     {
      78      389425 :         return m_nPaintFlags;
      79             :     }
      80      389425 :     vcl::Region& GetPaintRegion()
      81             :     {
      82      389425 :         return m_aPaintRegion;
      83             :     }
      84             :     void DoPaint(const vcl::Region* pRegion);
      85             :     ~PaintHelper();
      86             : };
      87             : 
      88     1058297 : PaintHelper::PaintHelper(vcl::Window *pWindow, sal_uInt16 nPaintFlags)
      89             :     : m_pWindow(pWindow)
      90             :     , m_pChildRegion(NULL)
      91             :     , m_nPaintFlags(nPaintFlags)
      92             :     , m_bPop(false)
      93     1058297 :     , m_bRestoreCursor(false)
      94             : {
      95     1058297 : }
      96             : 
      97      544685 : void PaintHelper::DoPaint(const vcl::Region* pRegion)
      98             : {
      99      544685 :     WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
     100      544685 :     vcl::Region* pWinChildClipRegion = m_pWindow->ImplGetWinChildClipRegion();
     101      544685 :     if ( pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     102      378161 :         pWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
     103             :     else
     104             :     {
     105      166524 :         if ( pRegion )
     106      138006 :             pWindowImpl->maInvalidateRegion.Union( *pRegion );
     107             : 
     108      166524 :         if( pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible )
     109             :             /* #98602# need to repaint all children within the
     110             :            * tracking rectangle, so the following invert
     111             :            * operation takes places without traces of the previous
     112             :            * one.
     113             :            */
     114           0 :             pWindowImpl->maInvalidateRegion.Union( *pWindowImpl->mpWinData->mpTrackRect );
     115             : 
     116      166524 :         if ( pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
     117       83992 :             m_pChildRegion = new vcl::Region( pWindowImpl->maInvalidateRegion );
     118      166524 :         pWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion );
     119             :     }
     120      544685 :     pWindowImpl->mnPaintFlags = 0;
     121      544685 :     if ( !pWindowImpl->maInvalidateRegion.IsEmpty() )
     122             :     {
     123      389425 :         m_pWindow->PushPaintHelper(this);
     124      389425 :         m_pWindow->Paint(m_aPaintRect);
     125             :     }
     126      544685 : }
     127             : 
     128             : namespace vcl {
     129             : 
     130      389425 : void Window::PushPaintHelper(PaintHelper *pHelper)
     131             : {
     132      389425 :     pHelper->SetPop();
     133             : 
     134      389425 :     if ( mpWindowImpl->mpCursor )
     135       36916 :         pHelper->SetRestoreCursor(mpWindowImpl->mpCursor->ImplSuspend());
     136             : 
     137      389425 :     mbInitClipRegion = true;
     138      389425 :     mpWindowImpl->mbInPaint = true;
     139             : 
     140             :     // restore Paint-Region
     141      389425 :     vcl::Region &rPaintRegion = pHelper->GetPaintRegion();
     142      389425 :     rPaintRegion = mpWindowImpl->maInvalidateRegion;
     143      389425 :     Rectangle   aPaintRect = rPaintRegion.GetBoundRect();
     144             : 
     145             :     // - RTL - re-mirror paint rect and region at this window
     146      389425 :     if( ImplIsAntiparallel() )
     147             :     {
     148          28 :         const OutputDevice *pOutDev = GetOutDev();
     149          28 :         pOutDev->ReMirror( aPaintRect );
     150          28 :         pOutDev->ReMirror( rPaintRegion );
     151             :     }
     152      389425 :     aPaintRect = ImplDevicePixelToLogic( aPaintRect);
     153      389425 :     mpWindowImpl->mpPaintRegion = &rPaintRegion;
     154      389425 :     mpWindowImpl->maInvalidateRegion.SetEmpty();
     155             : 
     156      389425 :     if ( (pHelper->GetPaintFlags() & IMPL_PAINT_ERASE) && IsBackground() )
     157             :     {
     158      222519 :         if ( IsClipRegion() )
     159             :         {
     160           0 :             vcl::Region aOldRegion = GetClipRegion();
     161           0 :             SetClipRegion();
     162           0 :             Erase();
     163           0 :             SetClipRegion( aOldRegion );
     164             :         }
     165             :         else
     166      222519 :             Erase();
     167             :     }
     168             : 
     169             :     // #98943# trigger drawing of toolbox selection after all childern are painted
     170      389425 :     if( mpWindowImpl->mbDrawSelectionBackground )
     171           0 :         pHelper->SetSelectionRect(aPaintRect);
     172      389425 :     pHelper->SetPaintRect(aPaintRect);
     173      389425 : }
     174             : 
     175      389425 : void Window::PopPaintHelper(PaintHelper *pHelper)
     176             : {
     177      389425 :     if ( mpWindowImpl->mpWinData )
     178             :     {
     179      209718 :         if ( mpWindowImpl->mbFocusVisible )
     180         249 :             ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
     181             :     }
     182      389425 :     mpWindowImpl->mbInPaint = false;
     183      389425 :     mbInitClipRegion = true;
     184      389425 :     mpWindowImpl->mpPaintRegion = NULL;
     185      389425 :     if ( mpWindowImpl->mpCursor )
     186       37250 :         mpWindowImpl->mpCursor->ImplResume(pHelper->GetRestoreCursor());
     187      389425 : }
     188             : 
     189             : } /* namespace vcl */
     190             : 
     191     2116594 : PaintHelper::~PaintHelper()
     192             : {
     193     1058297 :     WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
     194     1058297 :     if (m_bPop)
     195             :     {
     196      389425 :         m_pWindow->PopPaintHelper(this);
     197             :     }
     198             : 
     199     1058297 :     if ( m_nPaintFlags & (IMPL_PAINT_PAINTALLCHILDREN | IMPL_PAINT_PAINTCHILDREN) )
     200             :     {
     201             :         // Paint from the bottom child window and frontward.
     202     1046250 :         vcl::Window* pTempWindow = pWindowImpl->mpLastChild;
     203     3530657 :         while ( pTempWindow )
     204             :         {
     205     1438157 :             if ( pTempWindow->mpWindowImpl->mbVisible )
     206     1036371 :                 pTempWindow->ImplCallPaint( m_pChildRegion, m_nPaintFlags );
     207     1438157 :             pTempWindow = pTempWindow->mpWindowImpl->mpPrev;
     208             :         }
     209             :     }
     210             : 
     211     1058297 :     if ( pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible && (pWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
     212             :         /* #98602# need to invert the tracking rect AFTER
     213             :         * the children have painted
     214             :         */
     215           0 :         m_pWindow->InvertTracking( *(pWindowImpl->mpWinData->mpTrackRect), pWindowImpl->mpWinData->mnTrackFlags );
     216             : 
     217             :     // #98943# draw toolbox selection
     218     1058297 :     if( !m_aSelectionRect.IsEmpty() )
     219           0 :         m_pWindow->DrawSelectionBackground( m_aSelectionRect, 3, false, true, false );
     220             : 
     221     1058297 :     delete m_pChildRegion;
     222     1058297 : }
     223             : 
     224             : namespace vcl {
     225             : 
     226     1090153 : void Window::ImplCallPaint( const vcl::Region* pRegion, sal_uInt16 nPaintFlags )
     227             : {
     228             :     // call PrePaint. PrePaint may add to the invalidate region as well as
     229             :     // other parameters used below.
     230     1090153 :     PrePaint();
     231             : 
     232     1090153 :     mpWindowImpl->mbPaintFrame = false;
     233             : 
     234     1090153 :     if ( nPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
     235      542577 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDREN | (nPaintFlags & IMPL_PAINT_PAINTALL);
     236     1090153 :     if ( nPaintFlags & IMPL_PAINT_PAINTCHILDREN )
     237     1069229 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDREN;
     238     1090153 :     if ( nPaintFlags & IMPL_PAINT_ERASE )
     239      559745 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
     240     1090153 :     if ( nPaintFlags & IMPL_PAINT_CHECKRTL )
     241      112598 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
     242     1090153 :     if ( !mpWindowImpl->mpFirstChild )
     243      587773 :         mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDREN;
     244             : 
     245     1090153 :     if ( mpWindowImpl->mbPaintDisabled )
     246             :     {
     247       31856 :         if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     248       31796 :             Invalidate( INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
     249          60 :         else if ( pRegion )
     250          28 :             Invalidate( *pRegion, INVALIDATE_NOCHILDREN | INVALIDATE_NOERASE | INVALIDATE_NOTRANSPARENT | INVALIDATE_NOCLIPCHILDREN );
     251     1122009 :         return;
     252             :     }
     253             : 
     254     1058297 :     nPaintFlags = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT);
     255             : 
     256     1058297 :     PaintHelper aHelper(this, nPaintFlags);
     257             : 
     258     1058297 :     if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
     259      544685 :         aHelper.DoPaint(pRegion);
     260             :     else
     261      513612 :         mpWindowImpl->mnPaintFlags = 0;
     262             : }
     263             : 
     264       10384 : void Window::ImplCallOverlapPaint()
     265             : {
     266             :     // emit overlapping windows first
     267       10384 :     vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
     268       20768 :     while ( pTempWindow )
     269             :     {
     270           0 :         if ( pTempWindow->mpWindowImpl->mbReallyVisible )
     271           0 :             pTempWindow->ImplCallOverlapPaint();
     272           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
     273             :     }
     274             : 
     275             :     // only then ourself
     276       10384 :     if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
     277             :     {
     278             :         // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
     279             :         //         because we were called from the Sal layer
     280        9133 :         ImplCallPaint( NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
     281             :     }
     282       10384 : }
     283             : 
     284      794680 : void Window::ImplPostPaint()
     285             : {
     286      794680 :     if ( !ImplDoTiledRendering() && !mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
     287       15948 :         mpWindowImpl->mpFrameData->maPaintTimer.Start();
     288      794680 : }
     289             : 
     290       20824 : IMPL_LINK_NOARG(Window, ImplHandlePaintHdl)
     291             : {
     292             :     // save paint events until layout is done
     293       10412 :     if (!ImplDoTiledRendering() && IsSystemWindow() && static_cast<const SystemWindow*>(this)->hasPendingLayout())
     294             :     {
     295           0 :         mpWindowImpl->mpFrameData->maPaintTimer.Start();
     296           0 :         return 0;
     297             :     }
     298             : 
     299             :     // save paint events until resizing is done
     300       31236 :     if( !ImplDoTiledRendering() &&
     301       20824 :         mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeTimer.IsActive() )
     302           0 :         mpWindowImpl->mpFrameData->maPaintTimer.Start();
     303       10412 :     else if ( mpWindowImpl->mbReallyVisible )
     304       10384 :         ImplCallOverlapPaint();
     305       10412 :     return 0;
     306             : }
     307             : 
     308       11032 : IMPL_LINK_NOARG(Window, ImplHandleResizeTimerHdl)
     309             : {
     310        5516 :     if( mpWindowImpl->mbReallyVisible )
     311             :     {
     312         114 :         ImplCallResize();
     313         114 :         if( ImplDoTiledRendering() )
     314             :         {
     315           0 :             ImplHandlePaintHdl(NULL);
     316             :         }
     317         114 :         else if( mpWindowImpl->mpFrameData->maPaintTimer.IsActive() )
     318             :         {
     319         114 :             mpWindowImpl->mpFrameData->maPaintTimer.Stop();
     320         114 :             mpWindowImpl->mpFrameData->maPaintTimer.GetTimeoutHdl().Call( NULL );
     321             :         }
     322             :     }
     323             : 
     324        5516 :     return 0;
     325             : }
     326             : 
     327      794680 : void Window::ImplInvalidateFrameRegion( const vcl::Region* pRegion, sal_uInt16 nFlags )
     328             : {
     329             :     // set PAINTCHILDREN for all parent windows till the first OverlapWindow
     330      794680 :     if ( !ImplIsOverlapWindow() )
     331             :     {
     332      784012 :         vcl::Window* pTempWindow = this;
     333      784012 :         sal_uInt16 nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0;
     334      234274 :         do
     335             :         {
     336     1003127 :             pTempWindow = pTempWindow->ImplGetParent();
     337     1003127 :             if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDREN )
     338      768853 :                 break;
     339      234274 :             pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDREN | nTranspPaint;
     340      234274 :             if( ! pTempWindow->IsPaintTransparent() )
     341      226662 :                 nTranspPaint = 0;
     342             :         }
     343      234274 :         while ( !pTempWindow->ImplIsOverlapWindow() );
     344             :     }
     345             : 
     346             :     // set Paint-Flags
     347      794680 :     mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT;
     348      794680 :     if ( nFlags & INVALIDATE_CHILDREN )
     349      682807 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDREN;
     350      794680 :     if ( !(nFlags & INVALIDATE_NOERASE) )
     351      738965 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
     352      794680 :     if ( !pRegion )
     353      392560 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL;
     354             : 
     355             :     // if not everything has to be redrawn, add the region to it
     356      794680 :     if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) )
     357      306029 :         mpWindowImpl->maInvalidateRegion.Union( *pRegion );
     358             : 
     359             :     // Handle transparent windows correctly: invalidate must be done on the first opaque parent
     360     1623515 :     if( ((IsPaintTransparent() && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
     361      828777 :             && ImplGetParent() )
     362             :     {
     363       34083 :         vcl::Window *pParent = ImplGetParent();
     364      101256 :         while( pParent && pParent->IsPaintTransparent() )
     365       33090 :             pParent = pParent->ImplGetParent();
     366       34083 :         if( pParent )
     367             :         {
     368             :             vcl::Region *pChildRegion;
     369       34083 :             if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     370             :                 // invalidate the whole child window region in the parent
     371       14442 :                 pChildRegion = ImplGetWinChildClipRegion();
     372             :             else
     373             :                 // invalidate the same region in the parent that has to be repainted in the child
     374       19641 :                 pChildRegion = &mpWindowImpl->maInvalidateRegion;
     375             : 
     376       34083 :             nFlags |= INVALIDATE_CHILDREN;  // paint should also be done on all children
     377       34083 :             nFlags &= ~INVALIDATE_NOERASE;  // parent should paint and erase to create proper background
     378       34083 :             pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
     379             :         }
     380             :     }
     381      794680 :     ImplPostPaint();
     382      794680 : }
     383             : 
     384       13305 : void Window::ImplInvalidateOverlapFrameRegion( const vcl::Region& rRegion )
     385             : {
     386       13305 :     vcl::Region aRegion = rRegion;
     387             : 
     388       13305 :     ImplClipBoundaries( aRegion, true, true );
     389       13305 :     if ( !aRegion.IsEmpty() )
     390        5710 :         ImplInvalidateFrameRegion( &aRegion, INVALIDATE_CHILDREN );
     391             : 
     392             :     // now we invalidate the overlapping windows
     393       13305 :     vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
     394       26610 :     while ( pTempWindow )
     395             :     {
     396           0 :         if ( pTempWindow->IsVisible() )
     397           0 :             pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
     398             : 
     399           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
     400       13305 :     }
     401       13305 : }
     402             : 
     403      215264 : void Window::ImplInvalidateParentFrameRegion( vcl::Region& rRegion )
     404             : {
     405      215264 :     if ( mpWindowImpl->mbOverlapWin )
     406           0 :         mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
     407             :     else
     408             :     {
     409      215264 :         if( ImplGetParent() )
     410      215264 :             ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, INVALIDATE_CHILDREN );
     411             :     }
     412      215264 : }
     413             : 
     414      368869 : void Window::ImplInvalidate( const vcl::Region* pRegion, sal_uInt16 nFlags )
     415             : {
     416             : 
     417             :     // reset background storage
     418      368869 :     if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
     419           0 :         ImplInvalidateAllOverlapBackgrounds();
     420             : 
     421             :     // check what has to be redrawn
     422      368869 :     bool bInvalidateAll = !pRegion;
     423             : 
     424             :     // take Transparent-Invalidate into account
     425      368869 :     vcl::Window* pOpaqueWindow = this;
     426      368869 :     if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & INVALIDATE_NOTRANSPARENT)) || (nFlags & INVALIDATE_TRANSPARENT) )
     427             :     {
     428       18871 :         vcl::Window* pTempWindow = pOpaqueWindow->ImplGetParent();
     429       42762 :         while ( pTempWindow )
     430             :         {
     431       23891 :             if ( !pTempWindow->IsPaintTransparent() )
     432             :             {
     433       18871 :                 pOpaqueWindow = pTempWindow;
     434       18871 :                 nFlags |= INVALIDATE_CHILDREN;
     435       18871 :                 bInvalidateAll = false;
     436       18871 :                 break;
     437             :             }
     438             : 
     439        5020 :             if ( pTempWindow->ImplIsOverlapWindow() )
     440           0 :                 break;
     441             : 
     442        5020 :             pTempWindow = pTempWindow->ImplGetParent();
     443             :         }
     444             :     }
     445             : 
     446             :     // assemble region
     447      368869 :     sal_uInt16 nOrgFlags = nFlags;
     448      368869 :     if ( !(nFlags & (INVALIDATE_CHILDREN | INVALIDATE_NOCHILDREN)) )
     449             :     {
     450      225284 :         if ( GetStyle() & WB_CLIPCHILDREN )
     451       90742 :             nFlags |= INVALIDATE_NOCHILDREN;
     452             :         else
     453      134542 :             nFlags |= INVALIDATE_CHILDREN;
     454             :     }
     455      368869 :     if ( (nFlags & INVALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
     456       48865 :         bInvalidateAll = false;
     457      368869 :     if ( bInvalidateAll )
     458      224402 :         ImplInvalidateFrameRegion( NULL, nFlags );
     459             :     else
     460             :     {
     461      144467 :         Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     462      144467 :         vcl::Region      aRegion( aRect );
     463      144467 :         if ( pRegion )
     464             :         {
     465             :             // --- RTL --- remirror region before intersecting it
     466      102926 :             if ( ImplIsAntiparallel() )
     467             :             {
     468           0 :                 const OutputDevice *pOutDev = GetOutDev();
     469             : 
     470           0 :                 vcl::Region aRgn( *pRegion );
     471           0 :                 pOutDev->ReMirror( aRgn );
     472           0 :                 aRegion.Intersect( aRgn );
     473             :             }
     474             :             else
     475      102926 :                 aRegion.Intersect( *pRegion );
     476             :         }
     477      144467 :         ImplClipBoundaries( aRegion, true, true );
     478      144467 :         if ( nFlags & INVALIDATE_NOCHILDREN )
     479             :         {
     480       85806 :             nFlags &= ~INVALIDATE_CHILDREN;
     481       85806 :             if ( !(nFlags & INVALIDATE_NOCLIPCHILDREN) )
     482             :             {
     483       85154 :                 if ( nOrgFlags & INVALIDATE_NOCHILDREN )
     484        4888 :                     ImplClipAllChildren( aRegion );
     485             :                 else
     486             :                 {
     487       80266 :                     if ( ImplClipChildren( aRegion ) )
     488         804 :                         nFlags |= INVALIDATE_CHILDREN;
     489             :                 }
     490             :             }
     491             :         }
     492      144467 :         if ( !aRegion.IsEmpty() )
     493      122718 :             ImplInvalidateFrameRegion( &aRegion, nFlags );  // transparency is handled here, pOpaqueWindow not required
     494             :     }
     495             : 
     496      368869 :     if ( nFlags & INVALIDATE_UPDATE )
     497           0 :         pOpaqueWindow->Update();        // start painting at the opaque parent
     498      368869 : }
     499             : 
     500        1762 : void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
     501             :                                        long nHorzScroll, long nVertScroll,
     502             :                                        bool bChildren )
     503             : {
     504        1762 :     if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
     505             :     {
     506          24 :         vcl::Region aTempRegion = mpWindowImpl->maInvalidateRegion;
     507          24 :         aTempRegion.Intersect( rRect );
     508          24 :         aTempRegion.Move( nHorzScroll, nVertScroll );
     509          24 :         mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
     510             :     }
     511             : 
     512        1762 :     if ( bChildren && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDREN) )
     513             :     {
     514          33 :         vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     515          99 :         while ( pWindow )
     516             :         {
     517          33 :             pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, true );
     518          33 :             pWindow = pWindow->mpWindowImpl->mpNext;
     519             :         }
     520             :     }
     521        1762 : }
     522             : 
     523        1729 : void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect,
     524             :                                            long nHorzScroll, long nVertScroll,
     525             :                                            bool bChildren )
     526             : {
     527             :     // also shift Paint-Region when paints need processing
     528        1729 :     ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChildren );
     529             :     // Paint-Region should be shifted, as drawn by the parents
     530        1729 :     if ( !ImplIsOverlapWindow() )
     531             :     {
     532        1729 :         vcl::Region  aPaintAllRegion;
     533        1729 :         vcl::Window* pPaintAllWindow = this;
     534        8426 :         do
     535             :         {
     536        8426 :             pPaintAllWindow = pPaintAllWindow->ImplGetParent();
     537        8426 :             if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
     538             :             {
     539           2 :                 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     540             :                 {
     541           0 :                     aPaintAllRegion.SetEmpty();
     542           0 :                     break;
     543             :                 }
     544             :                 else
     545           2 :                     aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
     546             :             }
     547             :         }
     548        8426 :         while ( !pPaintAllWindow->ImplIsOverlapWindow() );
     549        1729 :         if ( !aPaintAllRegion.IsEmpty() )
     550             :         {
     551           2 :             aPaintAllRegion.Move( nHorzScroll, nVertScroll );
     552           2 :             sal_uInt16 nPaintFlags = 0;
     553           2 :             if ( bChildren )
     554           0 :                 mpWindowImpl->mnPaintFlags |= INVALIDATE_CHILDREN;
     555           2 :             ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
     556        1729 :         }
     557             :     }
     558        1729 : }
     559             : 
     560           6 : void Window::ImplValidateFrameRegion( const vcl::Region* pRegion, sal_uInt16 nFlags )
     561             : {
     562           6 :     if ( !pRegion )
     563           6 :         mpWindowImpl->maInvalidateRegion.SetEmpty();
     564             :     else
     565             :     {
     566             :         // when all child windows have to be drawn we need to invalidate them before doing so
     567           0 :         if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN) && mpWindowImpl->mpFirstChild )
     568             :         {
     569           0 :             vcl::Region aChildRegion = mpWindowImpl->maInvalidateRegion;
     570           0 :             if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     571             :             {
     572           0 :                 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     573           0 :                 aChildRegion = aRect;
     574             :             }
     575           0 :             vcl::Window* pChild = mpWindowImpl->mpFirstChild;
     576           0 :             while ( pChild )
     577             :             {
     578           0 :                 pChild->Invalidate( aChildRegion, INVALIDATE_CHILDREN | INVALIDATE_NOTRANSPARENT );
     579           0 :                 pChild = pChild->mpWindowImpl->mpNext;
     580           0 :             }
     581             :         }
     582           0 :         if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     583             :         {
     584           0 :             Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     585           0 :             mpWindowImpl->maInvalidateRegion = aRect;
     586             :         }
     587           0 :         mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
     588             :     }
     589           6 :     mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
     590             : 
     591           6 :     if ( nFlags & VALIDATE_CHILDREN )
     592             :     {
     593           0 :         vcl::Window* pChild = mpWindowImpl->mpFirstChild;
     594           0 :         while ( pChild )
     595             :         {
     596           0 :             pChild->ImplValidateFrameRegion( pRegion, nFlags );
     597           0 :             pChild = pChild->mpWindowImpl->mpNext;
     598             :         }
     599             :     }
     600           6 : }
     601             : 
     602           6 : void Window::ImplValidate( const vcl::Region* pRegion, sal_uInt16 nFlags )
     603             : {
     604             :     // assemble region
     605           6 :     bool    bValidateAll = !pRegion;
     606           6 :     sal_uInt16  nOrgFlags = nFlags;
     607           6 :     if ( !(nFlags & (VALIDATE_CHILDREN | VALIDATE_NOCHILDREN)) )
     608             :     {
     609           6 :         if ( GetStyle() & WB_CLIPCHILDREN )
     610           6 :             nFlags |= VALIDATE_NOCHILDREN;
     611             :         else
     612           0 :             nFlags |= VALIDATE_CHILDREN;
     613             :     }
     614           6 :     if ( (nFlags & VALIDATE_NOCHILDREN) && mpWindowImpl->mpFirstChild )
     615           0 :         bValidateAll = false;
     616           6 :     if ( bValidateAll )
     617           6 :         ImplValidateFrameRegion( NULL, nFlags );
     618             :     else
     619             :     {
     620           0 :         Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     621           0 :         vcl::Region      aRegion( aRect );
     622           0 :         if ( pRegion )
     623           0 :             aRegion.Intersect( *pRegion );
     624           0 :         ImplClipBoundaries( aRegion, true, true );
     625           0 :         if ( nFlags & VALIDATE_NOCHILDREN )
     626             :         {
     627           0 :             nFlags &= ~VALIDATE_CHILDREN;
     628           0 :             if ( nOrgFlags & VALIDATE_NOCHILDREN )
     629           0 :                 ImplClipAllChildren( aRegion );
     630             :             else
     631             :             {
     632           0 :                 if ( ImplClipChildren( aRegion ) )
     633           0 :                     nFlags |= VALIDATE_CHILDREN;
     634             :             }
     635             :         }
     636           0 :         if ( !aRegion.IsEmpty() )
     637           0 :             ImplValidateFrameRegion( &aRegion, nFlags );
     638             :     }
     639           6 : }
     640             : 
     641           0 : void Window::ImplUpdateAll( bool bOverlapWindows )
     642             : {
     643           0 :     if ( !mpWindowImpl->mbReallyVisible )
     644           0 :         return;
     645             : 
     646           0 :     bool bFlush = false;
     647           0 :     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
     648             :     {
     649           0 :         Point aPoint( 0, 0 );
     650           0 :         vcl::Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
     651           0 :         ImplInvalidateOverlapFrameRegion( aRegion );
     652           0 :         if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
     653           0 :             bFlush = true;
     654             :     }
     655             : 
     656             :     // an update changes the OverlapWindow, such that for later paints
     657             :     // not too much has to be drawn, if ALLCHILDREN etc. is set
     658           0 :     vcl::Window* pWindow = ImplGetFirstOverlapWindow();
     659           0 :     if ( bOverlapWindows )
     660           0 :         pWindow->ImplCallOverlapPaint();
     661             :     else
     662             :     {
     663           0 :         if ( pWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
     664           0 :             pWindow->ImplCallPaint( NULL, pWindow->mpWindowImpl->mnPaintFlags );
     665             :     }
     666             : 
     667           0 :     if ( bFlush )
     668           0 :         Flush();
     669             : }
     670             : 
     671     1045937 : void Window::PrePaint()
     672             : {
     673     1045937 : }
     674             : 
     675       86815 : void Window::Paint( const Rectangle& rRect )
     676             : {
     677       86815 :     ImplCallEventListeners( VCLEVENT_WINDOW_PAINT, (void*)&rRect );
     678       86815 : }
     679             : 
     680           0 : void Window::PostPaint()
     681             : {
     682           0 : }
     683             : 
     684      150244 : void Window::SetPaintTransparent( bool bTransparent )
     685             : {
     686             : 
     687             :     // transparency is not useful for frames as the background would have to be provided by a different frame
     688      150244 :     if( bTransparent && mpWindowImpl->mbFrame )
     689      150244 :         return;
     690             : 
     691      150244 :     if ( mpWindowImpl->mpBorderWindow )
     692         126 :         mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
     693             : 
     694      150244 :     mpWindowImpl->mbPaintTransparent = bTransparent;
     695             : }
     696             : 
     697           0 : void Window::SetWindowRegionPixel()
     698             : {
     699             : 
     700           0 :     if ( mpWindowImpl->mpBorderWindow )
     701           0 :         mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
     702           0 :     else if( mpWindowImpl->mbFrame )
     703             :     {
     704           0 :         mpWindowImpl->maWinRegion = vcl::Region(true);
     705           0 :         mpWindowImpl->mbWinRegion = false;
     706           0 :         mpWindowImpl->mpFrame->ResetClipRegion();
     707             :     }
     708             :     else
     709             :     {
     710           0 :         if ( mpWindowImpl->mbWinRegion )
     711             :         {
     712           0 :             mpWindowImpl->maWinRegion = vcl::Region(true);
     713           0 :             mpWindowImpl->mbWinRegion = false;
     714           0 :             ImplSetClipFlag();
     715             : 
     716           0 :             if ( IsReallyVisible() )
     717             :             {
     718             :                 // restore background storage
     719           0 :                 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
     720           0 :                     ImplDeleteOverlapBackground();
     721           0 :                 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
     722           0 :                     ImplInvalidateAllOverlapBackgrounds();
     723           0 :                 Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     724           0 :                 vcl::Region      aRegion( aRect );
     725           0 :                 ImplInvalidateParentFrameRegion( aRegion );
     726             :             }
     727             :         }
     728             :     }
     729           0 : }
     730             : 
     731           0 : void Window::SetWindowRegionPixel( const vcl::Region& rRegion )
     732             : {
     733             : 
     734           0 :     if ( mpWindowImpl->mpBorderWindow )
     735           0 :         mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
     736           0 :     else if( mpWindowImpl->mbFrame )
     737             :     {
     738           0 :         if( !rRegion.IsNull() )
     739             :         {
     740           0 :             mpWindowImpl->maWinRegion = rRegion;
     741           0 :             mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
     742             : 
     743           0 :             if( mpWindowImpl->mbWinRegion )
     744             :             {
     745             :                 // set/update ClipRegion
     746           0 :                 RectangleVector aRectangles;
     747           0 :                 mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
     748           0 :                 mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
     749             : 
     750           0 :                 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     751             :                 {
     752             :                     mpWindowImpl->mpFrame->UnionClipRegion(
     753             :                         aRectIter->Left(),
     754             :                         aRectIter->Top(),
     755             :                         aRectIter->GetWidth(),       // orig nWidth was ((R - L) + 1), same as GetWidth does
     756           0 :                         aRectIter->GetHeight());     // same for height
     757             :                 }
     758             : 
     759           0 :                 mpWindowImpl->mpFrame->EndSetClipRegion();
     760             : 
     761             :                 //long                nX;
     762             :                 //long                nY;
     763             :                 //long                nWidth;
     764             :                 //long                nHeight;
     765             :                 //sal_uLong               nRectCount;
     766             :                 //ImplRegionInfo      aInfo;
     767             :                 //sal_Bool                bRegionRect;
     768             : 
     769             :                 //nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
     770             :                 //mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
     771             :                 //bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
     772             :                 //while ( bRegionRect )
     773             :                 //{
     774             :                 //    mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
     775             :                 //    bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
     776             :                 //}
     777             :                 //mpWindowImpl->mpFrame->EndSetClipRegion();
     778             :             }
     779             :             else
     780           0 :                 SetWindowRegionPixel();
     781             :         }
     782             :         else
     783           0 :             SetWindowRegionPixel();
     784             :     }
     785             :     else
     786             :     {
     787           0 :         if ( rRegion.IsNull() )
     788             :         {
     789           0 :             if ( mpWindowImpl->mbWinRegion )
     790             :             {
     791           0 :                 mpWindowImpl->maWinRegion = vcl::Region(true);
     792           0 :                 mpWindowImpl->mbWinRegion = false;
     793           0 :                 ImplSetClipFlag();
     794             :             }
     795             :         }
     796             :         else
     797             :         {
     798           0 :             mpWindowImpl->maWinRegion = rRegion;
     799           0 :             mpWindowImpl->mbWinRegion = true;
     800           0 :             ImplSetClipFlag();
     801             :         }
     802             : 
     803           0 :         if ( IsReallyVisible() )
     804             :         {
     805             :             // restore background storage
     806           0 :             if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
     807           0 :                 ImplDeleteOverlapBackground();
     808           0 :             if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
     809           0 :                 ImplInvalidateAllOverlapBackgrounds();
     810           0 :             Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     811           0 :             vcl::Region      aRegion( aRect );
     812           0 :             ImplInvalidateParentFrameRegion( aRegion );
     813             :         }
     814             :     }
     815           0 : }
     816             : 
     817           0 : const vcl::Region& Window::GetWindowRegionPixel() const
     818             : {
     819             : 
     820           0 :     if ( mpWindowImpl->mpBorderWindow )
     821           0 :         return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel();
     822             :     else
     823           0 :         return mpWindowImpl->maWinRegion;
     824             : }
     825             : 
     826           0 : bool Window::IsWindowRegionPixel() const
     827             : {
     828             : 
     829           0 :     if ( mpWindowImpl->mpBorderWindow )
     830           0 :         return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel();
     831             :     else
     832           0 :         return mpWindowImpl->mbWinRegion;
     833             : }
     834             : 
     835      199443 : vcl::Region Window::GetPaintRegion() const
     836             : {
     837             : 
     838      199443 :     if ( mpWindowImpl->mpPaintRegion )
     839             :     {
     840      199439 :         vcl::Region aRegion = *mpWindowImpl->mpPaintRegion;
     841      199439 :         aRegion.Move( -mnOutOffX, -mnOutOffY );
     842      199439 :         return PixelToLogic( aRegion );
     843             :     }
     844             :     else
     845             :     {
     846           4 :         vcl::Region aPaintRegion(true);
     847           4 :         return aPaintRegion;
     848             :     }
     849             : }
     850             : 
     851      617116 : void Window::Invalidate( sal_uInt16 nFlags )
     852             : {
     853             : 
     854      617116 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
     855     1047383 :         return;
     856             : 
     857      186849 :     ImplInvalidate( NULL, nFlags );
     858             : }
     859             : 
     860      158239 : void Window::Invalidate( const Rectangle& rRect, sal_uInt16 nFlags )
     861             : {
     862             : 
     863      158239 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
     864      213415 :         return;
     865             : 
     866      103063 :     OutputDevice *pOutDev = GetOutDev();
     867      103063 :     Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
     868      103063 :     if ( !aRect.IsEmpty() )
     869             :     {
     870       98461 :         vcl::Region aRegion( aRect );
     871       98461 :         ImplInvalidate( &aRegion, nFlags );
     872             :     }
     873             : }
     874             : 
     875        5056 : void Window::Invalidate( const vcl::Region& rRegion, sal_uInt16 nFlags )
     876             : {
     877             : 
     878        5056 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
     879        5056 :         return;
     880             : 
     881        5056 :     if ( rRegion.IsNull() )
     882           0 :         ImplInvalidate( NULL, nFlags );
     883             :     else
     884             :     {
     885        5056 :         vcl::Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
     886        5056 :         if ( !aRegion.IsEmpty() )
     887        4465 :             ImplInvalidate( &aRegion, nFlags );
     888             :     }
     889             : }
     890             : 
     891           6 : void Window::Validate( sal_uInt16 nFlags )
     892             : {
     893             : 
     894           6 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
     895           6 :         return;
     896             : 
     897           6 :     ImplValidate( NULL, nFlags );
     898             : }
     899             : 
     900      235591 : bool Window::HasPaintEvent() const
     901             : {
     902             : 
     903      235591 :     if ( !mpWindowImpl->mbReallyVisible )
     904       23875 :         return false;
     905             : 
     906      211716 :     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
     907        7120 :         return true;
     908             : 
     909      204596 :     if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
     910       32565 :         return true;
     911             : 
     912      172031 :     if ( !ImplIsOverlapWindow() )
     913             :     {
     914      172031 :         const vcl::Window* pTempWindow = this;
     915     1282003 :         do
     916             :         {
     917     1362709 :             pTempWindow = pTempWindow->ImplGetParent();
     918     1362709 :             if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDREN | IMPL_PAINT_PAINTALLCHILDREN) )
     919       80706 :                 return true;
     920             :         }
     921     1282003 :         while ( !pTempWindow->ImplIsOverlapWindow() );
     922             :     }
     923             : 
     924       91325 :     return false;
     925             : }
     926             : 
     927      133039 : void Window::Update()
     928             : {
     929             : 
     930      133039 :     if ( mpWindowImpl->mpBorderWindow )
     931             :     {
     932         736 :         mpWindowImpl->mpBorderWindow->Update();
     933         736 :         return;
     934             :     }
     935             : 
     936      132303 :     if ( !mpWindowImpl->mbReallyVisible )
     937       25960 :         return;
     938             : 
     939      106343 :     bool bFlush = false;
     940      106343 :     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
     941             :     {
     942        8133 :         Point aPoint( 0, 0 );
     943        8133 :         vcl::Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
     944        8133 :         ImplInvalidateOverlapFrameRegion( aRegion );
     945        8133 :         if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
     946           2 :             bFlush = true;
     947             :     }
     948             : 
     949             :     // First we should skip all windows which are Paint-Transparent
     950      106343 :     vcl::Window* pUpdateWindow = this;
     951      106343 :     vcl::Window* pWindow = pUpdateWindow;
     952      212824 :     while ( !pWindow->ImplIsOverlapWindow() )
     953             :     {
     954      106479 :         if ( !pWindow->mpWindowImpl->mbPaintTransparent )
     955             :         {
     956      106341 :             pUpdateWindow = pWindow;
     957      106341 :             break;
     958             :         }
     959         138 :         pWindow = pWindow->ImplGetParent();
     960             :     }
     961             :     // In order to limit drawing, an update only draws the window which
     962             :     // has PAINTALLCHILDREN set
     963      106343 :     pWindow = pUpdateWindow;
     964      347165 :     do
     965             :     {
     966      453508 :         if ( pWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
     967       79678 :             pUpdateWindow = pWindow;
     968      453508 :         if ( pWindow->ImplIsOverlapWindow() )
     969      106343 :             break;
     970      347165 :         pWindow = pWindow->ImplGetParent();
     971             :     }
     972             :     while ( pWindow );
     973             : 
     974             :     // if there is something to paint, trigger a Paint
     975      106343 :     if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
     976             :     {
     977       44649 :         ImplDelData aDogTag(this);
     978             : 
     979             :         // trigger an update also for system windows on top of us,
     980             :         // otherwise holes would remain
     981       44649 :          vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap;
     982       89298 :          while ( pUpdateOverlapWindow )
     983             :          {
     984           0 :              pUpdateOverlapWindow->Update();
     985           0 :              pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
     986             :          }
     987             : 
     988       44649 :         pUpdateWindow->ImplCallPaint( NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags );
     989             : 
     990       44649 :         if (aDogTag.IsDead())
     991           0 :            return;
     992       44649 :         bFlush = true;
     993             :     }
     994             : 
     995      106343 :     if ( bFlush )
     996       44649 :         Flush();
     997             : }
     998             : 
     999        6631 : void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
    1000             : {
    1001        6631 :     bool bRVisible = mpWindowImpl->mbReallyVisible;
    1002        6631 :     mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
    1003        6631 :     bool bDevOutput = mbDevOutput;
    1004        6631 :     mbDevOutput = true;
    1005             : 
    1006        6631 :     const OutputDevice *pOutDev = GetOutDev();
    1007        6631 :     long nOldDPIX = pOutDev->GetDPIX();
    1008        6631 :     long nOldDPIY = pOutDev->GetDPIY();
    1009        6631 :     mnDPIX = i_pTargetOutDev->GetDPIX();
    1010        6631 :     mnDPIY = i_pTargetOutDev->GetDPIY();
    1011        6631 :     bool bOutput = IsOutputEnabled();
    1012        6631 :     EnableOutput();
    1013             : 
    1014             :     DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
    1015        6631 :     if ( GetMapMode().GetMapUnit() != MAP_PIXEL )
    1016        6631 :         return;
    1017             : 
    1018             :     // preserve graphicsstate
    1019        6631 :     Push();
    1020        6631 :     vcl::Region aClipRegion( GetClipRegion() );
    1021        6631 :     SetClipRegion();
    1022             : 
    1023        6631 :     GDIMetaFile* pOldMtf = GetConnectMetaFile();
    1024       13262 :     GDIMetaFile aMtf;
    1025        6631 :     SetConnectMetaFile( &aMtf );
    1026             : 
    1027             :     // put a push action to metafile
    1028        6631 :     Push();
    1029             :     // copy graphics state to metafile
    1030       13262 :     vcl::Font aCopyFont = GetFont();
    1031        6631 :     if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY )
    1032             :     {
    1033           0 :         aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY );
    1034           0 :         aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX );
    1035             :     }
    1036        6631 :     SetFont( aCopyFont );
    1037        6631 :     SetTextColor( GetTextColor() );
    1038        6631 :     if( IsLineColor() )
    1039        6463 :         SetLineColor( GetLineColor() );
    1040             :     else
    1041         168 :         SetLineColor();
    1042        6631 :     if( IsFillColor() )
    1043        6631 :         SetFillColor( GetFillColor() );
    1044             :     else
    1045           0 :         SetFillColor();
    1046        6631 :     if( IsTextLineColor() )
    1047           0 :         SetTextLineColor( GetTextLineColor() );
    1048             :     else
    1049        6631 :         SetTextLineColor();
    1050        6631 :     if( IsOverlineColor() )
    1051           0 :         SetOverlineColor( GetOverlineColor() );
    1052             :     else
    1053        6631 :         SetOverlineColor();
    1054        6631 :     if( IsTextFillColor() )
    1055          27 :         SetTextFillColor( GetTextFillColor() );
    1056             :     else
    1057        6604 :         SetTextFillColor();
    1058        6631 :     SetTextAlign( GetTextAlign() );
    1059        6631 :     SetRasterOp( GetRasterOp() );
    1060        6631 :     if( IsRefPoint() )
    1061           0 :         SetRefPoint( GetRefPoint() );
    1062             :     else
    1063        6631 :         SetRefPoint();
    1064        6631 :     SetLayoutMode( GetLayoutMode() );
    1065        6631 :     SetDigitLanguage( GetDigitLanguage() );
    1066        6631 :     Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() );
    1067        6631 :     aClipRegion.Intersect( aPaintRect );
    1068        6631 :     SetClipRegion( aClipRegion );
    1069             : 
    1070             :     // do the actual paint
    1071             : 
    1072             :     // background
    1073        6631 :     if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & PARENTCLIPMODE_NOCLIP ) )
    1074        2807 :         Erase();
    1075             :     // foreground
    1076        6631 :     Paint( aPaintRect );
    1077             :     // put a pop action to metafile
    1078        6631 :     Pop();
    1079             : 
    1080        6631 :     SetConnectMetaFile( pOldMtf );
    1081        6631 :     EnableOutput( bOutput );
    1082        6631 :     mpWindowImpl->mbReallyVisible = bRVisible;
    1083             : 
    1084             :     // paint metafile to VDev
    1085        6631 :     VirtualDevice* pMaskedDevice = new VirtualDevice( *i_pTargetOutDev, 0, 0 );
    1086        6631 :     pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
    1087        6631 :     pMaskedDevice->EnableRTL( IsRTLEnabled() );
    1088        6631 :     aMtf.WindStart();
    1089        6631 :     aMtf.Play( pMaskedDevice );
    1090       13262 :     BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) );
    1091        6631 :     i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
    1092             :     // get rid of virtual device now so they don't pile up during recursive calls
    1093        6631 :     delete pMaskedDevice, pMaskedDevice = NULL;
    1094             : 
    1095       11477 :     for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
    1096             :     {
    1097        4846 :         if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
    1098             :         {
    1099        4107 :             long nDeltaX = pChild->mnOutOffX - mnOutOffX;
    1100             : 
    1101        4107 :             if( pOutDev->HasMirroredGraphics() )
    1102           0 :                 nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth;
    1103        4107 :             long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
    1104        4107 :             Point aPos( i_rPos );
    1105        4107 :             Point aDelta( nDeltaX, nDeltaY );
    1106        4107 :             aPos += aDelta;
    1107        4107 :             pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
    1108             :         }
    1109             :     }
    1110             : 
    1111             :     // restore graphics state
    1112        6631 :     Pop();
    1113             : 
    1114        6631 :     EnableOutput( bOutput );
    1115        6631 :     mpWindowImpl->mbReallyVisible = bRVisible;
    1116        6631 :     mbDevOutput = bDevOutput;
    1117        6631 :     mnDPIX = nOldDPIX;
    1118       13262 :     mnDPIY = nOldDPIY;
    1119             : }
    1120             : 
    1121        2524 : void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ )
    1122             : {
    1123             :     // FIXME: scaling: currently this is for pixel copying only
    1124             : 
    1125             :     DBG_ASSERT( ! pDev->HasMirroredGraphics(), "PaintToDevice to mirroring graphics" );
    1126             :     DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" );
    1127             : 
    1128        2524 :     vcl::Window* pRealParent = NULL;
    1129        2524 :     if( ! mpWindowImpl->mbVisible )
    1130             :     {
    1131        2524 :         vcl::Window* pTempParent = ImplGetDefaultWindow();
    1132        2524 :         if( pTempParent )
    1133        2524 :             pTempParent->EnableChildTransparentMode();
    1134        2524 :         pRealParent = GetParent();
    1135        2524 :         SetParent( pTempParent );
    1136             :         // trigger correct visibility flags for children
    1137        2524 :         Show();
    1138        2524 :         Hide();
    1139             :     }
    1140             : 
    1141        2524 :     bool bVisible = mpWindowImpl->mbVisible;
    1142        2524 :     mpWindowImpl->mbVisible = true;
    1143             : 
    1144        2524 :     if( mpWindowImpl->mpBorderWindow )
    1145        1719 :         mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
    1146             :     else
    1147         805 :         ImplPaintToDevice( pDev, rPos );
    1148             : 
    1149        2524 :     mpWindowImpl->mbVisible = bVisible;
    1150             : 
    1151        2524 :     if( pRealParent )
    1152        2524 :         SetParent( pRealParent );
    1153        2524 : }
    1154             : 
    1155      225326 : void Window::Erase()
    1156             : {
    1157      225326 :     if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
    1158      225326 :         return;
    1159             : 
    1160      225326 :     bool bNativeOK = false;
    1161             : 
    1162      225326 :     ControlPart aCtrlPart = ImplGetWindowImpl()->mnNativeBackground;
    1163      225326 :     if( aCtrlPart != 0 && ! IsControlBackground() )
    1164             :     {
    1165           0 :         Rectangle           aCtrlRegion( Point(), GetOutputSizePixel() );
    1166           0 :         ControlState        nState = 0;
    1167             : 
    1168           0 :         if( IsEnabled() )
    1169           0 :             nState |= CTRL_STATE_ENABLED;
    1170             : 
    1171             :         bNativeOK = DrawNativeControl( CTRL_WINDOW_BACKGROUND, aCtrlPart, aCtrlRegion,
    1172           0 :                                        nState, ImplControlValue(), OUString() );
    1173             :     }
    1174             : 
    1175      225326 :     if ( mbBackground && ! bNativeOK )
    1176             :     {
    1177      225326 :         RasterOp eRasterOp = GetRasterOp();
    1178      225326 :         if ( eRasterOp != ROP_OVERPAINT )
    1179           0 :             SetRasterOp( ROP_OVERPAINT );
    1180      225326 :         DrawWallpaper( 0, 0, mnOutWidth, mnOutHeight, maBackground );
    1181      225326 :         if ( eRasterOp != ROP_OVERPAINT )
    1182           0 :             SetRasterOp( eRasterOp );
    1183             :     }
    1184             : 
    1185      225326 :     if( mpAlphaVDev )
    1186           0 :         mpAlphaVDev->Erase();
    1187             : }
    1188             : 
    1189        9298 : void Window::ImplScroll( const Rectangle& rRect,
    1190             :                          long nHorzScroll, long nVertScroll, sal_uInt16 nFlags )
    1191             : {
    1192        9298 :     if ( !IsDeviceOutputNecessary() )
    1193       15320 :         return;
    1194             : 
    1195        1770 :     nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll );
    1196        1770 :     nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll );
    1197             : 
    1198        1770 :     if ( !nHorzScroll && !nVertScroll )
    1199         264 :         return;
    1200             : 
    1201             :     // restore background storage
    1202        1506 :     if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
    1203           0 :         ImplInvalidateAllOverlapBackgrounds();
    1204             : 
    1205        1506 :     if ( mpWindowImpl->mpCursor )
    1206        1292 :         mpWindowImpl->mpCursor->ImplSuspend();
    1207             : 
    1208        1506 :     sal_uInt16 nOrgFlags = nFlags;
    1209        1506 :     if ( !(nFlags & (SCROLL_CHILDREN | SCROLL_NOCHILDREN)) )
    1210             :     {
    1211         104 :         if ( GetStyle() & WB_CLIPCHILDREN )
    1212           2 :             nFlags |= SCROLL_NOCHILDREN;
    1213             :         else
    1214         102 :             nFlags |= SCROLL_CHILDREN;
    1215             :     }
    1216             : 
    1217        1506 :     vcl::Region  aInvalidateRegion;
    1218        1506 :     bool    bScrollChildren = (nFlags & SCROLL_CHILDREN) != 0;
    1219        1506 :     bool    bErase = (nFlags & SCROLL_NOERASE) == 0;
    1220             : 
    1221        1506 :     if ( !mpWindowImpl->mpFirstChild )
    1222        1372 :         bScrollChildren = false;
    1223             : 
    1224        1506 :     OutputDevice *pOutDev = GetOutDev();
    1225             : 
    1226             :     // --- RTL --- check if this window requires special action
    1227        1506 :     bool bReMirror = ( ImplIsAntiparallel() );
    1228             : 
    1229        1506 :     Rectangle aRectMirror( rRect );
    1230        1506 :     if( bReMirror )
    1231             :     {
    1232             :         // --- RTL --- make sure the invalidate region of this window is
    1233             :         // computed in the same coordinate space as the one from the overlap windows
    1234           0 :         pOutDev->ReMirror( aRectMirror );
    1235             :     }
    1236             : 
    1237             :     // adapt paint areas
    1238        1506 :     ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChildren );
    1239             : 
    1240        1506 :     if ( !(nFlags & SCROLL_NOINVALIDATE) )
    1241             :     {
    1242        1506 :         ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChildren, true, false );
    1243             : 
    1244             :         // --- RTL ---
    1245             :         // if the scrolling on the device is performed in the opposite direction
    1246             :         // then move the overlaps in that direction to compute the invalidate region
    1247             :         // on the correct side, i.e., revert nHorzScroll
    1248             : 
    1249        1506 :         if ( !aInvalidateRegion.IsEmpty() )
    1250             :         {
    1251           0 :             aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
    1252           0 :             bErase = true;
    1253             :         }
    1254        1506 :         if ( !(nFlags & SCROLL_NOWINDOWINVALIDATE) )
    1255             :         {
    1256        1506 :             Rectangle aDestRect( aRectMirror );
    1257        1506 :             aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
    1258        1506 :             vcl::Region aWinInvalidateRegion( aRectMirror );
    1259        1506 :             aWinInvalidateRegion.Exclude( aDestRect );
    1260             : 
    1261        1506 :             aInvalidateRegion.Union( aWinInvalidateRegion );
    1262             :         }
    1263             :     }
    1264             : 
    1265        1506 :     Point aPoint( mnOutOffX, mnOutOffY );
    1266        3012 :     vcl::Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
    1267        1506 :     if ( nFlags & SCROLL_CLIP )
    1268           0 :         aRegion.Intersect( rRect );
    1269        1506 :     if ( mpWindowImpl->mbWinRegion )
    1270           0 :         aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
    1271             : 
    1272        1506 :     aRegion.Exclude( aInvalidateRegion );
    1273             : 
    1274        1506 :     ImplClipBoundaries( aRegion, false, true );
    1275        1506 :     if ( !bScrollChildren )
    1276             :     {
    1277        1374 :         if ( nOrgFlags & SCROLL_NOCHILDREN )
    1278           0 :             ImplClipAllChildren( aRegion );
    1279             :         else
    1280        1374 :             ImplClipChildren( aRegion );
    1281             :     }
    1282        1506 :     if ( mbClipRegion && (nFlags & SCROLL_USECLIPREGION) )
    1283           0 :         aRegion.Intersect( maRegion );
    1284        1506 :     if ( !aRegion.IsEmpty() )
    1285             :     {
    1286        1374 :         if ( mpWindowImpl->mpWinData )
    1287             :         {
    1288           0 :             if ( mpWindowImpl->mbFocusVisible )
    1289           0 :                 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
    1290           0 :             if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
    1291           0 :                 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
    1292             :         }
    1293             : #ifndef IOS
    1294             :         // This seems completely unnecessary with tiled rendering, and
    1295             :         // causes the "AquaSalGraphics::copyArea() for non-layered
    1296             :         // graphics" message. Presumably we should bypass this on all
    1297             :         // platforms when dealing with a "window" that uses tiled
    1298             :         // rendering at the moment. Unclear how to figure that out,
    1299             :         // though. Also unclear whether we actually could just not
    1300             :         // create a "frame window", whatever that exactly is, in the
    1301             :         // tiled rendering case, or at least for platforms where tiles
    1302             :         // rendering is all there is.
    1303             : 
    1304        1374 :         SalGraphics* pGraphics = ImplGetFrameGraphics();
    1305        1374 :         if ( pGraphics )
    1306             :         {
    1307        1374 :             if( bReMirror )
    1308             :             {
    1309             :                 // --- RTL --- frame coordinates require re-mirroring
    1310           0 :                 pOutDev->ReMirror( aRegion );
    1311             :             }
    1312             : 
    1313        1374 :             pOutDev->SelectClipRegion( aRegion, pGraphics );
    1314        2748 :             pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
    1315             :                                  rRect.Left(), rRect.Top(),
    1316             :                                  rRect.GetWidth(), rRect.GetHeight(),
    1317        4122 :                                  SAL_COPYAREA_WINDOWINVALIDATE, this );
    1318             :         }
    1319             : #endif
    1320        1374 :         if ( mpWindowImpl->mpWinData )
    1321             :         {
    1322           0 :             if ( mpWindowImpl->mbFocusVisible )
    1323           0 :                 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
    1324           0 :             if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
    1325           0 :                 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
    1326             :         }
    1327             :     }
    1328             : 
    1329        1506 :     if ( !aInvalidateRegion.IsEmpty() )
    1330             :     {
    1331             :         // --- RTL --- the invalidate region for this windows is already computed in frame coordinates
    1332             :         // so it has to be re-mirrored before calling the Paint-handler
    1333        1506 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
    1334             : 
    1335        1506 :         sal_uInt16 nPaintFlags = INVALIDATE_CHILDREN;
    1336        1506 :         if ( !bErase )
    1337           0 :             nPaintFlags |= INVALIDATE_NOERASE;
    1338        1506 :         if ( !bScrollChildren )
    1339             :         {
    1340        1374 :             if ( nOrgFlags & SCROLL_NOCHILDREN )
    1341           0 :                 ImplClipAllChildren( aInvalidateRegion );
    1342             :             else
    1343        1374 :                 ImplClipChildren( aInvalidateRegion );
    1344             :         }
    1345        1506 :         ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags );
    1346             :     }
    1347             : 
    1348        1506 :     if ( bScrollChildren )
    1349             :     {
    1350         132 :         vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
    1351         436 :         while ( pWindow )
    1352             :         {
    1353         172 :             Point aPos = pWindow->GetPosPixel();
    1354         172 :             aPos += Point( nHorzScroll, nVertScroll );
    1355         172 :             pWindow->SetPosPixel( aPos );
    1356             : 
    1357         172 :             pWindow = pWindow->mpWindowImpl->mpNext;
    1358             :         }
    1359             :     }
    1360             : 
    1361        1506 :     if ( nFlags & SCROLL_UPDATE )
    1362           0 :         Update();
    1363             : 
    1364        1506 :     if ( mpWindowImpl->mpCursor )
    1365        2798 :         mpWindowImpl->mpCursor->ImplResume();
    1366             : }
    1367             : 
    1368        1233 : } /* namespace vcl */
    1369             : 
    1370             : 
    1371             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10