LCOV - code coverage report
Current view: top level - vcl/source/window - paint.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 589 864 68.2 %
Date: 2015-06-13 12:38:46 Functions: 44 53 83.0 %
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             : class PaintHelper
      43             : {
      44             : private:
      45             :     VclPtr<vcl::Window> m_pWindow;
      46             :     VclPtr<VirtualDevice> m_pBuffer; ///< Buffer for the double-buffering
      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 : 1;
      53             :     bool m_bRestoreCursor : 1;
      54             :     bool m_bCreatedBuffer : 1; ///< This PaintHelper created the buffer for the double-buffering, and should dispose it when being destructed (if it is still alive by then).
      55             : public:
      56             :     PaintHelper(vcl::Window* pWindow, const VclPtr<VirtualDevice>& rBuffer, sal_uInt16 nPaintFlags);
      57      146054 :     void SetPop()
      58             :     {
      59      146054 :         m_bPop = true;
      60      146054 :     }
      61      146054 :     void SetPaintRect(const Rectangle& rRect)
      62             :     {
      63      146054 :         m_aPaintRect = rRect;
      64      146054 :     }
      65           0 :     void SetSelectionRect(const Rectangle& rRect)
      66             :     {
      67           0 :         m_aSelectionRect = rRect;
      68           0 :     }
      69       12226 :     void SetRestoreCursor(bool bRestoreCursor)
      70             :     {
      71       12226 :         m_bRestoreCursor = bRestoreCursor;
      72       12226 :     }
      73       12465 :     bool GetRestoreCursor() const
      74             :     {
      75       12465 :         return m_bRestoreCursor;
      76             :     }
      77      146054 :     sal_uInt16 GetPaintFlags() const
      78             :     {
      79      146054 :         return m_nPaintFlags;
      80             :     }
      81      146054 :     vcl::Region& GetPaintRegion()
      82             :     {
      83      146054 :         return m_aPaintRegion;
      84             :     }
      85             :     void DoPaint(const vcl::Region* pRegion);
      86             : 
      87             :     /// Create m_pBuffer, and set it up to have the same settings as m_pWindow.
      88             :     void CreateBuffer();
      89             : 
      90             :     /// Setup m_pBuffer according to the settings of the current m_pWindow.
      91             :     void SetupBuffer();
      92             : 
      93             :     /// Paint the content of the buffer to the current m_pWindow.
      94             :     void PaintBuffer();
      95             : 
      96             :     ~PaintHelper();
      97             : };
      98             : 
      99      764034 : PaintHelper::PaintHelper(vcl::Window *pWindow, const VclPtr<VirtualDevice>& rBuffer, sal_uInt16 nPaintFlags)
     100             :     : m_pWindow(pWindow)
     101             :     , m_pBuffer(rBuffer)
     102             :     , m_pChildRegion(NULL)
     103             :     , m_nPaintFlags(nPaintFlags)
     104             :     , m_bPop(false)
     105             :     , m_bRestoreCursor(false)
     106      764034 :     , m_bCreatedBuffer(false)
     107             : {
     108      764034 : }
     109             : 
     110           0 : void PaintHelper::CreateBuffer()
     111             : {
     112             :     assert(!m_pBuffer);
     113             : 
     114           0 :     m_pBuffer = VclPtrInstance<VirtualDevice>();
     115           0 :     m_bCreatedBuffer = true;
     116             : 
     117           0 :     SetupBuffer();
     118             : 
     119             :     // update the output size now, after all the settings were copied
     120           0 :     m_pBuffer->SetOutputSize(m_pWindow->GetOutputSize());
     121             : 
     122             :     // we need to remember the mnOutOffX / mnOutOffY, but actually really
     123             :     // set it just temporarily for the subwidgets - so we are setting it here
     124             :     // only to remember the value & to be able to pass it to the descendants
     125             :     // FIXME: once everything's double-buffered, this is (hopefully) not
     126             :     // necessary as the m_pBuffer is always created for the main window.
     127           0 :     m_pBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel();
     128           0 :     m_pBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel();
     129           0 : }
     130             : 
     131           0 : void PaintHelper::SetupBuffer()
     132             : {
     133             :     // transfer various settings
     134             :     // FIXME: this must disappear as we move to RenderContext only,
     135             :     // the painting must become state-less, so that no actual
     136             :     // vcl::Window setting affects this
     137           0 :     if (m_pWindow->IsBackground())
     138           0 :         m_pBuffer->SetBackground(m_pWindow->GetBackground());
     139             :     else
     140             :         SAL_WARN("vcl.doublebuffering", "the root of the double-buffering hierarchy should not have a transparent background");
     141             : 
     142           0 :     m_pBuffer->SetClipRegion(m_pWindow->GetClipRegion());
     143           0 :     m_pBuffer->SetFillColor(m_pWindow->GetFillColor());
     144           0 :     m_pBuffer->SetFont(m_pWindow->GetFont());
     145           0 :     m_pBuffer->SetLineColor(m_pWindow->GetLineColor());
     146           0 :     m_pBuffer->SetMapMode(m_pWindow->GetMapMode());
     147           0 :     m_pBuffer->SetRefPoint(m_pWindow->GetRefPoint());
     148           0 :     m_pBuffer->SetSettings(m_pWindow->GetSettings());
     149           0 :     m_pBuffer->SetTextColor(m_pWindow->GetTextColor());
     150           0 :     m_pBuffer->SetTextLineColor(m_pWindow->GetTextLineColor());
     151           0 :     m_pBuffer->SetOverlineColor(m_pWindow->GetOverlineColor());
     152           0 :     m_pBuffer->SetTextFillColor(m_pWindow->GetTextFillColor());
     153           0 :     m_pBuffer->SetTextAlign(m_pWindow->GetTextAlign());
     154           0 :     m_pBuffer->SetRasterOp(m_pWindow->GetRasterOp());
     155           0 :     m_pBuffer->SetLayoutMode(m_pWindow->GetLayoutMode());
     156           0 :     m_pBuffer->SetDigitLanguage(m_pWindow->GetDigitLanguage());
     157           0 : }
     158             : 
     159           0 : void PaintHelper::PaintBuffer()
     160             : {
     161             :     assert(m_pBuffer);
     162             :     assert(m_bCreatedBuffer);
     163             : 
     164           0 :     m_pBuffer->mnOutOffX = 0;
     165           0 :     m_pBuffer->mnOutOffY = 0;
     166             : 
     167             :     // copy the buffer content to the actual window
     168             :     // export VCL_DOUBLEBUFFERING_AVOID_PAINT=1 to see where we are
     169             :     // painting directly instead of using Invalidate()
     170             :     // [ie. everything you can see was painted directly to the
     171             :     // window either above or in eg. an event handler]
     172           0 :     if (!getenv("VCL_DOUBLEBUFFERING_AVOID_PAINT"))
     173           0 :         m_pWindow->DrawOutDev(m_aPaintRect.TopLeft(), m_aPaintRect.GetSize(), m_aPaintRect.TopLeft(), m_aPaintRect.GetSize(), *m_pBuffer.get());
     174           0 : }
     175             : 
     176      238364 : void PaintHelper::DoPaint(const vcl::Region* pRegion)
     177             : {
     178      238364 :     WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
     179      238364 :     vcl::Region* pWinChildClipRegion = m_pWindow->ImplGetWinChildClipRegion();
     180      238364 :     if (pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL || m_pBuffer)
     181             :     {
     182      152373 :         pWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
     183             :     }
     184             :     else
     185             :     {
     186       85991 :         if (pRegion)
     187       59317 :             pWindowImpl->maInvalidateRegion.Union( *pRegion );
     188             : 
     189       85991 :         if (pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible)
     190             :             /* #98602# need to repaint all children within the
     191             :            * tracking rectangle, so the following invert
     192             :            * operation takes places without traces of the previous
     193             :            * one.
     194             :            */
     195           0 :            pWindowImpl->maInvalidateRegion.Union(*pWindowImpl->mpWinData->mpTrackRect);
     196             : 
     197       85991 :         if (pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN)
     198       41714 :             m_pChildRegion = new vcl::Region(pWindowImpl->maInvalidateRegion);
     199       85991 :         pWindowImpl->maInvalidateRegion.Intersect(*pWinChildClipRegion);
     200             :     }
     201      238364 :     pWindowImpl->mnPaintFlags = 0;
     202      238364 :     if (!pWindowImpl->maInvalidateRegion.IsEmpty())
     203             :     {
     204      146054 :         m_pWindow->BeginPaint();
     205             : 
     206             :         // double-buffering: setup the buffer if it does not exist
     207      146054 :         if (!m_pBuffer && m_pWindow->SupportsDoubleBuffering())
     208           0 :             CreateBuffer();
     209             : 
     210             :         // double-buffering: if this window does not support double-buffering,
     211             :         // but we are in the middle of double-buffered paint, we might be
     212             :         // losing information
     213      146054 :         if (m_pBuffer && !m_pWindow->SupportsDoubleBuffering())
     214             :             SAL_WARN("vcl.doublebuffering", "non-double buffered window in the double-buffered hierarchy, painting directly: " << typeid(*m_pWindow.get()).name());
     215             : 
     216      146054 :         if (m_pBuffer && m_pWindow->SupportsDoubleBuffering())
     217             :         {
     218             :             // double-buffering
     219           0 :             SetupBuffer();
     220           0 :             m_pWindow->ApplySettings(*m_pBuffer.get());
     221             : 
     222             :             // temporarily decrease the mnOutOffX/Y of the buffer for the
     223             :             // subwidgets (because the m_pBuffer is our base here)
     224             :             // FIXME: once everything's double-buffered, this is (hopefully) not
     225             :             // necessary as the m_pBuffer is always created for the main window.
     226           0 :             long nOutOffX = m_pBuffer->mnOutOffX;
     227           0 :             long nOutOffY = m_pBuffer->mnOutOffY;
     228           0 :             m_pBuffer->mnOutOffX = m_pWindow->GetOutOffXPixel() - m_pBuffer->mnOutOffX;
     229           0 :             m_pBuffer->mnOutOffY = m_pWindow->GetOutOffYPixel() - m_pBuffer->mnOutOffY;
     230             : 
     231           0 :             m_pWindow->PushPaintHelper(this, *m_pBuffer.get());
     232           0 :             m_pWindow->Paint(*m_pBuffer.get(), m_aPaintRect);
     233             : 
     234             :             // restore the mnOutOffX/Y value
     235           0 :             m_pBuffer->mnOutOffX = nOutOffX;
     236           0 :             m_pBuffer->mnOutOffY = nOutOffY;
     237             :         }
     238             :         else
     239             :         {
     240             :             // direct painting
     241      146054 :             m_pWindow->ApplySettings(*m_pWindow);
     242      146054 :             m_pWindow->PushPaintHelper(this, *m_pWindow);
     243      146054 :             m_pWindow->Paint(*m_pWindow, m_aPaintRect);
     244             :         }
     245             : 
     246      146054 :         m_pWindow->EndPaint();
     247             :     }
     248      238364 : }
     249             : 
     250             : namespace vcl
     251             : {
     252             : 
     253        1061 : void RenderTools::DrawSelectionBackground(vcl::RenderContext& rRenderContext, vcl::Window& rWindow,
     254             :                                           const Rectangle& rRect, sal_uInt16 nHighlight,
     255             :                                           bool bChecked, bool bDrawBorder, bool bDrawExtBorderOnly,
     256             :                                           Color* pSelectionTextColor, long nCornerRadius, Color* pPaintColor)
     257             : {
     258        1061 :     if (rRect.IsEmpty())
     259        1061 :         return;
     260             : 
     261        1061 :     bool bRoundEdges = nCornerRadius > 0;
     262             : 
     263        1061 :     const StyleSettings& rStyles = rRenderContext.GetSettings().GetStyleSettings();
     264             : 
     265             :     // colors used for item highlighting
     266        1061 :     Color aSelectionBorderColor(pPaintColor ? *pPaintColor : rStyles.GetHighlightColor());
     267        1061 :     Color aSelectionFillColor(aSelectionBorderColor);
     268             : 
     269        1061 :     bool bDark = rStyles.GetFaceColor().IsDark();
     270        1061 :     bool bBright = ( rStyles.GetFaceColor() == Color( COL_WHITE ) );
     271             : 
     272        1061 :     int c1 = aSelectionBorderColor.GetLuminance();
     273        1061 :     int c2 = rWindow.GetDisplayBackground().GetColor().GetLuminance();
     274             : 
     275        1061 :     if (!bDark && !bBright && std::abs(c2 - c1) < (pPaintColor ? 40 : 75))
     276             :     {
     277             :         // constrast too low
     278             :         sal_uInt16 h, s, b;
     279           0 :         aSelectionFillColor.RGBtoHSB( h, s, b );
     280           0 :         if( b > 50 )    b -= 40;
     281           0 :         else            b += 40;
     282           0 :         aSelectionFillColor.SetColor( Color::HSBtoRGB( h, s, b ) );
     283           0 :         aSelectionBorderColor = aSelectionFillColor;
     284             :     }
     285             : 
     286        1061 :     if (bRoundEdges)
     287             :     {
     288        1058 :         if (aSelectionBorderColor.IsDark())
     289        1058 :             aSelectionBorderColor.IncreaseLuminance(128);
     290             :         else
     291           0 :             aSelectionBorderColor.DecreaseLuminance(128);
     292             :     }
     293             : 
     294        1061 :     Rectangle aRect(rRect);
     295        1061 :     if (bDrawExtBorderOnly)
     296             :     {
     297           0 :         aRect.Left()   -= 1;
     298           0 :         aRect.Top()    -= 1;
     299           0 :         aRect.Right()  += 1;
     300           0 :         aRect.Bottom() += 1;
     301             :     }
     302        1061 :     rRenderContext.Push(PushFlags::FILLCOLOR | PushFlags::LINECOLOR);
     303             : 
     304        1061 :     if (bDrawBorder)
     305        1061 :         rRenderContext.SetLineColor(bDark ? Color(COL_WHITE) : (bBright ? Color(COL_BLACK) : aSelectionBorderColor));
     306             :     else
     307           0 :         rRenderContext.SetLineColor();
     308             : 
     309        1061 :     sal_uInt16 nPercent = 0;
     310        1061 :     if (!nHighlight)
     311             :     {
     312        1058 :         if (bDark)
     313           0 :             aSelectionFillColor = COL_BLACK;
     314             :         else
     315        1058 :             nPercent = 80;  // just checked (light)
     316             :     }
     317             :     else
     318             :     {
     319           3 :         if (bChecked && nHighlight == 2)
     320             :         {
     321           0 :             if (bDark)
     322           0 :                 aSelectionFillColor = COL_LIGHTGRAY;
     323           0 :             else if (bBright)
     324             :             {
     325           0 :                 aSelectionFillColor = COL_BLACK;
     326           0 :                 rRenderContext.SetLineColor(COL_BLACK);
     327           0 :                 nPercent = 0;
     328             :             }
     329             :             else
     330           0 :                 nPercent = bRoundEdges ? 40 : 20; // selected, pressed or checked ( very dark )
     331             :         }
     332           3 :         else if (bChecked || nHighlight == 1)
     333             :         {
     334           6 :             if (bDark)
     335           0 :                 aSelectionFillColor = COL_GRAY;
     336           3 :             else if (bBright)
     337             :             {
     338           0 :                 aSelectionFillColor = COL_BLACK;
     339           0 :                 rRenderContext.SetLineColor(COL_BLACK);
     340           0 :                 nPercent = 0;
     341             :             }
     342             :             else
     343           3 :                 nPercent = bRoundEdges ? 60 : 35; // selected, pressed or checked ( very dark )
     344             :         }
     345             :         else
     346             :         {
     347           0 :             if (bDark)
     348           0 :                 aSelectionFillColor = COL_LIGHTGRAY;
     349           0 :             else if (bBright)
     350             :             {
     351           0 :                 aSelectionFillColor = COL_BLACK;
     352           0 :                 rRenderContext.SetLineColor(COL_BLACK);
     353           0 :                 if (nHighlight == 3)
     354           0 :                     nPercent = 80;
     355             :                 else
     356           0 :                     nPercent = 0;
     357             :             }
     358             :             else
     359           0 :                 nPercent = 70; // selected ( dark )
     360             :         }
     361             :     }
     362             : 
     363        1061 :     if (bDark && bDrawExtBorderOnly)
     364             :     {
     365           0 :         rRenderContext.SetFillColor();
     366           0 :         if (pSelectionTextColor)
     367           0 :             *pSelectionTextColor = rStyles.GetHighlightTextColor();
     368             :     }
     369             :     else
     370             :     {
     371        1061 :         rRenderContext.SetFillColor(aSelectionFillColor);
     372        1061 :         if (pSelectionTextColor)
     373             :         {
     374           0 :             Color aTextColor = rWindow.IsControlBackground() ? rWindow.GetControlForeground() : rStyles.GetButtonTextColor();
     375           0 :             Color aHLTextColor = rStyles.GetHighlightTextColor();
     376           0 :             int nTextDiff = std::abs(aSelectionFillColor.GetLuminance() - aTextColor.GetLuminance());
     377           0 :             int nHLDiff = std::abs(aSelectionFillColor.GetLuminance() - aHLTextColor.GetLuminance());
     378           0 :             *pSelectionTextColor = (nHLDiff >= nTextDiff) ? aHLTextColor : aTextColor;
     379             :         }
     380             :     }
     381             : 
     382        1061 :     if (bDark)
     383             :     {
     384           0 :         rRenderContext.DrawRect(aRect);
     385             :     }
     386             :     else
     387             :     {
     388        1061 :         if (bRoundEdges)
     389             :         {
     390        1058 :             Polygon aPoly(aRect, nCornerRadius, nCornerRadius);
     391        2116 :             tools::PolyPolygon aPolyPoly(aPoly);
     392        2116 :             rRenderContext.DrawTransparent(aPolyPoly, nPercent);
     393             :         }
     394             :         else
     395             :         {
     396           3 :             Polygon aPoly(aRect);
     397           6 :             tools::PolyPolygon aPolyPoly(aPoly);
     398           6 :             rRenderContext.DrawTransparent(aPolyPoly, nPercent);
     399             :         }
     400             :     }
     401             : 
     402        1061 :     rRenderContext.Pop(); // LINECOLOR | FILLCOLOR
     403             : }
     404             : 
     405      146054 : void Window::PushPaintHelper(PaintHelper *pHelper, vcl::RenderContext& rRenderContext)
     406             : {
     407      146054 :     pHelper->SetPop();
     408             : 
     409      146054 :     if ( mpWindowImpl->mpCursor )
     410       12226 :         pHelper->SetRestoreCursor(mpWindowImpl->mpCursor->ImplSuspend());
     411             : 
     412      146054 :     mbInitClipRegion = true;
     413      146054 :     mpWindowImpl->mbInPaint = true;
     414             : 
     415             :     // restore Paint-Region
     416      146054 :     vcl::Region &rPaintRegion = pHelper->GetPaintRegion();
     417      146054 :     rPaintRegion = mpWindowImpl->maInvalidateRegion;
     418      146054 :     Rectangle aPaintRect = rPaintRegion.GetBoundRect();
     419             : 
     420             :     // - RTL - re-mirror paint rect and region at this window
     421      146054 :     if (ImplIsAntiparallel())
     422             :     {
     423          45 :         rRenderContext.ReMirror(aPaintRect);
     424          45 :         rRenderContext.ReMirror(rPaintRegion);
     425             :     }
     426      146054 :     aPaintRect = ImplDevicePixelToLogic(aPaintRect);
     427      146054 :     mpWindowImpl->mpPaintRegion = &rPaintRegion;
     428      146054 :     mpWindowImpl->maInvalidateRegion.SetEmpty();
     429             : 
     430      146054 :     if ((pHelper->GetPaintFlags() & IMPL_PAINT_ERASE) && rRenderContext.IsBackground())
     431             :     {
     432       92903 :         if (rRenderContext.IsClipRegion())
     433             :         {
     434           0 :             vcl::Region aOldRegion = rRenderContext.GetClipRegion();
     435           0 :             rRenderContext.SetClipRegion();
     436           0 :             Erase(rRenderContext);
     437           0 :             rRenderContext.SetClipRegion(aOldRegion);
     438             :         }
     439             :         else
     440       92903 :             Erase(rRenderContext);
     441             :     }
     442             : 
     443             :     // #98943# trigger drawing of toolbox selection after all childern are painted
     444      146054 :     if (mpWindowImpl->mbDrawSelectionBackground)
     445           0 :         pHelper->SetSelectionRect(aPaintRect);
     446      146054 :     pHelper->SetPaintRect(aPaintRect);
     447      146054 : }
     448             : 
     449      146054 : void Window::PopPaintHelper(PaintHelper *pHelper)
     450             : {
     451      146054 :     if (mpWindowImpl->mpWinData)
     452             :     {
     453       95045 :         if (mpWindowImpl->mbFocusVisible)
     454          18 :             ImplInvertFocus(*(mpWindowImpl->mpWinData->mpFocusRect));
     455             :     }
     456      146054 :     mpWindowImpl->mbInPaint = false;
     457      146054 :     mbInitClipRegion = true;
     458      146054 :     mpWindowImpl->mpPaintRegion = NULL;
     459      146054 :     if (mpWindowImpl->mpCursor)
     460       12465 :         mpWindowImpl->mpCursor->ImplResume(pHelper->GetRestoreCursor());
     461      146054 : }
     462             : 
     463             : } /* namespace vcl */
     464             : 
     465     1528068 : PaintHelper::~PaintHelper()
     466             : {
     467      764034 :     WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
     468      764034 :     if (m_bPop)
     469             :     {
     470      146054 :         m_pWindow->PopPaintHelper(this);
     471             :     }
     472             : 
     473      764034 :     if ( m_nPaintFlags & (IMPL_PAINT_PAINTALLCHILDREN | IMPL_PAINT_PAINTCHILDREN) )
     474             :     {
     475             :         // Paint from the bottom child window and frontward.
     476      744899 :         vcl::Window* pTempWindow = pWindowImpl->mpLastChild;
     477     2608559 :         while (pTempWindow)
     478             :         {
     479     1118761 :             if (pTempWindow->mpWindowImpl->mbVisible)
     480      736889 :                 pTempWindow->ImplCallPaint(m_pBuffer, m_pChildRegion, m_nPaintFlags);
     481     1118761 :             pTempWindow = pTempWindow->mpWindowImpl->mpPrev;
     482             :         }
     483             :     }
     484             : 
     485      764034 :     if ( pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible && (pWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
     486             :         /* #98602# need to invert the tracking rect AFTER
     487             :         * the children have painted
     488             :         */
     489           0 :         m_pWindow->InvertTracking( *(pWindowImpl->mpWinData->mpTrackRect), pWindowImpl->mpWinData->mnTrackFlags );
     490             : 
     491             :     // double-buffering: paint in case we created the buffer, the children are
     492             :     // already painted inside
     493      764034 :     if (m_bCreatedBuffer && m_pBuffer)
     494             :     {
     495           0 :         PaintBuffer();
     496           0 :         m_pBuffer.disposeAndClear();
     497             :     }
     498             : 
     499             :     // #98943# draw toolbox selection
     500      764034 :     if( !m_aSelectionRect.IsEmpty() )
     501           0 :         m_pWindow->DrawSelectionBackground( m_aSelectionRect, 3, false, true, false );
     502             : 
     503      764034 :     delete m_pChildRegion;
     504      764034 : }
     505             : 
     506             : namespace vcl {
     507             : 
     508      783423 : void Window::ImplCallPaint(const VclPtr<VirtualDevice>& rBuffer, const vcl::Region* pRegion, sal_uInt16 nPaintFlags)
     509             : {
     510             :     // call PrePaint. PrePaint may add to the invalidate region as well as
     511             :     // other parameters used below.
     512      783423 :     PrePaint(*this);
     513             : 
     514      783423 :     mpWindowImpl->mbPaintFrame = false;
     515             : 
     516      783423 :     if (nPaintFlags & IMPL_PAINT_PAINTALLCHILDREN)
     517      226577 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALLCHILDREN | (nPaintFlags & IMPL_PAINT_PAINTALL);
     518      783423 :     if (nPaintFlags & IMPL_PAINT_PAINTCHILDREN)
     519      753367 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDREN;
     520      783423 :     if (nPaintFlags & IMPL_PAINT_ERASE)
     521      235179 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
     522      783423 :     if (nPaintFlags & IMPL_PAINT_CHECKRTL)
     523       33567 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
     524      783423 :     if (!mpWindowImpl->mpFirstChild)
     525      474899 :         mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALLCHILDREN;
     526             : 
     527      783423 :     if (mpWindowImpl->mbPaintDisabled)
     528             :     {
     529       19389 :         if (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL)
     530       19326 :             Invalidate(InvalidateFlags::NoChildren | InvalidateFlags::NoErase | InvalidateFlags::NoTransparent | InvalidateFlags::NoClipChildren);
     531          63 :         else if ( pRegion )
     532          24 :             Invalidate(*pRegion, InvalidateFlags::NoChildren | InvalidateFlags::NoErase | InvalidateFlags::NoTransparent | InvalidateFlags::NoClipChildren);
     533      802812 :         return;
     534             :     }
     535             : 
     536      764034 :     nPaintFlags = mpWindowImpl->mnPaintFlags & ~(IMPL_PAINT_PAINT);
     537             : 
     538      764034 :     PaintHelper aHelper(this, rBuffer, nPaintFlags);
     539             : 
     540      764034 :     if (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT)
     541      238364 :         aHelper.DoPaint(pRegion);
     542             :     else
     543      525670 :         mpWindowImpl->mnPaintFlags = 0;
     544             : 
     545      764034 :     PostPaint(*this);
     546             : }
     547             : 
     548       16205 : void Window::ImplCallOverlapPaint()
     549             : {
     550             :     // emit overlapping windows first
     551       16205 :     vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
     552       32410 :     while ( pTempWindow )
     553             :     {
     554           0 :         if ( pTempWindow->mpWindowImpl->mbReallyVisible )
     555           0 :             pTempWindow->ImplCallOverlapPaint();
     556           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
     557             :     }
     558             : 
     559             :     // only then ourself
     560       16205 :     if ( mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
     561             :     {
     562             :         // - RTL - notify ImplCallPaint to check for re-mirroring (CHECKRTL)
     563             :         //         because we were called from the Sal layer
     564       16082 :         OutputDevice *pOutDev = GetOutDev();
     565       16082 :         pOutDev->BeginPaint();
     566       16082 :         ImplCallPaint(NULL, NULL, mpWindowImpl->mnPaintFlags /*| IMPL_PAINT_CHECKRTL */);
     567       16082 :         pOutDev->EndPaint();
     568             :     }
     569       16205 : }
     570             : 
     571      448056 : void Window::ImplPostPaint()
     572             : {
     573      448056 :     if ( !ImplDoTiledRendering() && !mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
     574       19405 :         mpWindowImpl->mpFrameData->maPaintIdle.Start();
     575      448056 : }
     576             : 
     577       32480 : IMPL_LINK_NOARG_TYPED(Window, ImplHandlePaintHdl, Idle *, void)
     578             : {
     579             :     // save paint events until layout is done
     580       16240 :     if (!ImplDoTiledRendering() && IsSystemWindow() && static_cast<const SystemWindow*>(this)->hasPendingLayout())
     581             :     {
     582           0 :         mpWindowImpl->mpFrameData->maPaintIdle.Start();
     583       16240 :         return;
     584             :     }
     585             : 
     586             :     // save paint events until resizing is done
     587       48720 :     if( !ImplDoTiledRendering() &&
     588       32480 :         mpWindowImpl->mbFrame && mpWindowImpl->mpFrameData->maResizeIdle.IsActive() )
     589           0 :         mpWindowImpl->mpFrameData->maPaintIdle.Start();
     590       16240 :     else if ( mpWindowImpl->mbReallyVisible )
     591       16205 :         ImplCallOverlapPaint();
     592             : }
     593             : 
     594        6392 : IMPL_LINK_NOARG_TYPED(Window, ImplHandleResizeTimerHdl, Idle *, void)
     595             : {
     596        3196 :     if( mpWindowImpl->mbReallyVisible )
     597             :     {
     598          73 :         ImplCallResize();
     599          73 :         if( ImplDoTiledRendering() )
     600             :         {
     601           0 :             ImplHandlePaintHdl(NULL);
     602             :         }
     603          73 :         else if( mpWindowImpl->mpFrameData->maPaintIdle.IsActive() )
     604             :         {
     605          73 :             mpWindowImpl->mpFrameData->maPaintIdle.Stop();
     606          73 :             mpWindowImpl->mpFrameData->maPaintIdle.GetIdleHdl().Call( NULL );
     607             :         }
     608             :     }
     609        3196 : }
     610             : 
     611      448056 : void Window::ImplInvalidateFrameRegion( const vcl::Region* pRegion, InvalidateFlags nFlags )
     612             : {
     613             :     // set PAINTCHILDREN for all parent windows till the first OverlapWindow
     614      448056 :     if ( !ImplIsOverlapWindow() )
     615             :     {
     616      441940 :         vcl::Window* pTempWindow = this;
     617      441940 :         sal_uInt16 nTranspPaint = IsPaintTransparent() ? IMPL_PAINT_PAINT : 0;
     618      148001 :         do
     619             :         {
     620      571059 :             pTempWindow = pTempWindow->ImplGetParent();
     621      571059 :             if ( pTempWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDREN )
     622      423058 :                 break;
     623      148001 :             pTempWindow->mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTCHILDREN | nTranspPaint;
     624      148001 :             if( ! pTempWindow->IsPaintTransparent() )
     625      147921 :                 nTranspPaint = 0;
     626             :         }
     627      148001 :         while ( !pTempWindow->ImplIsOverlapWindow() );
     628             :     }
     629             : 
     630             :     // set Paint-Flags
     631      448056 :     mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINT;
     632      448056 :     if ( nFlags & InvalidateFlags::Children )
     633      384450 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALLCHILDREN;
     634      448056 :     if ( !(nFlags & InvalidateFlags::NoErase) )
     635      372268 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_ERASE;
     636      448056 :     if ( !pRegion )
     637      255749 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_PAINTALL;
     638             : 
     639             :     // if not everything has to be redrawn, add the region to it
     640      448056 :     if ( !(mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL) )
     641      133735 :         mpWindowImpl->maInvalidateRegion.Union( *pRegion );
     642             : 
     643             :     // Handle transparent windows correctly: invalidate must be done on the first opaque parent
     644      902424 :     if( ((IsPaintTransparent() && !(nFlags & InvalidateFlags::NoTransparent)) || (nFlags & InvalidateFlags::Transparent) )
     645      902365 :             && ImplGetParent() )
     646             :     {
     647        6246 :         vcl::Window *pParent = ImplGetParent();
     648       12874 :         while( pParent && pParent->IsPaintTransparent() )
     649         382 :             pParent = pParent->ImplGetParent();
     650        6246 :         if( pParent )
     651             :         {
     652             :             vcl::Region *pChildRegion;
     653        6246 :             if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     654             :                 // invalidate the whole child window region in the parent
     655        1206 :                 pChildRegion = ImplGetWinChildClipRegion();
     656             :             else
     657             :                 // invalidate the same region in the parent that has to be repainted in the child
     658        5040 :                 pChildRegion = &mpWindowImpl->maInvalidateRegion;
     659             : 
     660        6246 :             nFlags |= InvalidateFlags::Children;  // paint should also be done on all children
     661        6246 :             nFlags &= ~InvalidateFlags::NoErase;  // parent should paint and erase to create proper background
     662        6246 :             pParent->ImplInvalidateFrameRegion( pChildRegion, nFlags );
     663             :         }
     664             :     }
     665      448056 :     ImplPostPaint();
     666      448056 : }
     667             : 
     668        7820 : void Window::ImplInvalidateOverlapFrameRegion( const vcl::Region& rRegion )
     669             : {
     670        7820 :     vcl::Region aRegion = rRegion;
     671             : 
     672        7820 :     ImplClipBoundaries( aRegion, true, true );
     673        7820 :     if ( !aRegion.IsEmpty() )
     674        3103 :         ImplInvalidateFrameRegion( &aRegion, InvalidateFlags::Children );
     675             : 
     676             :     // now we invalidate the overlapping windows
     677        7820 :     vcl::Window* pTempWindow = mpWindowImpl->mpFirstOverlap;
     678       15640 :     while ( pTempWindow )
     679             :     {
     680           0 :         if ( pTempWindow->IsVisible() )
     681           0 :             pTempWindow->ImplInvalidateOverlapFrameRegion( rRegion );
     682             : 
     683           0 :         pTempWindow = pTempWindow->mpWindowImpl->mpNext;
     684        7820 :     }
     685        7820 : }
     686             : 
     687      107854 : void Window::ImplInvalidateParentFrameRegion( vcl::Region& rRegion )
     688             : {
     689      107854 :     if ( mpWindowImpl->mbOverlapWin )
     690           0 :         mpWindowImpl->mpFrameWindow->ImplInvalidateOverlapFrameRegion( rRegion );
     691             :     else
     692             :     {
     693      107854 :         if( ImplGetParent() )
     694      107854 :             ImplGetParent()->ImplInvalidateFrameRegion( &rRegion, InvalidateFlags::Children );
     695             :     }
     696      107854 : }
     697             : 
     698      241671 : void Window::ImplInvalidate( const vcl::Region* pRegion, InvalidateFlags nFlags )
     699             : {
     700             :     // reset background storage
     701      241671 :     if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
     702           0 :         ImplInvalidateAllOverlapBackgrounds();
     703             : 
     704             :     // check what has to be redrawn
     705      241671 :     bool bInvalidateAll = !pRegion;
     706             : 
     707             :     // take Transparent-Invalidate into account
     708      241671 :     vcl::Window* pOpaqueWindow = this;
     709      241671 :     if ( (mpWindowImpl->mbPaintTransparent && !(nFlags & InvalidateFlags::NoTransparent)) || (nFlags & InvalidateFlags::Transparent) )
     710             :     {
     711        8753 :         vcl::Window* pTempWindow = pOpaqueWindow->ImplGetParent();
     712       17669 :         while ( pTempWindow )
     713             :         {
     714        8916 :             if ( !pTempWindow->IsPaintTransparent() )
     715             :             {
     716        8753 :                 pOpaqueWindow = pTempWindow;
     717        8753 :                 nFlags |= InvalidateFlags::Children;
     718        8753 :                 bInvalidateAll = false;
     719        8753 :                 break;
     720             :             }
     721             : 
     722         163 :             if ( pTempWindow->ImplIsOverlapWindow() )
     723           0 :                 break;
     724             : 
     725         163 :             pTempWindow = pTempWindow->ImplGetParent();
     726             :         }
     727             :     }
     728             : 
     729             :     // assemble region
     730      241671 :     InvalidateFlags nOrgFlags = nFlags;
     731      241671 :     if ( !(nFlags & (InvalidateFlags::Children | InvalidateFlags::NoChildren)) )
     732             :     {
     733      160279 :         if ( GetStyle() & WB_CLIPCHILDREN )
     734       51427 :             nFlags |= InvalidateFlags::NoChildren;
     735             :         else
     736      108852 :             nFlags |= InvalidateFlags::Children;
     737             :     }
     738      241671 :     if ( (nFlags & InvalidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
     739       24396 :         bInvalidateAll = false;
     740      241671 :     if ( bInvalidateAll )
     741      164860 :         ImplInvalidateFrameRegion( NULL, nFlags );
     742             :     else
     743             :     {
     744       76811 :         Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     745       76811 :         vcl::Region      aRegion( aRect );
     746       76811 :         if ( pRegion )
     747             :         {
     748             :             // --- RTL --- remirror region before intersecting it
     749       56771 :             if ( ImplIsAntiparallel() )
     750             :             {
     751           0 :                 const OutputDevice *pOutDev = GetOutDev();
     752             : 
     753           0 :                 vcl::Region aRgn( *pRegion );
     754           0 :                 pOutDev->ReMirror( aRgn );
     755           0 :                 aRegion.Intersect( aRgn );
     756             :             }
     757             :             else
     758       56771 :                 aRegion.Intersect( *pRegion );
     759             :         }
     760       76811 :         ImplClipBoundaries( aRegion, true, true );
     761       76811 :         if ( nFlags & InvalidateFlags::NoChildren )
     762             :         {
     763       46219 :             nFlags &= ~InvalidateFlags::Children;
     764       46219 :             if ( !(nFlags & InvalidateFlags::NoClipChildren) )
     765             :             {
     766       45825 :                 if ( nOrgFlags & InvalidateFlags::NoChildren )
     767         930 :                     ImplClipAllChildren( aRegion );
     768             :                 else
     769             :                 {
     770       44895 :                     if ( ImplClipChildren( aRegion ) )
     771        1705 :                         nFlags |= InvalidateFlags::Children;
     772             :                 }
     773             :             }
     774             :         }
     775       76811 :         if ( !aRegion.IsEmpty() )
     776       66065 :             ImplInvalidateFrameRegion( &aRegion, nFlags );  // transparency is handled here, pOpaqueWindow not required
     777             :     }
     778             : 
     779      241671 :     if ( nFlags & InvalidateFlags::Update )
     780           0 :         pOpaqueWindow->Update();        // start painting at the opaque parent
     781      241671 : }
     782             : 
     783         492 : void Window::ImplMoveInvalidateRegion( const Rectangle& rRect,
     784             :                                        long nHorzScroll, long nVertScroll,
     785             :                                        bool bChildren )
     786             : {
     787         492 :     if ( (mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTALL)) == IMPL_PAINT_PAINT )
     788             :     {
     789           8 :         vcl::Region aTempRegion = mpWindowImpl->maInvalidateRegion;
     790           8 :         aTempRegion.Intersect( rRect );
     791           8 :         aTempRegion.Move( nHorzScroll, nVertScroll );
     792           8 :         mpWindowImpl->maInvalidateRegion.Union( aTempRegion );
     793             :     }
     794             : 
     795         492 :     if ( bChildren && (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTCHILDREN) )
     796             :     {
     797          31 :         vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
     798          94 :         while ( pWindow )
     799             :         {
     800          32 :             pWindow->ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, true );
     801          32 :             pWindow = pWindow->mpWindowImpl->mpNext;
     802             :         }
     803             :     }
     804         492 : }
     805             : 
     806         460 : void Window::ImplMoveAllInvalidateRegions( const Rectangle& rRect,
     807             :                                            long nHorzScroll, long nVertScroll,
     808             :                                            bool bChildren )
     809             : {
     810             :     // also shift Paint-Region when paints need processing
     811         460 :     ImplMoveInvalidateRegion( rRect, nHorzScroll, nVertScroll, bChildren );
     812             :     // Paint-Region should be shifted, as drawn by the parents
     813         460 :     if ( !ImplIsOverlapWindow() )
     814             :     {
     815         460 :         vcl::Region  aPaintAllRegion;
     816         460 :         vcl::Window* pPaintAllWindow = this;
     817        2289 :         do
     818             :         {
     819        2289 :             pPaintAllWindow = pPaintAllWindow->ImplGetParent();
     820        2289 :             if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
     821             :             {
     822           0 :                 if ( pPaintAllWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     823             :                 {
     824           0 :                     aPaintAllRegion.SetEmpty();
     825           0 :                     break;
     826             :                 }
     827             :                 else
     828           0 :                     aPaintAllRegion.Union( pPaintAllWindow->mpWindowImpl->maInvalidateRegion );
     829             :             }
     830             :         }
     831        2289 :         while ( !pPaintAllWindow->ImplIsOverlapWindow() );
     832         460 :         if ( !aPaintAllRegion.IsEmpty() )
     833             :         {
     834           0 :             aPaintAllRegion.Move( nHorzScroll, nVertScroll );
     835           0 :             InvalidateFlags nPaintFlags = InvalidateFlags::NONE;
     836           0 :             if ( bChildren )
     837           0 :                 nPaintFlags |= InvalidateFlags::Children;
     838           0 :             ImplInvalidateFrameRegion( &aPaintAllRegion, nPaintFlags );
     839         460 :         }
     840             :     }
     841         460 : }
     842             : 
     843         228 : void Window::ImplValidateFrameRegion( const vcl::Region* pRegion, ValidateFlags nFlags )
     844             : {
     845         228 :     if ( !pRegion )
     846         228 :         mpWindowImpl->maInvalidateRegion.SetEmpty();
     847             :     else
     848             :     {
     849             :         // when all child windows have to be drawn we need to invalidate them before doing so
     850           0 :         if ( (mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN) && mpWindowImpl->mpFirstChild )
     851             :         {
     852           0 :             vcl::Region aChildRegion = mpWindowImpl->maInvalidateRegion;
     853           0 :             if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     854             :             {
     855           0 :                 Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     856           0 :                 aChildRegion = aRect;
     857             :             }
     858           0 :             vcl::Window* pChild = mpWindowImpl->mpFirstChild;
     859           0 :             while ( pChild )
     860             :             {
     861           0 :                 pChild->Invalidate( aChildRegion, InvalidateFlags::Children | InvalidateFlags::NoTransparent );
     862           0 :                 pChild = pChild->mpWindowImpl->mpNext;
     863           0 :             }
     864             :         }
     865           0 :         if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
     866             :         {
     867           0 :             Rectangle aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     868           0 :             mpWindowImpl->maInvalidateRegion = aRect;
     869             :         }
     870           0 :         mpWindowImpl->maInvalidateRegion.Exclude( *pRegion );
     871             :     }
     872         228 :     mpWindowImpl->mnPaintFlags &= ~IMPL_PAINT_PAINTALL;
     873             : 
     874         228 :     if ( nFlags & ValidateFlags::Children )
     875             :     {
     876           0 :         vcl::Window* pChild = mpWindowImpl->mpFirstChild;
     877           0 :         while ( pChild )
     878             :         {
     879           0 :             pChild->ImplValidateFrameRegion( pRegion, nFlags );
     880           0 :             pChild = pChild->mpWindowImpl->mpNext;
     881             :         }
     882             :     }
     883         228 : }
     884             : 
     885         228 : void Window::ImplValidate( const vcl::Region* pRegion, ValidateFlags nFlags )
     886             : {
     887             :     // assemble region
     888         228 :     bool    bValidateAll = !pRegion;
     889         228 :     ValidateFlags nOrgFlags = nFlags;
     890         228 :     if ( !(nFlags & (ValidateFlags::Children | ValidateFlags::NoChildren)) )
     891             :     {
     892         228 :         if ( GetStyle() & WB_CLIPCHILDREN )
     893         228 :             nFlags |= ValidateFlags::NoChildren;
     894             :         else
     895           0 :             nFlags |= ValidateFlags::Children;
     896             :     }
     897         228 :     if ( (nFlags & ValidateFlags::NoChildren) && mpWindowImpl->mpFirstChild )
     898           0 :         bValidateAll = false;
     899         228 :     if ( bValidateAll )
     900         228 :         ImplValidateFrameRegion( NULL, nFlags );
     901             :     else
     902             :     {
     903           0 :         Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
     904           0 :         vcl::Region      aRegion( aRect );
     905           0 :         if ( pRegion )
     906           0 :             aRegion.Intersect( *pRegion );
     907           0 :         ImplClipBoundaries( aRegion, true, true );
     908           0 :         if ( nFlags & ValidateFlags::NoChildren )
     909             :         {
     910           0 :             nFlags &= ~ValidateFlags::Children;
     911           0 :             if ( nOrgFlags & ValidateFlags::NoChildren )
     912           0 :                 ImplClipAllChildren( aRegion );
     913             :             else
     914             :             {
     915           0 :                 if ( ImplClipChildren( aRegion ) )
     916           0 :                     nFlags |= ValidateFlags::Children;
     917             :             }
     918             :         }
     919           0 :         if ( !aRegion.IsEmpty() )
     920           0 :             ImplValidateFrameRegion( &aRegion, nFlags );
     921             :     }
     922         228 : }
     923             : 
     924           0 : void Window::ImplUpdateAll( bool bOverlapWindows )
     925             : {
     926           0 :     if ( !mpWindowImpl->mbReallyVisible )
     927           0 :         return;
     928             : 
     929           0 :     bool bFlush = false;
     930           0 :     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
     931             :     {
     932           0 :         Point aPoint( 0, 0 );
     933           0 :         vcl::Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
     934           0 :         ImplInvalidateOverlapFrameRegion( aRegion );
     935           0 :         if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
     936           0 :             bFlush = true;
     937             :     }
     938             : 
     939             :     // an update changes the OverlapWindow, such that for later paints
     940             :     // not too much has to be drawn, if ALLCHILDREN etc. is set
     941           0 :     vcl::Window* pWindow = ImplGetFirstOverlapWindow();
     942           0 :     if ( bOverlapWindows )
     943           0 :         pWindow->ImplCallOverlapPaint();
     944             :     else
     945             :     {
     946           0 :         if (pWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN))
     947           0 :             pWindow->ImplCallPaint(NULL, NULL, pWindow->mpWindowImpl->mnPaintFlags);
     948             :     }
     949             : 
     950           0 :     if ( bFlush )
     951           0 :         Flush();
     952             : }
     953             : 
     954      747659 : void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
     955             : {
     956      747659 : }
     957             : 
     958      764030 : void Window::PostPaint(vcl::RenderContext& /*rRenderContext*/)
     959             : {
     960      764030 : }
     961             : 
     962       24300 : void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const Rectangle& rRect)
     963             : {
     964       24300 :     CallEventListeners(VCLEVENT_WINDOW_PAINT, const_cast<Rectangle *>(&rRect));
     965       24300 : }
     966             : 
     967      118505 : void Window::SetPaintTransparent( bool bTransparent )
     968             : {
     969             :     // transparency is not useful for frames as the background would have to be provided by a different frame
     970      118505 :     if( bTransparent && mpWindowImpl->mbFrame )
     971      118505 :         return;
     972             : 
     973      118505 :     if ( mpWindowImpl->mpBorderWindow )
     974         171 :         mpWindowImpl->mpBorderWindow->SetPaintTransparent( bTransparent );
     975             : 
     976      118505 :     mpWindowImpl->mbPaintTransparent = bTransparent;
     977             : }
     978             : 
     979           0 : void Window::SetWindowRegionPixel()
     980             : {
     981             : 
     982           0 :     if ( mpWindowImpl->mpBorderWindow )
     983           0 :         mpWindowImpl->mpBorderWindow->SetWindowRegionPixel();
     984           0 :     else if( mpWindowImpl->mbFrame )
     985             :     {
     986           0 :         mpWindowImpl->maWinRegion = vcl::Region(true);
     987           0 :         mpWindowImpl->mbWinRegion = false;
     988           0 :         mpWindowImpl->mpFrame->ResetClipRegion();
     989             :     }
     990             :     else
     991             :     {
     992           0 :         if ( mpWindowImpl->mbWinRegion )
     993             :         {
     994           0 :             mpWindowImpl->maWinRegion = vcl::Region(true);
     995           0 :             mpWindowImpl->mbWinRegion = false;
     996           0 :             ImplSetClipFlag();
     997             : 
     998           0 :             if ( IsReallyVisible() )
     999             :             {
    1000             :                 // restore background storage
    1001           0 :                 if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
    1002           0 :                     ImplDeleteOverlapBackground();
    1003           0 :                 if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
    1004           0 :                     ImplInvalidateAllOverlapBackgrounds();
    1005           0 :                 Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
    1006           0 :                 vcl::Region      aRegion( aRect );
    1007           0 :                 ImplInvalidateParentFrameRegion( aRegion );
    1008             :             }
    1009             :         }
    1010             :     }
    1011           0 : }
    1012             : 
    1013           0 : void Window::SetWindowRegionPixel( const vcl::Region& rRegion )
    1014             : {
    1015             : 
    1016           0 :     if ( mpWindowImpl->mpBorderWindow )
    1017           0 :         mpWindowImpl->mpBorderWindow->SetWindowRegionPixel( rRegion );
    1018           0 :     else if( mpWindowImpl->mbFrame )
    1019             :     {
    1020           0 :         if( !rRegion.IsNull() )
    1021             :         {
    1022           0 :             mpWindowImpl->maWinRegion = rRegion;
    1023           0 :             mpWindowImpl->mbWinRegion = ! rRegion.IsEmpty();
    1024             : 
    1025           0 :             if( mpWindowImpl->mbWinRegion )
    1026             :             {
    1027             :                 // set/update ClipRegion
    1028           0 :                 RectangleVector aRectangles;
    1029           0 :                 mpWindowImpl->maWinRegion.GetRegionRectangles(aRectangles);
    1030           0 :                 mpWindowImpl->mpFrame->BeginSetClipRegion(aRectangles.size());
    1031             : 
    1032           0 :                 for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
    1033             :                 {
    1034             :                     mpWindowImpl->mpFrame->UnionClipRegion(
    1035             :                         aRectIter->Left(),
    1036             :                         aRectIter->Top(),
    1037             :                         aRectIter->GetWidth(),       // orig nWidth was ((R - L) + 1), same as GetWidth does
    1038           0 :                         aRectIter->GetHeight());     // same for height
    1039             :                 }
    1040             : 
    1041           0 :                 mpWindowImpl->mpFrame->EndSetClipRegion();
    1042             : 
    1043             :                 //long                nX;
    1044             :                 //long                nY;
    1045             :                 //long                nWidth;
    1046             :                 //long                nHeight;
    1047             :                 //sal_uLong               nRectCount;
    1048             :                 //ImplRegionInfo      aInfo;
    1049             :                 //sal_Bool                bRegionRect;
    1050             : 
    1051             :                 //nRectCount = mpWindowImpl->maWinRegion.GetRectCount();
    1052             :                 //mpWindowImpl->mpFrame->BeginSetClipRegion( nRectCount );
    1053             :                 //bRegionRect = mpWindowImpl->maWinRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
    1054             :                 //while ( bRegionRect )
    1055             :                 //{
    1056             :                 //    mpWindowImpl->mpFrame->UnionClipRegion( nX, nY, nWidth, nHeight );
    1057             :                 //    bRegionRect = mpWindowImpl->maWinRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
    1058             :                 //}
    1059             :                 //mpWindowImpl->mpFrame->EndSetClipRegion();
    1060             :             }
    1061             :             else
    1062           0 :                 SetWindowRegionPixel();
    1063             :         }
    1064             :         else
    1065           0 :             SetWindowRegionPixel();
    1066             :     }
    1067             :     else
    1068             :     {
    1069           0 :         if ( rRegion.IsNull() )
    1070             :         {
    1071           0 :             if ( mpWindowImpl->mbWinRegion )
    1072             :             {
    1073           0 :                 mpWindowImpl->maWinRegion = vcl::Region(true);
    1074           0 :                 mpWindowImpl->mbWinRegion = false;
    1075           0 :                 ImplSetClipFlag();
    1076             :             }
    1077             :         }
    1078             :         else
    1079             :         {
    1080           0 :             mpWindowImpl->maWinRegion = rRegion;
    1081           0 :             mpWindowImpl->mbWinRegion = true;
    1082           0 :             ImplSetClipFlag();
    1083             :         }
    1084             : 
    1085           0 :         if ( IsReallyVisible() )
    1086             :         {
    1087             :             // restore background storage
    1088           0 :             if ( mpWindowImpl->mpOverlapData && mpWindowImpl->mpOverlapData->mpSaveBackDev )
    1089           0 :                 ImplDeleteOverlapBackground();
    1090           0 :             if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
    1091           0 :                 ImplInvalidateAllOverlapBackgrounds();
    1092           0 :             Rectangle   aRect( Point( mnOutOffX, mnOutOffY ), Size( mnOutWidth, mnOutHeight ) );
    1093           0 :             vcl::Region      aRegion( aRect );
    1094           0 :             ImplInvalidateParentFrameRegion( aRegion );
    1095             :         }
    1096             :     }
    1097           0 : }
    1098             : 
    1099           0 : const vcl::Region& Window::GetWindowRegionPixel() const
    1100             : {
    1101             : 
    1102           0 :     if ( mpWindowImpl->mpBorderWindow )
    1103           0 :         return mpWindowImpl->mpBorderWindow->GetWindowRegionPixel();
    1104             :     else
    1105           0 :         return mpWindowImpl->maWinRegion;
    1106             : }
    1107             : 
    1108           0 : bool Window::IsWindowRegionPixel() const
    1109             : {
    1110             : 
    1111           0 :     if ( mpWindowImpl->mpBorderWindow )
    1112           0 :         return mpWindowImpl->mpBorderWindow->IsWindowRegionPixel();
    1113             :     else
    1114           0 :         return mpWindowImpl->mbWinRegion;
    1115             : }
    1116             : 
    1117      107167 : vcl::Region Window::GetPaintRegion() const
    1118             : {
    1119             : 
    1120      107167 :     if ( mpWindowImpl->mpPaintRegion )
    1121             :     {
    1122      107167 :         vcl::Region aRegion = *mpWindowImpl->mpPaintRegion;
    1123      107167 :         aRegion.Move( -mnOutOffX, -mnOutOffY );
    1124      107167 :         return PixelToLogic( aRegion );
    1125             :     }
    1126             :     else
    1127             :     {
    1128           0 :         vcl::Region aPaintRegion(true);
    1129           0 :         return aPaintRegion;
    1130             :     }
    1131             : }
    1132             : 
    1133      428169 : void Window::Invalidate( InvalidateFlags nFlags )
    1134             : {
    1135      428169 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
    1136      718130 :         return;
    1137             : 
    1138      138208 :     ImplInvalidate( NULL, nFlags );
    1139      138208 :     LogicInvalidate(0);
    1140             : }
    1141             : 
    1142       93561 : void Window::Invalidate( const Rectangle& rRect, InvalidateFlags nFlags )
    1143             : {
    1144       93561 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
    1145      123490 :         return;
    1146             : 
    1147       63632 :     OutputDevice *pOutDev = GetOutDev();
    1148       63632 :     Rectangle aRect = pOutDev->ImplLogicToDevicePixel( rRect );
    1149       63632 :     if ( !aRect.IsEmpty() )
    1150             :     {
    1151       56262 :         vcl::Region aRegion( aRect );
    1152       56262 :         ImplInvalidate( &aRegion, nFlags );
    1153       56262 :         Rectangle aLogicRectangle(rRect);
    1154       56262 :         LogicInvalidate(&aLogicRectangle);
    1155             :     }
    1156             : }
    1157             : 
    1158         826 : void Window::Invalidate( const vcl::Region& rRegion, InvalidateFlags nFlags )
    1159             : {
    1160         826 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
    1161         826 :         return;
    1162             : 
    1163         826 :     if ( rRegion.IsNull() )
    1164             :     {
    1165           0 :         ImplInvalidate( NULL, nFlags );
    1166           0 :         LogicInvalidate(0);
    1167             :     }
    1168             :     else
    1169             :     {
    1170         826 :         vcl::Region aRegion = ImplPixelToDevicePixel( LogicToPixel( rRegion ) );
    1171         826 :         if ( !aRegion.IsEmpty() )
    1172             :         {
    1173         509 :             ImplInvalidate( &aRegion, nFlags );
    1174         509 :             Rectangle aLogicRectangle = rRegion.GetBoundRect();
    1175         509 :             LogicInvalidate(&aLogicRectangle);
    1176         826 :         }
    1177             :     }
    1178             : }
    1179             : 
    1180         228 : void Window::Validate( ValidateFlags nFlags )
    1181             : {
    1182             : 
    1183         228 :     if ( !IsDeviceOutputNecessary() || !mnOutWidth || !mnOutHeight )
    1184         228 :         return;
    1185             : 
    1186         228 :     ImplValidate( NULL, nFlags );
    1187         228 :     LogicInvalidate(0);
    1188             : }
    1189             : 
    1190       70065 : bool Window::HasPaintEvent() const
    1191             : {
    1192             : 
    1193       70065 :     if ( !mpWindowImpl->mbReallyVisible )
    1194       14136 :         return false;
    1195             : 
    1196       55929 :     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
    1197        2914 :         return true;
    1198             : 
    1199       53015 :     if ( mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINT )
    1200       21757 :         return true;
    1201             : 
    1202       31258 :     if ( !ImplIsOverlapWindow() )
    1203             :     {
    1204       31258 :         const vcl::Window* pTempWindow = this;
    1205       10090 :         do
    1206             :         {
    1207       39832 :             pTempWindow = pTempWindow->ImplGetParent();
    1208       39832 :             if ( pTempWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINTCHILDREN | IMPL_PAINT_PAINTALLCHILDREN) )
    1209       29742 :                 return true;
    1210             :         }
    1211       10090 :         while ( !pTempWindow->ImplIsOverlapWindow() );
    1212             :     }
    1213             : 
    1214        1516 :     return false;
    1215             : }
    1216             : 
    1217       81687 : void Window::Update()
    1218             : {
    1219       81687 :     if ( mpWindowImpl->mpBorderWindow )
    1220             :     {
    1221          71 :         mpWindowImpl->mpBorderWindow->Update();
    1222          71 :         return;
    1223             :     }
    1224             : 
    1225       81616 :     if ( !mpWindowImpl->mbReallyVisible )
    1226       14113 :         return;
    1227             : 
    1228       67503 :     bool bFlush = false;
    1229       67503 :     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
    1230             :     {
    1231        4876 :         Point aPoint( 0, 0 );
    1232        4876 :         vcl::Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
    1233        4876 :         ImplInvalidateOverlapFrameRegion( aRegion );
    1234        4876 :         if ( mpWindowImpl->mbFrame || (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) )
    1235           0 :             bFlush = true;
    1236             :     }
    1237             : 
    1238             :     // First we should skip all windows which are Paint-Transparent
    1239       67503 :     vcl::Window* pUpdateWindow = this;
    1240       67503 :     vcl::Window* pWindow = pUpdateWindow;
    1241      135137 :     while ( !pWindow->ImplIsOverlapWindow() )
    1242             :     {
    1243       67634 :         if ( !pWindow->mpWindowImpl->mbPaintTransparent )
    1244             :         {
    1245       67503 :             pUpdateWindow = pWindow;
    1246       67503 :             break;
    1247             :         }
    1248         131 :         pWindow = pWindow->ImplGetParent();
    1249             :     }
    1250             :     // In order to limit drawing, an update only draws the window which
    1251             :     // has PAINTALLCHILDREN set
    1252       67503 :     pWindow = pUpdateWindow;
    1253      208974 :     do
    1254             :     {
    1255      276477 :         if ( pWindow->mpWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
    1256       49172 :             pUpdateWindow = pWindow;
    1257      276477 :         if ( pWindow->ImplIsOverlapWindow() )
    1258       67503 :             break;
    1259      208974 :         pWindow = pWindow->ImplGetParent();
    1260             :     }
    1261             :     while ( pWindow );
    1262             : 
    1263             :     // if there is something to paint, trigger a Paint
    1264       67503 :     if ( pUpdateWindow->mpWindowImpl->mnPaintFlags & (IMPL_PAINT_PAINT | IMPL_PAINT_PAINTCHILDREN) )
    1265             :     {
    1266       30452 :         ImplDelData aDogTag(this);
    1267             : 
    1268             :         // trigger an update also for system windows on top of us,
    1269             :         // otherwise holes would remain
    1270       30452 :          vcl::Window* pUpdateOverlapWindow = ImplGetFirstOverlapWindow()->mpWindowImpl->mpFirstOverlap;
    1271       60904 :          while ( pUpdateOverlapWindow )
    1272             :          {
    1273           0 :              pUpdateOverlapWindow->Update();
    1274           0 :              pUpdateOverlapWindow = pUpdateOverlapWindow->mpWindowImpl->mpNext;
    1275             :          }
    1276             : 
    1277       30452 :         pUpdateWindow->ImplCallPaint(NULL, NULL, pUpdateWindow->mpWindowImpl->mnPaintFlags);
    1278             : 
    1279       30452 :         if (aDogTag.IsDead())
    1280           0 :            return;
    1281       30452 :         bFlush = true;
    1282             :     }
    1283             : 
    1284       67503 :     if ( bFlush )
    1285       30452 :         Flush();
    1286             : }
    1287             : 
    1288       12783 : void Window::ImplPaintToDevice( OutputDevice* i_pTargetOutDev, const Point& i_rPos )
    1289             : {
    1290       12783 :     bool bRVisible = mpWindowImpl->mbReallyVisible;
    1291       12783 :     mpWindowImpl->mbReallyVisible = mpWindowImpl->mbVisible;
    1292       12783 :     bool bDevOutput = mbDevOutput;
    1293       12783 :     mbDevOutput = true;
    1294             : 
    1295       12783 :     const OutputDevice *pOutDev = GetOutDev();
    1296       12783 :     long nOldDPIX = pOutDev->GetDPIX();
    1297       12783 :     long nOldDPIY = pOutDev->GetDPIY();
    1298       12783 :     mnDPIX = i_pTargetOutDev->GetDPIX();
    1299       12783 :     mnDPIY = i_pTargetOutDev->GetDPIY();
    1300       12783 :     bool bOutput = IsOutputEnabled();
    1301       12783 :     EnableOutput();
    1302             : 
    1303             :     DBG_ASSERT( GetMapMode().GetMapUnit() == MAP_PIXEL, "MapMode must be PIXEL based" );
    1304       12783 :     if ( GetMapMode().GetMapUnit() != MAP_PIXEL )
    1305       12783 :         return;
    1306             : 
    1307             :     // preserve graphicsstate
    1308       12783 :     Push();
    1309       12783 :     vcl::Region aClipRegion( GetClipRegion() );
    1310       12783 :     SetClipRegion();
    1311             : 
    1312       12783 :     GDIMetaFile* pOldMtf = GetConnectMetaFile();
    1313       25566 :     GDIMetaFile aMtf;
    1314       12783 :     SetConnectMetaFile( &aMtf );
    1315             : 
    1316             :     // put a push action to metafile
    1317       12783 :     Push();
    1318             :     // copy graphics state to metafile
    1319       25566 :     vcl::Font aCopyFont = GetFont();
    1320       12783 :     if( nOldDPIX != mnDPIX || nOldDPIY != mnDPIY )
    1321             :     {
    1322           0 :         aCopyFont.SetHeight( aCopyFont.GetHeight() * mnDPIY / nOldDPIY );
    1323           0 :         aCopyFont.SetWidth( aCopyFont.GetWidth() * mnDPIX / nOldDPIX );
    1324             :     }
    1325       12783 :     SetFont( aCopyFont );
    1326       12783 :     SetTextColor( GetTextColor() );
    1327       12783 :     if( IsLineColor() )
    1328       12410 :         SetLineColor( GetLineColor() );
    1329             :     else
    1330         373 :         SetLineColor();
    1331       12783 :     if( IsFillColor() )
    1332       12782 :         SetFillColor( GetFillColor() );
    1333             :     else
    1334           1 :         SetFillColor();
    1335       12783 :     if( IsTextLineColor() )
    1336           0 :         SetTextLineColor( GetTextLineColor() );
    1337             :     else
    1338       12783 :         SetTextLineColor();
    1339       12783 :     if( IsOverlineColor() )
    1340           0 :         SetOverlineColor( GetOverlineColor() );
    1341             :     else
    1342       12783 :         SetOverlineColor();
    1343       12783 :     if( IsTextFillColor() )
    1344         220 :         SetTextFillColor( GetTextFillColor() );
    1345             :     else
    1346       12563 :         SetTextFillColor();
    1347       12783 :     SetTextAlign( GetTextAlign() );
    1348       12783 :     SetRasterOp( GetRasterOp() );
    1349       12783 :     if( IsRefPoint() )
    1350           0 :         SetRefPoint( GetRefPoint() );
    1351             :     else
    1352       12783 :         SetRefPoint();
    1353       12783 :     SetLayoutMode( GetLayoutMode() );
    1354       12783 :     SetDigitLanguage( GetDigitLanguage() );
    1355       12783 :     Rectangle aPaintRect( Point( 0, 0 ), GetOutputSizePixel() );
    1356       12783 :     aClipRegion.Intersect( aPaintRect );
    1357       12783 :     SetClipRegion( aClipRegion );
    1358             : 
    1359             :     // do the actual paint
    1360             : 
    1361             :     // background
    1362       12783 :     if( ! IsPaintTransparent() && IsBackground() && ! (GetParentClipMode() & ParentClipMode::NoClip ) )
    1363        5891 :         Erase(*this);
    1364             :     // foreground
    1365       12783 :     Paint(*this, aPaintRect);
    1366             :     // put a pop action to metafile
    1367       12783 :     Pop();
    1368             : 
    1369       12783 :     SetConnectMetaFile( pOldMtf );
    1370       12783 :     EnableOutput( bOutput );
    1371       12783 :     mpWindowImpl->mbReallyVisible = bRVisible;
    1372             : 
    1373             :     // paint metafile to VDev
    1374       25566 :     VclPtrInstance<VirtualDevice> pMaskedDevice( *i_pTargetOutDev, 0, 0 );
    1375       12783 :     pMaskedDevice->SetOutputSizePixel( GetOutputSizePixel() );
    1376       12783 :     pMaskedDevice->EnableRTL( IsRTLEnabled() );
    1377       12783 :     aMtf.WindStart();
    1378       12783 :     aMtf.Play( pMaskedDevice );
    1379       25566 :     BitmapEx aBmpEx( pMaskedDevice->GetBitmapEx( Point( 0, 0 ), pMaskedDevice->GetOutputSizePixel() ) );
    1380       12783 :     i_pTargetOutDev->DrawBitmapEx( i_rPos, aBmpEx );
    1381             :     // get rid of virtual device now so they don't pile up during recursive calls
    1382       12783 :     pMaskedDevice.disposeAndClear();
    1383             : 
    1384       22500 :     for( vcl::Window* pChild = mpWindowImpl->mpFirstChild; pChild; pChild = pChild->mpWindowImpl->mpNext )
    1385             :     {
    1386        9717 :         if( pChild->mpWindowImpl->mpFrame == mpWindowImpl->mpFrame && pChild->IsVisible() )
    1387             :         {
    1388        8321 :             long nDeltaX = pChild->mnOutOffX - mnOutOffX;
    1389             : 
    1390        8321 :             if( pOutDev->HasMirroredGraphics() )
    1391           0 :                 nDeltaX = mnOutWidth - nDeltaX - pChild->mnOutWidth;
    1392        8321 :             long nDeltaY = pChild->GetOutOffYPixel() - GetOutOffYPixel();
    1393        8321 :             Point aPos( i_rPos );
    1394        8321 :             Point aDelta( nDeltaX, nDeltaY );
    1395        8321 :             aPos += aDelta;
    1396        8321 :             pChild->ImplPaintToDevice( i_pTargetOutDev, aPos );
    1397             :         }
    1398             :     }
    1399             : 
    1400             :     // restore graphics state
    1401       12783 :     Pop();
    1402             : 
    1403       12783 :     EnableOutput( bOutput );
    1404       12783 :     mpWindowImpl->mbReallyVisible = bRVisible;
    1405       12783 :     mbDevOutput = bDevOutput;
    1406       12783 :     mnDPIX = nOldDPIX;
    1407       25566 :     mnDPIY = nOldDPIY;
    1408             : }
    1409             : 
    1410        4462 : void Window::PaintToDevice( OutputDevice* pDev, const Point& rPos, const Size& /*rSize*/ )
    1411             : {
    1412             :     // FIXME: scaling: currently this is for pixel copying only
    1413             : 
    1414             :     DBG_ASSERT( ! pDev->HasMirroredGraphics(), "PaintToDevice to mirroring graphics" );
    1415             :     DBG_ASSERT( ! pDev->IsRTLEnabled(), "PaintToDevice to mirroring device" );
    1416             : 
    1417        4462 :     vcl::Window* pRealParent = NULL;
    1418        4462 :     if( ! mpWindowImpl->mbVisible )
    1419             :     {
    1420        4462 :         vcl::Window* pTempParent = ImplGetDefaultWindow();
    1421        4462 :         if( pTempParent )
    1422        4462 :             pTempParent->EnableChildTransparentMode();
    1423        4462 :         pRealParent = GetParent();
    1424        4462 :         SetParent( pTempParent );
    1425             :         // trigger correct visibility flags for children
    1426        4462 :         Show();
    1427        4462 :         Hide();
    1428             :     }
    1429             : 
    1430        4462 :     bool bVisible = mpWindowImpl->mbVisible;
    1431        4462 :     mpWindowImpl->mbVisible = true;
    1432             : 
    1433        4462 :     if( mpWindowImpl->mpBorderWindow )
    1434        3235 :         mpWindowImpl->mpBorderWindow->ImplPaintToDevice( pDev, rPos );
    1435             :     else
    1436        1227 :         ImplPaintToDevice( pDev, rPos );
    1437             : 
    1438        4462 :     mpWindowImpl->mbVisible = bVisible;
    1439             : 
    1440        4462 :     if( pRealParent )
    1441        4462 :         SetParent( pRealParent );
    1442        4462 : }
    1443             : 
    1444       98794 : void Window::Erase(vcl::RenderContext& rRenderContext)
    1445             : {
    1446       98794 :     if (!IsDeviceOutputNecessary() || ImplIsRecordLayout())
    1447       98794 :         return;
    1448             : 
    1449       98794 :     bool bNativeOK = false;
    1450             : 
    1451       98794 :     ControlPart aCtrlPart = ImplGetWindowImpl()->mnNativeBackground;
    1452       98794 :     if (aCtrlPart != 0 && ! IsControlBackground())
    1453             :     {
    1454           0 :         Rectangle aCtrlRegion(Point(), rRenderContext.GetOutputSizePixel());
    1455           0 :         ControlState nState = ControlState::NONE;
    1456             : 
    1457           0 :         if (IsEnabled())
    1458           0 :             nState |= ControlState::ENABLED;
    1459             : 
    1460             :         bNativeOK = rRenderContext.DrawNativeControl(CTRL_WINDOW_BACKGROUND, aCtrlPart, aCtrlRegion,
    1461           0 :                                                      nState, ImplControlValue(), OUString());
    1462             :     }
    1463             : 
    1464       98794 :     if (mbBackground && !bNativeOK)
    1465             :     {
    1466       98794 :         RasterOp eRasterOp = GetRasterOp();
    1467       98794 :         if (eRasterOp != ROP_OVERPAINT)
    1468           0 :             SetRasterOp(ROP_OVERPAINT);
    1469       98794 :         rRenderContext.DrawWallpaper(0, 0, mnOutWidth, mnOutHeight, maBackground);
    1470       98794 :         if (eRasterOp != ROP_OVERPAINT)
    1471           0 :             rRenderContext.SetRasterOp(eRasterOp);
    1472             :     }
    1473             : 
    1474       98794 :     if (mpAlphaVDev)
    1475           0 :         mpAlphaVDev->Erase();
    1476             : }
    1477             : 
    1478        4777 : void Window::ImplScroll( const Rectangle& rRect,
    1479             :                          long nHorzScroll, long nVertScroll, ScrollFlags nFlags )
    1480             : {
    1481        4777 :     if ( !IsDeviceOutputNecessary() )
    1482        8478 :         return;
    1483             : 
    1484         627 :     nHorzScroll = ImplLogicWidthToDevicePixel( nHorzScroll );
    1485         627 :     nVertScroll = ImplLogicHeightToDevicePixel( nVertScroll );
    1486             : 
    1487         627 :     if ( !nHorzScroll && !nVertScroll )
    1488         178 :         return;
    1489             : 
    1490             :     // restore background storage
    1491         449 :     if ( mpWindowImpl->mpFrameData->mpFirstBackWin )
    1492           0 :         ImplInvalidateAllOverlapBackgrounds();
    1493             : 
    1494         449 :     if ( mpWindowImpl->mpCursor )
    1495         228 :         mpWindowImpl->mpCursor->ImplSuspend();
    1496             : 
    1497         449 :     ScrollFlags nOrgFlags = nFlags;
    1498         449 :     if ( !(nFlags & (ScrollFlags::Children | ScrollFlags::NoChildren)) )
    1499             :     {
    1500         111 :         if ( GetStyle() & WB_CLIPCHILDREN )
    1501           3 :             nFlags |= ScrollFlags::NoChildren;
    1502             :         else
    1503         108 :             nFlags |= ScrollFlags::Children;
    1504             :     }
    1505             : 
    1506         449 :     vcl::Region  aInvalidateRegion;
    1507         449 :     bool    bScrollChildren(nFlags & ScrollFlags::Children);
    1508         449 :     bool    bErase(!(nFlags & ScrollFlags::NoErase));
    1509             : 
    1510         449 :     if ( !mpWindowImpl->mpFirstChild )
    1511         394 :         bScrollChildren = false;
    1512             : 
    1513         449 :     OutputDevice *pOutDev = GetOutDev();
    1514             : 
    1515             :     // --- RTL --- check if this window requires special action
    1516         449 :     bool bReMirror = ( ImplIsAntiparallel() );
    1517             : 
    1518         449 :     Rectangle aRectMirror( rRect );
    1519         449 :     if( bReMirror )
    1520             :     {
    1521             :         // --- RTL --- make sure the invalidate region of this window is
    1522             :         // computed in the same coordinate space as the one from the overlap windows
    1523           0 :         pOutDev->ReMirror( aRectMirror );
    1524             :     }
    1525             : 
    1526             :     // adapt paint areas
    1527         449 :     ImplMoveAllInvalidateRegions( aRectMirror, nHorzScroll, nVertScroll, bScrollChildren );
    1528             : 
    1529         449 :     if ( !(nFlags & ScrollFlags::NoInvalidate) )
    1530             :     {
    1531         449 :         ImplCalcOverlapRegion( aRectMirror, aInvalidateRegion, !bScrollChildren, true, false );
    1532             : 
    1533             :         // --- RTL ---
    1534             :         // if the scrolling on the device is performed in the opposite direction
    1535             :         // then move the overlaps in that direction to compute the invalidate region
    1536             :         // on the correct side, i.e., revert nHorzScroll
    1537             : 
    1538         449 :         if ( !aInvalidateRegion.IsEmpty() )
    1539             :         {
    1540          22 :             aInvalidateRegion.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
    1541          22 :             bErase = true;
    1542             :         }
    1543         449 :         if ( !(nFlags & ScrollFlags::NoWindowInvalidate) )
    1544             :         {
    1545         449 :             Rectangle aDestRect( aRectMirror );
    1546         449 :             aDestRect.Move( bReMirror ? -nHorzScroll : nHorzScroll, nVertScroll );
    1547         449 :             vcl::Region aWinInvalidateRegion( aRectMirror );
    1548         449 :             aWinInvalidateRegion.Exclude( aDestRect );
    1549             : 
    1550         449 :             aInvalidateRegion.Union( aWinInvalidateRegion );
    1551             :         }
    1552             :     }
    1553             : 
    1554         449 :     Point aPoint( mnOutOffX, mnOutOffY );
    1555         898 :     vcl::Region aRegion( Rectangle( aPoint, Size( mnOutWidth, mnOutHeight ) ) );
    1556         449 :     if ( nFlags & ScrollFlags::Clip )
    1557           0 :         aRegion.Intersect( rRect );
    1558         449 :     if ( mpWindowImpl->mbWinRegion )
    1559           0 :         aRegion.Intersect( ImplPixelToDevicePixel( mpWindowImpl->maWinRegion ) );
    1560             : 
    1561         449 :     aRegion.Exclude( aInvalidateRegion );
    1562             : 
    1563         449 :     ImplClipBoundaries( aRegion, false, true );
    1564         449 :     if ( !bScrollChildren )
    1565             :     {
    1566         397 :         if ( nOrgFlags & ScrollFlags::NoChildren )
    1567           0 :             ImplClipAllChildren( aRegion );
    1568             :         else
    1569         397 :             ImplClipChildren( aRegion );
    1570             :     }
    1571         449 :     if ( mbClipRegion && (nFlags & ScrollFlags::UseClipRegion) )
    1572           0 :         aRegion.Intersect( maRegion );
    1573         449 :     if ( !aRegion.IsEmpty() )
    1574             :     {
    1575         300 :         if ( mpWindowImpl->mpWinData )
    1576             :         {
    1577           0 :             if ( mpWindowImpl->mbFocusVisible )
    1578           0 :                 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
    1579           0 :             if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
    1580           0 :                 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
    1581             :         }
    1582             : #ifndef IOS
    1583             :         // This seems completely unnecessary with tiled rendering, and
    1584             :         // causes the "AquaSalGraphics::copyArea() for non-layered
    1585             :         // graphics" message. Presumably we should bypass this on all
    1586             :         // platforms when dealing with a "window" that uses tiled
    1587             :         // rendering at the moment. Unclear how to figure that out,
    1588             :         // though. Also unclear whether we actually could just not
    1589             :         // create a "frame window", whatever that exactly is, in the
    1590             :         // tiled rendering case, or at least for platforms where tiles
    1591             :         // rendering is all there is.
    1592             : 
    1593         300 :         SalGraphics* pGraphics = ImplGetFrameGraphics();
    1594         300 :         if ( pGraphics )
    1595             :         {
    1596         300 :             if( bReMirror )
    1597             :             {
    1598             :                 // --- RTL --- frame coordinates require re-mirroring
    1599           0 :                 pOutDev->ReMirror( aRegion );
    1600             :             }
    1601             : 
    1602         300 :             pOutDev->SelectClipRegion( aRegion, pGraphics );
    1603         600 :             pGraphics->CopyArea( rRect.Left()+nHorzScroll, rRect.Top()+nVertScroll,
    1604             :                                  rRect.Left(), rRect.Top(),
    1605             :                                  rRect.GetWidth(), rRect.GetHeight(),
    1606         900 :                                  SAL_COPYAREA_WINDOWINVALIDATE, this );
    1607             :         }
    1608             : #endif
    1609         300 :         if ( mpWindowImpl->mpWinData )
    1610             :         {
    1611           0 :             if ( mpWindowImpl->mbFocusVisible )
    1612           0 :                 ImplInvertFocus( *(mpWindowImpl->mpWinData->mpFocusRect) );
    1613           0 :             if ( mpWindowImpl->mbTrackVisible && (mpWindowImpl->mpWinData->mnTrackFlags & SHOWTRACK_WINDOW) )
    1614           0 :                 InvertTracking( *(mpWindowImpl->mpWinData->mpTrackRect), mpWindowImpl->mpWinData->mnTrackFlags );
    1615             :         }
    1616             :     }
    1617             : 
    1618         449 :     if ( !aInvalidateRegion.IsEmpty() )
    1619             :     {
    1620             :         // --- RTL --- the invalidate region for this windows is already computed in frame coordinates
    1621             :         // so it has to be re-mirrored before calling the Paint-handler
    1622         449 :         mpWindowImpl->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
    1623             : 
    1624         449 :         InvalidateFlags nPaintFlags = InvalidateFlags::Children;
    1625         449 :         if ( !bErase )
    1626           0 :             nPaintFlags |= InvalidateFlags::NoErase;
    1627         449 :         if ( !bScrollChildren )
    1628             :         {
    1629         397 :             if ( nOrgFlags & ScrollFlags::NoChildren )
    1630           0 :                 ImplClipAllChildren( aInvalidateRegion );
    1631             :             else
    1632         397 :                 ImplClipChildren( aInvalidateRegion );
    1633             :         }
    1634         449 :         ImplInvalidateFrameRegion( &aInvalidateRegion, nPaintFlags );
    1635             :     }
    1636             : 
    1637         449 :     if ( bScrollChildren )
    1638             :     {
    1639          52 :         vcl::Window* pWindow = mpWindowImpl->mpFirstChild;
    1640         159 :         while ( pWindow )
    1641             :         {
    1642          55 :             Point aPos = pWindow->GetPosPixel();
    1643          55 :             aPos += Point( nHorzScroll, nVertScroll );
    1644          55 :             pWindow->SetPosPixel( aPos );
    1645             : 
    1646          55 :             pWindow = pWindow->mpWindowImpl->mpNext;
    1647             :         }
    1648             :     }
    1649             : 
    1650         449 :     if ( nFlags & ScrollFlags::Update )
    1651           0 :         Update();
    1652             : 
    1653         449 :     if ( mpWindowImpl->mpCursor )
    1654         677 :         mpWindowImpl->mpCursor->ImplResume();
    1655             : }
    1656             : 
    1657         801 : } /* namespace vcl */
    1658             : 
    1659             : 
    1660             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11