LCOV - code coverage report
Current view: top level - sd/source/ui/slidesorter/view - SlsLayeredDevice.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 182 0.0 %
Date: 2014-04-14 Functions: 0 35 0.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             : 
      21             : #include "SlsLayeredDevice.hxx"
      22             : 
      23             : #include <vcl/window.hxx>
      24             : #include <vcl/virdev.hxx>
      25             : 
      26             : #include <boost/bind.hpp>
      27             : #include <boost/function.hpp>
      28             : 
      29             : #include <tools/gen.hxx>
      30             : 
      31             : namespace sd { namespace slidesorter { namespace view {
      32             : 
      33             : namespace {
      34             : static const sal_Int32 gnMaximumLayerCount = 8;
      35             : 
      36             : class LayerInvalidator : public ILayerInvalidator
      37             : {
      38             : public:
      39           0 :     LayerInvalidator (
      40             :         const ::boost::shared_ptr<LayeredDevice>& rpLayeredDevice,
      41             :         const SharedSdWindow& rpTargetWindow,
      42             :         const int nLayer)
      43             :         : mpLayeredDevice(rpLayeredDevice),
      44             :           mpTargetWindow(rpTargetWindow),
      45           0 :           mnLayer(nLayer)
      46             :     {
      47           0 :     }
      48             : 
      49           0 :     virtual ~LayerInvalidator ( )
      50           0 :     {
      51           0 :     }
      52             : 
      53           0 :     virtual void Invalidate (const Rectangle& rInvalidationBox) SAL_OVERRIDE
      54             :     {
      55           0 :         mpLayeredDevice->Invalidate(rInvalidationBox, mnLayer);
      56           0 :         mpTargetWindow->Invalidate(rInvalidationBox);
      57           0 :     }
      58             : 
      59             : private:
      60             :     const ::boost::shared_ptr<LayeredDevice> mpLayeredDevice;
      61             :     SharedSdWindow mpTargetWindow;
      62             :     const int mnLayer;
      63             : };
      64             : 
      65           0 : void DeviceCopy (
      66             :     OutputDevice& rTargetDevice,
      67             :     OutputDevice& rSourceDevice,
      68             :     const Rectangle& rBox)
      69             : {
      70             :     rTargetDevice.DrawOutDev(
      71             :         rBox.TopLeft(),
      72             :         rBox.GetSize(),
      73             :         rBox.TopLeft(),
      74             :         rBox.GetSize(),
      75           0 :         rSourceDevice);
      76           0 : }
      77             : 
      78             : 
      79           0 : void ForAllRectangles (const Region& rRegion, ::boost::function<void(const Rectangle&)> aFunction)
      80             : {
      81             :     OSL_ASSERT(aFunction);
      82           0 :     RectangleVector aRectangles;
      83           0 :     rRegion.GetRegionRectangles(aRectangles);
      84             : 
      85           0 :     if(0 == aRectangles.size())
      86             :     {
      87           0 :         aFunction(Rectangle());
      88             :     }
      89             :     else
      90             :     {
      91           0 :         for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
      92             :         {
      93           0 :             aFunction(*aRectIter);
      94             :         }
      95             : 
      96             :         //Region aMutableRegionCopy (rRegion);
      97             :         //RegionHandle aHandle(aMutableRegionCopy.BeginEnumRects());
      98             :         //Rectangle aBox;
      99             :         //while (aMutableRegionCopy.GetEnumRects(aHandle, aBox))
     100             :         //    aFunction(aBox);
     101             :         //aMutableRegionCopy.EndEnumRects(aHandle);
     102           0 :     }
     103           0 : }
     104             : 
     105             : class Layer : private ::boost::noncopyable
     106             : {
     107             : public:
     108             :     Layer (void);
     109             :     ~Layer (void);
     110             : 
     111             :     void Initialize (const SharedSdWindow& rpTargetWindow);
     112             :     void InvalidateRectangle (const Rectangle& rInvalidationBox);
     113             :     void InvalidateRegion (const Region& rInvalidationRegion);
     114             :     void Validate (const MapMode& rMapMode);
     115             :     void Repaint (
     116             :         OutputDevice& rTargetDevice,
     117             :         const Rectangle& rRepaintRectangle);
     118             :     void Resize (const Size& rSize);
     119             :     void AddPainter (const SharedILayerPainter& rpPainter);
     120             :     void RemovePainter (const SharedILayerPainter& rpPainter);
     121             :     bool HasPainter (void) const;
     122             :     void Dispose (void);
     123             : 
     124             : private:
     125             :     ::boost::shared_ptr<VirtualDevice> mpLayerDevice;
     126             :     ::std::vector<SharedILayerPainter> maPainters;
     127             :     Region maInvalidationRegion;
     128             : 
     129             :     void ValidateRectangle (const Rectangle& rBox);
     130             : };
     131             : typedef ::boost::shared_ptr<Layer> SharedLayer;
     132             : 
     133             : 
     134             : } // end of anonymous namespace
     135             : 
     136             : 
     137             : class LayeredDevice::LayerContainer : public ::std::vector<SharedLayer>
     138             : {
     139             : public:
     140           0 :     LayerContainer (void) {}
     141           0 :     ~LayerContainer (void) {}
     142             : };
     143             : 
     144             : 
     145             : 
     146             : 
     147             : //===== LayeredDevice =========================================================
     148             : 
     149           0 : LayeredDevice::LayeredDevice (const SharedSdWindow& rpTargetWindow)
     150             :     : mpTargetWindow(rpTargetWindow),
     151           0 :       mpLayers(new LayerContainer()),
     152           0 :       mpBackBuffer(new VirtualDevice(*mpTargetWindow)),
     153           0 :       maSavedMapMode(rpTargetWindow->GetMapMode())
     154             : {
     155           0 :     mpBackBuffer->SetOutputSizePixel(mpTargetWindow->GetSizePixel());
     156           0 : }
     157             : 
     158             : 
     159             : 
     160             : 
     161           0 : LayeredDevice::~LayeredDevice (void)
     162             : {
     163           0 : }
     164             : 
     165             : 
     166             : 
     167             : 
     168           0 : void LayeredDevice::Invalidate (
     169             :     const Rectangle& rInvalidationArea,
     170             :     const sal_Int32 nLayer)
     171             : {
     172           0 :     if (nLayer<0 || size_t(nLayer)>=mpLayers->size())
     173             :     {
     174             :         OSL_ASSERT(nLayer>=0 && size_t(nLayer)<mpLayers->size());
     175           0 :         return;
     176             :     }
     177             : 
     178           0 :     (*mpLayers)[nLayer]->InvalidateRectangle(rInvalidationArea);
     179             : }
     180             : 
     181             : 
     182             : 
     183             : 
     184           0 : void LayeredDevice::InvalidateAllLayers (const Rectangle& rInvalidationArea)
     185             : {
     186           0 :     for (sal_uInt32 nLayer=0; nLayer<mpLayers->size(); ++nLayer)
     187           0 :         (*mpLayers)[nLayer]->InvalidateRectangle(rInvalidationArea);
     188           0 : }
     189             : 
     190             : 
     191             : 
     192             : 
     193           0 : void LayeredDevice::InvalidateAllLayers (const Region& rInvalidationRegion)
     194             : {
     195           0 :     for (sal_uInt32 nLayer=0; nLayer<mpLayers->size(); ++nLayer)
     196           0 :         (*mpLayers)[nLayer]->InvalidateRegion(rInvalidationRegion);
     197           0 : }
     198             : 
     199             : 
     200             : 
     201             : 
     202           0 : void LayeredDevice::RegisterPainter (
     203             :     const SharedILayerPainter& rpPainter,
     204             :     const sal_Int32 nLayer)
     205             : {
     206             :     OSL_ASSERT(mpLayers);
     207           0 :     if ( ! rpPainter)
     208             :     {
     209             :         OSL_ASSERT(rpPainter);
     210           0 :         return;
     211             :     }
     212           0 :     if (nLayer<0 || nLayer>=gnMaximumLayerCount)
     213             :     {
     214             :         OSL_ASSERT(nLayer>=0 && nLayer<gnMaximumLayerCount);
     215           0 :         return;
     216             :     }
     217             : 
     218             :     // Provide the layers.
     219           0 :     if (sal_uInt32(nLayer) >= mpLayers->size())
     220             :     {
     221           0 :         const sal_Int32 nOldLayerCount (mpLayers->size());
     222           0 :         mpLayers->resize(nLayer+1);
     223             : 
     224           0 :         for (size_t nIndex=nOldLayerCount; nIndex<mpLayers->size(); ++nIndex)
     225           0 :             (*mpLayers)[nIndex].reset(new Layer());
     226             :     }
     227             : 
     228           0 :     (*mpLayers)[nLayer]->AddPainter(rpPainter);
     229           0 :     if (nLayer == 0)
     230           0 :         (*mpLayers)[nLayer]->Initialize(mpTargetWindow);
     231             : 
     232           0 :     rpPainter->SetLayerInvalidator(
     233           0 :         SharedILayerInvalidator(new LayerInvalidator(shared_from_this(),mpTargetWindow,nLayer)));
     234             : }
     235             : 
     236             : 
     237             : 
     238             : 
     239           0 : void LayeredDevice::RemovePainter (
     240             :     const SharedILayerPainter& rpPainter,
     241             :     const sal_Int32 nLayer)
     242             : {
     243           0 :     if ( ! rpPainter)
     244             :     {
     245             :         OSL_ASSERT(rpPainter);
     246           0 :         return;
     247             :     }
     248           0 :     if (nLayer<0 || size_t(nLayer)>=mpLayers->size())
     249             :     {
     250             :         OSL_ASSERT(nLayer>=0 && size_t(nLayer)<mpLayers->size());
     251           0 :         return;
     252             :     }
     253             : 
     254           0 :     rpPainter->SetLayerInvalidator(SharedILayerInvalidator());
     255             : 
     256           0 :     (*mpLayers)[nLayer]->RemovePainter(rpPainter);
     257             : 
     258             :     // Remove top most layers that do not contain any painters.
     259           0 :     while ( ! mpLayers->empty() && ! mpLayers->back()->HasPainter())
     260           0 :         mpLayers->erase(mpLayers->end()-1);
     261             : }
     262             : 
     263             : 
     264             : 
     265             : 
     266           0 : void LayeredDevice::Repaint (const Region& rRepaintRegion)
     267             : {
     268             :     // Validate the contents of all layers (that have their own devices.)
     269             :     ::std::for_each(
     270           0 :         mpLayers->begin(),
     271           0 :         mpLayers->end(),
     272           0 :         ::boost::bind(&Layer::Validate, _1, mpTargetWindow->GetMapMode()));
     273             : 
     274           0 :     ForAllRectangles(rRepaintRegion, ::boost::bind(&LayeredDevice::RepaintRectangle, this, _1));
     275           0 : }
     276             : 
     277             : 
     278             : 
     279             : 
     280           0 : void LayeredDevice::RepaintRectangle (const Rectangle& rRepaintRectangle)
     281             : {
     282           0 :     if (mpLayers->empty())
     283           0 :         return;
     284           0 :     else if (mpLayers->size() == 1)
     285             :     {
     286             :         // Just copy the main layer into the target device.
     287           0 :         (*mpLayers)[0]->Repaint(*mpTargetWindow, rRepaintRectangle);
     288             :     }
     289             :     else
     290             :     {
     291             :         // Paint all layers first into the back buffer (to avoid flickering
     292             :         // due to synchronous paints) and then copy that into the target
     293             :         // device.
     294           0 :         mpBackBuffer->SetMapMode(mpTargetWindow->GetMapMode());
     295             :         ::std::for_each(
     296           0 :             mpLayers->begin(),
     297           0 :             mpLayers->end(),
     298           0 :             ::boost::bind(&Layer::Repaint, _1, ::boost::ref(*mpBackBuffer), rRepaintRectangle));
     299             : 
     300           0 :         DeviceCopy(*mpTargetWindow, *mpBackBuffer, rRepaintRectangle);
     301             :     }
     302             : }
     303             : 
     304             : 
     305             : 
     306             : 
     307           0 : void LayeredDevice::Resize (void)
     308             : {
     309           0 :     const Size aSize (mpTargetWindow->GetSizePixel());
     310           0 :     mpBackBuffer->SetOutputSizePixel(aSize);
     311           0 :     ::std::for_each(mpLayers->begin(), mpLayers->end(), ::boost::bind(&Layer::Resize, _1, aSize));
     312           0 : }
     313             : 
     314             : 
     315             : 
     316             : 
     317           0 : void LayeredDevice::Dispose (void)
     318             : {
     319           0 :     ::std::for_each(mpLayers->begin(), mpLayers->end(), ::boost::bind(&Layer::Dispose, _1));
     320           0 :     mpLayers->clear();
     321           0 : }
     322             : 
     323             : 
     324             : 
     325             : 
     326           0 : bool LayeredDevice::HandleMapModeChange (void)
     327             : {
     328           0 :     const MapMode& rMapMode (mpTargetWindow->GetMapMode());
     329           0 :     if (maSavedMapMode == rMapMode)
     330           0 :         return false;
     331             : 
     332             :     const Rectangle aLogicWindowBox (
     333           0 :         mpTargetWindow->PixelToLogic(Rectangle(Point(0,0), mpTargetWindow->GetSizePixel())));
     334           0 :     if (maSavedMapMode.GetScaleX() != rMapMode.GetScaleX()
     335           0 :         || maSavedMapMode.GetScaleY() != rMapMode.GetScaleY()
     336           0 :         || maSavedMapMode.GetMapUnit() != rMapMode.GetMapUnit())
     337             :     {
     338             :         // When the scale has changed then we have to paint everything.
     339           0 :         InvalidateAllLayers(aLogicWindowBox);
     340             :     }
     341           0 :     else if (maSavedMapMode.GetOrigin() != rMapMode.GetOrigin())
     342             :     {
     343             :         // Window has been scrolled.  Adapt contents of backbuffers and
     344             :         // layer devices.
     345           0 :         const Point aDelta (rMapMode.GetOrigin() - maSavedMapMode.GetOrigin());
     346           0 :         mpBackBuffer->CopyArea(
     347             :             aLogicWindowBox.TopLeft(),
     348           0 :             mpTargetWindow->PixelToLogic(Point(0,0), maSavedMapMode),
     349           0 :             aLogicWindowBox.GetSize());
     350             : 
     351             :         // Invalidate the area(s) that have been exposed.
     352           0 :         const Rectangle aWindowBox (Point(0,0), mpTargetWindow->GetSizePixel());
     353           0 :         if (aDelta.Y() < 0)
     354           0 :             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
     355             :                 aWindowBox.Left(),
     356           0 :                 aWindowBox.Bottom()+aDelta.Y(),
     357             :                 aWindowBox.Right(),
     358           0 :                 aWindowBox.Bottom())));
     359           0 :         else if (aDelta.Y() > 0)
     360           0 :             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
     361             :                 aWindowBox.Left(),
     362             :                 aWindowBox.Top(),
     363             :                 aWindowBox.Right(),
     364           0 :                 aWindowBox.Top()+aDelta.Y())));
     365           0 :         if (aDelta.X() < 0)
     366           0 :             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
     367           0 :                 aWindowBox.Right()+aDelta.X(),
     368             :                 aWindowBox.Top(),
     369             :                 aWindowBox.Right(),
     370           0 :                 aWindowBox.Bottom())));
     371           0 :         else if (aDelta.X() > 0)
     372           0 :             InvalidateAllLayers(mpTargetWindow->PixelToLogic(Rectangle(
     373             :                 aWindowBox.Left(),
     374             :                 aWindowBox.Top(),
     375           0 :                 aWindowBox.Left()+aDelta.X(),
     376           0 :                 aWindowBox.Bottom())));
     377             :     }
     378             :     else
     379             :     {
     380             :         // Can this happen?  Lets trigger a warning when it does.
     381             :         OSL_ASSERT(false);
     382             :     }
     383             : 
     384           0 :     maSavedMapMode = rMapMode;
     385             : 
     386           0 :     return true;
     387             : }
     388             : 
     389             : 
     390             : 
     391             : 
     392             : //===== Layer =================================================================
     393             : 
     394           0 : Layer::Layer (void)
     395             :     : mpLayerDevice(),
     396             :       maPainters(),
     397           0 :       maInvalidationRegion()
     398             : {
     399           0 : }
     400             : 
     401             : 
     402             : 
     403             : 
     404           0 : Layer::~Layer (void)
     405             : {
     406           0 : }
     407             : 
     408             : 
     409             : 
     410             : 
     411           0 : void Layer::Initialize (const SharedSdWindow& rpTargetWindow)
     412             : {
     413             : #if 0
     414             :     (void)rpTargetWindow;
     415             : #else
     416           0 :     if ( ! mpLayerDevice)
     417             :     {
     418           0 :         mpLayerDevice.reset(new VirtualDevice(*rpTargetWindow));
     419           0 :         mpLayerDevice->SetOutputSizePixel(rpTargetWindow->GetSizePixel());
     420             :     }
     421             : #endif
     422           0 : }
     423             : 
     424             : 
     425             : 
     426             : 
     427           0 : void Layer::InvalidateRectangle (const Rectangle& rInvalidationBox)
     428             : {
     429           0 :     maInvalidationRegion.Union(rInvalidationBox);
     430           0 : }
     431             : 
     432             : 
     433             : 
     434             : 
     435           0 : void Layer::InvalidateRegion (const Region& rInvalidationRegion)
     436             : {
     437           0 :     maInvalidationRegion.Union(rInvalidationRegion);
     438           0 : }
     439             : 
     440             : 
     441             : 
     442             : 
     443           0 : void Layer::Validate (const MapMode& rMapMode)
     444             : {
     445           0 :     if (mpLayerDevice && ! maInvalidationRegion.IsEmpty())
     446             :     {
     447           0 :         Region aRegion (maInvalidationRegion);
     448           0 :         maInvalidationRegion.SetEmpty();
     449             : 
     450           0 :         mpLayerDevice->SetMapMode(rMapMode);
     451             :         ForAllRectangles(
     452             :             aRegion,
     453           0 :             ::boost::bind(&Layer::ValidateRectangle, this, _1));
     454             :     }
     455           0 : }
     456             : 
     457             : 
     458             : 
     459             : 
     460           0 : void Layer::ValidateRectangle (const Rectangle& rBox)
     461             : {
     462           0 :     if ( ! mpLayerDevice)
     463           0 :         return;
     464           0 :     const Region aSavedClipRegion (mpLayerDevice->GetClipRegion());
     465           0 :     mpLayerDevice->IntersectClipRegion(rBox);
     466             : 
     467           0 :     for (::std::vector<SharedILayerPainter>::const_iterator
     468           0 :              iPainter(maPainters.begin()),
     469           0 :              iEnd(maPainters.end());
     470             :          iPainter!=iEnd;
     471             :          ++iPainter)
     472             :     {
     473           0 :         (*iPainter)->Paint(*mpLayerDevice, rBox);
     474             :     }
     475             : 
     476           0 :     mpLayerDevice->SetClipRegion(aSavedClipRegion);
     477             : }
     478             : 
     479             : 
     480             : 
     481             : 
     482           0 : void Layer::Repaint (
     483             :     OutputDevice& rTargetDevice,
     484             :     const Rectangle& rRepaintRectangle)
     485             : {
     486           0 :     if (mpLayerDevice)
     487             :     {
     488           0 :         DeviceCopy(rTargetDevice, *mpLayerDevice, rRepaintRectangle);
     489             :     }
     490             :     else
     491             :     {
     492             :         ::std::for_each(
     493             :             maPainters.begin(),
     494             :             maPainters.end(),
     495             :             ::boost::bind(&ILayerPainter::Paint,
     496             :                 _1,
     497             :                 ::boost::ref(rTargetDevice),
     498           0 :                 rRepaintRectangle));
     499             :     }
     500           0 : }
     501             : 
     502             : 
     503             : 
     504             : 
     505           0 : void Layer::Resize (const Size& rSize)
     506             : {
     507           0 :     if (mpLayerDevice)
     508             :     {
     509           0 :         mpLayerDevice->SetOutputSizePixel(rSize);
     510           0 :         maInvalidationRegion = Rectangle(Point(0,0), rSize);
     511             :     }
     512           0 : }
     513             : 
     514             : 
     515             : 
     516             : 
     517           0 : void Layer::AddPainter (const SharedILayerPainter& rpPainter)
     518             : {
     519             :     OSL_ASSERT(::std::find(maPainters.begin(), maPainters.end(), rpPainter) == maPainters.end());
     520             : 
     521           0 :     maPainters.push_back(rpPainter);
     522           0 : }
     523             : 
     524             : 
     525             : 
     526             : 
     527           0 : void Layer::RemovePainter (const SharedILayerPainter& rpPainter)
     528             : {
     529             :     const ::std::vector<SharedILayerPainter>::iterator iPainter (
     530           0 :         ::std::find(maPainters.begin(), maPainters.end(), rpPainter));
     531           0 :     if (iPainter != maPainters.end())
     532             :     {
     533           0 :         maPainters.erase(iPainter);
     534             :     }
     535             :     else
     536             :     {
     537             :         DBG_ASSERT(false,"LayeredDevice::RemovePainter called for painter that is not registered");
     538             :     }
     539           0 : }
     540             : 
     541             : 
     542             : 
     543             : 
     544           0 : bool Layer::HasPainter (void) const
     545             : {
     546           0 :     return !maPainters.empty();
     547             : }
     548             : 
     549             : 
     550             : 
     551             : 
     552           0 : void Layer::Dispose (void)
     553             : {
     554           0 :     maPainters.clear();
     555           0 : }
     556             : 
     557             : 
     558           0 : } } } // end of namespace ::sd::slidesorter::view
     559             : 
     560             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10