LCOV - code coverage report
Current view: top level - svx/source/svdraw - sdrpaintwindow.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 123 135 91.1 %
Date: 2014-11-03 Functions: 21 23 91.3 %
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 <comphelper/random.hxx>
      21             : #include <svx/sdrpaintwindow.hxx>
      22             : #include <sdr/overlay/overlaymanagerbuffered.hxx>
      23             : #include <svx/svdpntv.hxx>
      24             : #include <vcl/gdimtf.hxx>
      25             : #include <vcl/svapp.hxx>
      26             : #include <vcl/settings.hxx>
      27             : #include <set>
      28             : #include <vector>
      29             : 
      30             : //rhbz#1007697 do this in two loops, one to collect the candidates
      31             : //and another to update them because updating a candidate can
      32             : //trigger the candidate to be deleted, so asking for its
      33             : //sibling after that is going to fail hard
      34       10396 : class CandidateMgr
      35             : {
      36             :     std::vector<vcl::Window*> m_aCandidates;
      37             :     std::set<vcl::Window*> m_aDeletedCandidates;
      38             :     DECL_LINK(WindowEventListener, VclSimpleEvent*);
      39             : public:
      40             :     void PaintTransparentChildren(vcl::Window & rWindow, Rectangle const& rPixelRect);
      41             :     ~CandidateMgr();
      42             : };
      43             : 
      44           0 : IMPL_LINK(CandidateMgr, WindowEventListener, VclSimpleEvent*, pEvent)
      45             : {
      46           0 :     VclWindowEvent* pWinEvent = dynamic_cast< VclWindowEvent* >( pEvent );
      47           0 :     if (pWinEvent)
      48             :     {
      49           0 :         vcl::Window* pWindow = pWinEvent->GetWindow();
      50           0 :         if (pWinEvent->GetId() == VCLEVENT_OBJECT_DYING)
      51             :         {
      52           0 :             m_aDeletedCandidates.insert(pWindow);
      53             :         }
      54             :     }
      55             : 
      56           0 :     return 0;
      57             : }
      58             : 
      59       20792 : CandidateMgr::~CandidateMgr()
      60             : {
      61       31890 :     for (std::vector<vcl::Window*>::iterator aI = m_aCandidates.begin();
      62       21260 :          aI != m_aCandidates.end(); ++aI)
      63             :     {
      64         234 :         vcl::Window* pCandidate = *aI;
      65         234 :         if (m_aDeletedCandidates.find(pCandidate) != m_aDeletedCandidates.end())
      66           0 :             continue;
      67         234 :         pCandidate->RemoveEventListener(LINK(this, CandidateMgr, WindowEventListener));
      68             :     }
      69       10396 : }
      70             : 
      71       10396 : void PaintTransparentChildren(vcl::Window & rWindow, Rectangle const& rPixelRect)
      72             : {
      73       10396 :     if (!rWindow.IsChildTransparentModeEnabled())
      74       10396 :         return;
      75             : 
      76       10396 :     CandidateMgr aManager;
      77       10396 :     aManager.PaintTransparentChildren(rWindow, rPixelRect);
      78             : }
      79             : 
      80       10396 : void CandidateMgr::PaintTransparentChildren(vcl::Window & rWindow, Rectangle const& rPixelRect)
      81             : {
      82       10396 :     vcl::Window * pCandidate = rWindow.GetWindow( WINDOW_FIRSTCHILD );
      83       23505 :     while (pCandidate)
      84             :     {
      85        2713 :         if (pCandidate->IsPaintTransparent())
      86             :         {
      87             :             const Rectangle aCandidatePosSizePixel(
      88         716 :                             pCandidate->GetPosPixel(),
      89        1432 :                             pCandidate->GetSizePixel());
      90             : 
      91         716 :             if (aCandidatePosSizePixel.IsOver(rPixelRect))
      92             :             {
      93         234 :                 m_aCandidates.push_back(pCandidate);
      94         234 :                 pCandidate->AddEventListener(LINK(this, CandidateMgr, WindowEventListener));
      95             :             }
      96             :         }
      97        2713 :         pCandidate = pCandidate->GetWindow( WINDOW_NEXT );
      98             :     }
      99             : 
     100       31890 :     for (std::vector<vcl::Window*>::iterator aI = m_aCandidates.begin();
     101       21260 :          aI != m_aCandidates.end(); ++aI)
     102             :     {
     103         234 :         pCandidate = *aI;
     104         234 :         if (m_aDeletedCandidates.find(pCandidate) != m_aDeletedCandidates.end())
     105           0 :             continue;
     106             :         //rhbz#1007697 this can cause the window itself to be
     107             :         //deleted. So we are listening to see if that happens
     108             :         //and if so, then skip the update
     109         234 :         pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN);
     110             :         // important: actually paint the child here!
     111         234 :         if (m_aDeletedCandidates.find(pCandidate) != m_aDeletedCandidates.end())
     112           0 :             continue;
     113         234 :         pCandidate->Update();
     114             :     }
     115       10396 : }
     116             : 
     117        1903 : SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal)
     118        1903 : :   mrOutputDevice(rOriginal)
     119             : {
     120        1903 : }
     121             : 
     122        1876 : SdrPreRenderDevice::~SdrPreRenderDevice()
     123             : {
     124        1876 : }
     125             : 
     126       14411 : void SdrPreRenderDevice::PreparePreRenderDevice()
     127             : {
     128             :     // compare size of maPreRenderDevice with size of visible area
     129       14411 :     if(maPreRenderDevice.GetOutputSizePixel() != mrOutputDevice.GetOutputSizePixel())
     130             :     {
     131        2109 :         maPreRenderDevice.SetOutputSizePixel(mrOutputDevice.GetOutputSizePixel());
     132             :     }
     133             : 
     134             :     // Also compare the MapModes for zoom/scroll changes
     135       14411 :     if(maPreRenderDevice.GetMapMode() != mrOutputDevice.GetMapMode())
     136             :     {
     137        4475 :         maPreRenderDevice.SetMapMode(mrOutputDevice.GetMapMode());
     138             :     }
     139             : 
     140             :     // #i29186#
     141       14411 :     maPreRenderDevice.SetDrawMode(mrOutputDevice.GetDrawMode());
     142       14411 :     maPreRenderDevice.SetSettings(mrOutputDevice.GetSettings());
     143       14411 : }
     144             : 
     145       14411 : void SdrPreRenderDevice::OutputPreRenderDevice(const vcl::Region& rExpandedRegion)
     146             : {
     147             :     // region to pixels
     148       14411 :     const vcl::Region aRegionPixel(mrOutputDevice.LogicToPixel(rExpandedRegion));
     149             :     //RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
     150             :     //Rectangle aRegionRectanglePixel;
     151             : 
     152             :     // MapModes off
     153       14411 :     bool bMapModeWasEnabledDest(mrOutputDevice.IsMapModeEnabled());
     154       14411 :     bool bMapModeWasEnabledSource(maPreRenderDevice.IsMapModeEnabled());
     155       14411 :     mrOutputDevice.EnableMapMode(false);
     156       14411 :     maPreRenderDevice.EnableMapMode(false);
     157             : 
     158       28822 :     RectangleVector aRectangles;
     159       14411 :     aRegionPixel.GetRegionRectangles(aRectangles);
     160             : 
     161       29603 :     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     162             :     {
     163             :         // for each rectangle, copy the area
     164       15192 :         const Point aTopLeft(aRectIter->TopLeft());
     165       15192 :         const Size aSize(aRectIter->GetSize());
     166             : 
     167             :         mrOutputDevice.DrawOutDev(
     168             :             aTopLeft, aSize,
     169             :             aTopLeft, aSize,
     170       15192 :             maPreRenderDevice);
     171             : 
     172             : #ifdef DBG_UTIL
     173             :         // #i74769#
     174             :         static bool bDoPaintForVisualControlRegion(false);
     175             : 
     176             :         if(bDoPaintForVisualControlRegion)
     177             :         {
     178             :             int nR = comphelper::rng::uniform_int_distribution(0, 0x7F-1);
     179             :             int nG = comphelper::rng::uniform_int_distribution(0, 0x7F-1);
     180             :             int nB = comphelper::rng::uniform_int_distribution(0, 0x7F-1);
     181             :             const Color aColor(((((nR|0x80)<<8L)|(nG|0x80))<<8L)|(nB|0x80));
     182             : 
     183             :             mrOutputDevice.SetLineColor(aColor);
     184             :             mrOutputDevice.SetFillColor();
     185             :             mrOutputDevice.DrawRect(*aRectIter);
     186             :         }
     187             : #endif
     188             :     }
     189             : 
     190       14411 :     mrOutputDevice.EnableMapMode(bMapModeWasEnabledDest);
     191       28822 :     maPreRenderDevice.EnableMapMode(bMapModeWasEnabledSource);
     192       14411 : }
     193             : 
     194             : 
     195             : 
     196       16050 : void SdrPaintWindow::impCreateOverlayManager()
     197             : {
     198             :     // not yet one created?
     199       16050 :     if(!mxOverlayManager.is())
     200             :     {
     201             :         // is it a window?
     202        3180 :         if(OUTDEV_WINDOW == GetOutputDevice().GetOutDevType())
     203             :         {
     204             :             // decide which OverlayManager to use
     205        2255 :             if(GetPaintView().IsBufferedOverlayAllowed() && mbUseBuffer)
     206             :             {
     207             :                 // buffered OverlayManager, buffers its background and refreshes from there
     208             :                 // for pure overlay changes (no system redraw). The 3rd parameter specifies
     209             :                 // whether that refresh itself will use a 2nd vdev to avoid flickering.
     210             :                 // Also hand over the old OverlayManager if existent; this means to take over
     211             :                 // the registered OverlayObjects from it
     212        2237 :                 mxOverlayManager = ::sdr::overlay::OverlayManagerBuffered::create(GetOutputDevice(), true);
     213             :             }
     214             :             else
     215             :             {
     216             :                 // unbuffered OverlayManager, just invalidates places where changes
     217             :                 // take place
     218             :                 // Also hand over the old OverlayManager if existent; this means to take over
     219             :                 // the registered OverlayObjects from it
     220          18 :                 mxOverlayManager = ::sdr::overlay::OverlayManager::create(GetOutputDevice());
     221             :             }
     222             : 
     223             :             OSL_ENSURE(mxOverlayManager.is(), "SdrPaintWindow::SdrPaintWindow: Could not allocate an overlayManager (!)");
     224             : 
     225             :             // Request a repaint so that the buffered overlay manager fills
     226             :             // its buffer properly.  This is a workaround for missing buffer
     227             :             // updates.
     228        2255 :             vcl::Window* pWindow = dynamic_cast<vcl::Window*>(&GetOutputDevice());
     229        2255 :             if (pWindow != NULL)
     230        2255 :                 pWindow->Invalidate();
     231             : 
     232        2255 :             Color aColA(GetPaintView().getOptionsDrawinglayer().GetStripeColorA());
     233        2255 :             Color aColB(GetPaintView().getOptionsDrawinglayer().GetStripeColorB());
     234             : 
     235        2255 :             if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
     236             :             {
     237           0 :                 aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor();
     238           0 :                 aColB.Invert();
     239             :             }
     240             : 
     241        2255 :             mxOverlayManager->setStripeColorA(aColA);
     242        2255 :             mxOverlayManager->setStripeColorB(aColB);
     243        2255 :             mxOverlayManager->setStripeLengthPixel(GetPaintView().getOptionsDrawinglayer().GetStripeLength());
     244             :         }
     245             :     }
     246       16050 : }
     247             : 
     248       48677 : SdrPaintWindow::SdrPaintWindow(SdrPaintView& rNewPaintView, OutputDevice& rOut)
     249             : :   mrOutputDevice(rOut),
     250             :     mrPaintView(rNewPaintView),
     251             :     mpPreRenderDevice(0L),
     252             :     mbTemporaryTarget(false), // #i72889#
     253       48677 :     mbUseBuffer(true)
     254             : {
     255       48677 : }
     256             : 
     257       97286 : SdrPaintWindow::~SdrPaintWindow()
     258             : {
     259       48643 :     mxOverlayManager.clear();
     260             : 
     261       48643 :     DestroyPreRenderDevice();
     262       48643 : }
     263             : 
     264        8718 : rtl::Reference< ::sdr::overlay::OverlayManager > SdrPaintWindow::GetOverlayManager() const
     265             : {
     266        8718 :     if(!mxOverlayManager.is())
     267             :     {
     268             :         // Create buffered overlay manager by default.
     269         648 :         const_cast< SdrPaintWindow* >(this)->impCreateOverlayManager();
     270             :     }
     271             : 
     272        8718 :     return mxOverlayManager;
     273             : }
     274             : 
     275        1076 : Rectangle SdrPaintWindow::GetVisibleArea() const
     276             : {
     277        1076 :     Size aVisSizePixel(GetOutputDevice().GetOutputSizePixel());
     278        1076 :     return Rectangle(GetOutputDevice().PixelToLogic(Rectangle(Point(0,0), aVisSizePixel)));
     279             : }
     280             : 
     281       14411 : bool SdrPaintWindow::OutputToRecordingMetaFile() const
     282             : {
     283       14411 :     GDIMetaFile* pMetaFile = mrOutputDevice.GetConnectMetaFile();
     284       14411 :     return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
     285             : }
     286             : 
     287       15402 : void SdrPaintWindow::PreparePreRenderDevice()
     288             : {
     289             :     const bool bPrepareBufferedOutput(
     290       15402 :         mrPaintView.IsBufferedOutputAllowed()
     291       15324 :         && !OutputToPrinter()
     292       15324 :         && !OutputToVirtualDevice()
     293       29813 :         && !OutputToRecordingMetaFile());
     294             : 
     295       15402 :     if(bPrepareBufferedOutput)
     296             :     {
     297       14411 :         if(!mpPreRenderDevice)
     298             :         {
     299        1903 :             mpPreRenderDevice = new SdrPreRenderDevice(mrOutputDevice);
     300             :         }
     301             :     }
     302             :     else
     303             :     {
     304         991 :         DestroyPreRenderDevice();
     305             :     }
     306             : 
     307       15402 :     if(mpPreRenderDevice)
     308             :     {
     309       14411 :         mpPreRenderDevice->PreparePreRenderDevice();
     310             :     }
     311       15402 : }
     312             : 
     313       49634 : void SdrPaintWindow::DestroyPreRenderDevice()
     314             : {
     315       49634 :     if(mpPreRenderDevice)
     316             :     {
     317        1876 :         delete mpPreRenderDevice;
     318        1876 :         mpPreRenderDevice = 0L;
     319             :     }
     320       49634 : }
     321             : 
     322       15402 : void SdrPaintWindow::OutputPreRenderDevice(const vcl::Region& rExpandedRegion)
     323             : {
     324       15402 :     if(mpPreRenderDevice)
     325             :     {
     326       14411 :         mpPreRenderDevice->OutputPreRenderDevice(rExpandedRegion);
     327             :     }
     328       15402 : }
     329             : 
     330             : // #i73602# add flag if buffer shall be used
     331       15402 : void SdrPaintWindow::DrawOverlay(const vcl::Region& rRegion)
     332             : {
     333             :     // ## force creation of OverlayManager since the first repaint needs to
     334             :     // save the background to get a controlled start into overlay mechanism
     335       15402 :     impCreateOverlayManager();
     336             : 
     337       15402 :     if(mxOverlayManager.is() && !OutputToPrinter())
     338             :     {
     339       14477 :         if(mpPreRenderDevice)
     340             :         {
     341       14411 :             mxOverlayManager->completeRedraw(rRegion, &mpPreRenderDevice->GetPreRenderDevice());
     342             :         }
     343             :         else
     344             :         {
     345          66 :             mxOverlayManager->completeRedraw(rRegion);
     346             :         }
     347             :     }
     348       15402 : }
     349             : 
     350             : 
     351       93339 : void SdrPaintWindow::SetRedrawRegion(const vcl::Region& rNew)
     352             : {
     353       93339 :     maRedrawRegion = rNew;
     354       93990 : }
     355             : 
     356             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10