LCOV - code coverage report
Current view: top level - libreoffice/svx/source/sdr/overlay - overlaymanager.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 98 146 67.1 %
Date: 2012-12-27 Functions: 15 22 68.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <svx/sdr/overlay/overlaymanager.hxx>
      21             : #include <basegfx/point/b2dpoint.hxx>
      22             : #include <basegfx/range/b2drange.hxx>
      23             : #include <tools/gen.hxx>
      24             : #include <vcl/outdev.hxx>
      25             : #include <vcl/window.hxx>
      26             : #include <svx/sdr/overlay/overlayobject.hxx>
      27             : #include <basegfx/matrix/b2dhommatrix.hxx>
      28             : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
      29             : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
      30             : 
      31             : //////////////////////////////////////////////////////////////////////////////
      32             : 
      33             : using namespace com::sun::star;
      34             : 
      35             : //////////////////////////////////////////////////////////////////////////////
      36             : 
      37             : namespace sdr
      38             : {
      39             :     namespace overlay
      40             :     {
      41           9 :         void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const
      42             :         {
      43           9 :             const sal_uInt32 nSize(maOverlayObjects.size());
      44             : 
      45           9 :             if(nSize)
      46             :             {
      47           9 :                 const sal_uInt16 nOriginalAA(rDestinationDevice.GetAntialiasing());
      48           9 :                 const bool bIsAntiAliasing(getDrawinglayerOpt().IsAntiAliasing());
      49             : 
      50             :                 // create processor
      51             :                 drawinglayer::processor2d::BaseProcessor2D* pProcessor =
      52             :                     ::drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
      53             :                         rDestinationDevice,
      54           9 :                         getCurrentViewInformation2D());
      55             : 
      56           9 :                 if(pProcessor)
      57             :                 {
      58          27 :                     for(OverlayObjectVector::const_iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
      59             :                     {
      60             :                         OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
      61          18 :                         const OverlayObject& rCandidate = **aIter;
      62             : 
      63          18 :                         if(rCandidate.isVisible())
      64             :                         {
      65          18 :                             const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rCandidate.getOverlayObjectPrimitive2DSequence();
      66             : 
      67          18 :                             if(rSequence.hasElements())
      68             :                             {
      69          18 :                                 if(rRange.overlaps(rCandidate.getBaseRange()))
      70             :                                 {
      71           9 :                                     if(bIsAntiAliasing && rCandidate.allowsAntiAliase())
      72             :                                     {
      73           0 :                                         rDestinationDevice.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW);
      74             :                                     }
      75             :                                     else
      76             :                                     {
      77           9 :                                         rDestinationDevice.SetAntialiasing(nOriginalAA & ~ANTIALIASING_ENABLE_B2DDRAW);
      78             :                                     }
      79             : 
      80           9 :                                     pProcessor->process(rSequence);
      81             :                                 }
      82          18 :                             }
      83             :                         }
      84             :                     }
      85             : 
      86           9 :                     delete pProcessor;
      87             :                 }
      88             : 
      89             :                 // restore AA settings
      90           9 :                 rDestinationDevice.SetAntialiasing(nOriginalAA);
      91             :             }
      92           9 :         }
      93             : 
      94         133 :         void OverlayManager::ImpStripeDefinitionChanged()
      95             :         {
      96         133 :             const sal_uInt32 nSize(maOverlayObjects.size());
      97             : 
      98         133 :             if(nSize)
      99             :             {
     100           0 :                 for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
     101             :                 {
     102             :                     OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
     103           0 :                     OverlayObject& rCandidate = **aIter;
     104           0 :                     rCandidate.stripeDefinitionHasChanged();
     105             :                 }
     106             :             }
     107         133 :         }
     108             : 
     109           0 :         double OverlayManager::getDiscreteOne() const
     110             :         {
     111           0 :             if(basegfx::fTools::equalZero(mfDiscreteOne))
     112             :             {
     113           0 :                 const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0));
     114           0 :                 const_cast< OverlayManager* >(this)->mfDiscreteOne = aDiscreteInLogic.getLength();
     115             :             }
     116             : 
     117           0 :             return mfDiscreteOne;
     118             :         }
     119             : 
     120         133 :         OverlayManager::OverlayManager(
     121             :             OutputDevice& rOutputDevice,
     122             :             OverlayManager* pOldOverlayManager)
     123             :         :   Scheduler(),
     124             :             mnRefCount(0),
     125             :             rmOutputDevice(rOutputDevice),
     126             :             maOverlayObjects(),
     127             :             maStripeColorA(Color(COL_BLACK)),
     128             :             maStripeColorB(Color(COL_WHITE)),
     129             :             mnStripeLengthPixel(5),
     130             :             maDrawinglayerOpt(),
     131             :             maViewTransformation(),
     132             :             maViewInformation2D(),
     133         133 :             mfDiscreteOne(0.0)
     134             :         {
     135             :             // set Property 'ReducedDisplayQuality' to true to allow simpler interaction
     136             :             // visualisations
     137             :             static bool bUseReducedDisplayQualityForDrag(true);
     138             : 
     139         133 :             if(bUseReducedDisplayQualityForDrag)
     140             :             {
     141         133 :                 uno::Sequence< beans::PropertyValue > xProperties(1);
     142         133 :                 xProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality"));
     143         133 :                 xProperties[0].Value <<= true;
     144         133 :                 maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties);
     145             :             }
     146             : 
     147         133 :             if(pOldOverlayManager)
     148             :             {
     149             :                 // take over OverlayObjects from given OverlayManager. Copy
     150             :                 // the vector of pointers
     151           0 :                 maOverlayObjects = pOldOverlayManager->maOverlayObjects;
     152           0 :                 const sal_uInt32 nSize(maOverlayObjects.size());
     153             : 
     154           0 :                 if(nSize)
     155             :                 {
     156           0 :                     for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
     157             :                     {
     158             :                         OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
     159           0 :                         OverlayObject& rCandidate = **aIter;
     160             : 
     161             :                         // remove from old and add to new OverlayManager
     162           0 :                         pOldOverlayManager->impApplyRemoveActions(rCandidate);
     163           0 :                         impApplyAddActions(rCandidate);
     164             :                     }
     165             : 
     166           0 :                     pOldOverlayManager->maOverlayObjects.clear();
     167             :                 }
     168             :             }
     169         133 :         }
     170             : 
     171           0 :         rtl::Reference<OverlayManager> OverlayManager::create(
     172             :             OutputDevice& rOutputDevice,
     173             :             OverlayManager* pOldOverlayManager)
     174             :         {
     175             :             return rtl::Reference<OverlayManager>(new OverlayManager(rOutputDevice,
     176           0 :                 pOldOverlayManager));
     177             :         }
     178             : 
     179          57 :         const drawinglayer::geometry::ViewInformation2D OverlayManager::getCurrentViewInformation2D() const
     180             :         {
     181          57 :             if(getOutputDevice().GetViewTransformation() != maViewTransformation)
     182             :             {
     183           6 :                 basegfx::B2DRange aViewRange(maViewInformation2D.getViewport());
     184             : 
     185           6 :                 if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType())
     186             :                 {
     187           6 :                     const Size aOutputSizePixel(getOutputDevice().GetOutputSizePixel());
     188           6 :                     aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
     189           6 :                     aViewRange.transform(getOutputDevice().GetInverseViewTransformation());
     190             :                 }
     191             : 
     192           6 :                 OverlayManager* pThis = const_cast< OverlayManager* >(this);
     193             : 
     194           6 :                 pThis->maViewTransformation = getOutputDevice().GetViewTransformation();
     195             :                 pThis->maViewInformation2D = drawinglayer::geometry::ViewInformation2D(
     196           6 :                     maViewInformation2D.getObjectTransformation(),
     197             :                     maViewTransformation,
     198             :                     aViewRange,
     199           6 :                     maViewInformation2D.getVisualizedPage(),
     200             :                     maViewInformation2D.getViewTime(),
     201          18 :                     maViewInformation2D.getExtendedInformationSequence());
     202           6 :                 pThis->mfDiscreteOne = 0.0;
     203             :             }
     204             : 
     205          57 :             return maViewInformation2D;
     206             :         }
     207             : 
     208           6 :         void OverlayManager::impApplyRemoveActions(OverlayObject& rTarget)
     209             :         {
     210             :             // handle evtl. animation
     211           6 :             if(rTarget.allowsAnimation())
     212             :             {
     213             :                 // remove from event chain
     214           0 :                 RemoveEvent(&rTarget);
     215             :             }
     216             : 
     217             :             // make invisible
     218           6 :             invalidateRange(rTarget.getBaseRange());
     219             : 
     220             :             // clear manager
     221           6 :             rTarget.mpOverlayManager = 0;
     222           6 :         }
     223             : 
     224          12 :         void OverlayManager::impApplyAddActions(OverlayObject& rTarget)
     225             :         {
     226             :             // set manager
     227          12 :             rTarget.mpOverlayManager = this;
     228             : 
     229             :             // make visible
     230          12 :             invalidateRange(rTarget.getBaseRange());
     231             : 
     232             :             // handle evtl. animation
     233          12 :             if(rTarget.allowsAnimation())
     234             :             {
     235             :                 // Trigger at current time to get alive. This will do the
     236             :                 // object-specific next time calculation and hand over adding
     237             :                 // again to the scheduler to the animated object, too. This works for
     238             :                 // a paused or non-paused animator.
     239           0 :                 rTarget.Trigger(GetTime());
     240             :             }
     241          12 :         }
     242             : 
     243          16 :         OverlayManager::~OverlayManager()
     244             :         {
     245             :             // The OverlayManager is not the owner of the OverlayObjects
     246             :             // and thus will not delete them, but remove them. Profit here
     247             :             // from knowing that all will be removed
     248           8 :             const sal_uInt32 nSize(maOverlayObjects.size());
     249             : 
     250           8 :             if(nSize)
     251             :             {
     252           0 :                 for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
     253             :                 {
     254             :                     OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
     255           0 :                     OverlayObject& rCandidate = **aIter;
     256           0 :                     impApplyRemoveActions(rCandidate);
     257             :                 }
     258             : 
     259             :                 // erase vector
     260           0 :                 maOverlayObjects.clear();
     261             :             }
     262           8 :         }
     263             : 
     264         262 :         void OverlayManager::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const
     265             :         {
     266         262 :             if(!rRegion.IsEmpty() && maOverlayObjects.size())
     267             :             {
     268             :                 // check for changed MapModes. That may influence the
     269             :                 // logical size of pixel based OverlayObjects (like BitmapHandles)
     270             :                 //ImpCheckMapModeChange();
     271             : 
     272             :                 // paint members
     273           6 :                 const Rectangle aRegionBoundRect(rRegion.GetBoundRect());
     274             :                 const basegfx::B2DRange aRegionRange(
     275          12 :                     aRegionBoundRect.Left(), aRegionBoundRect.Top(),
     276          18 :                     aRegionBoundRect.Right(), aRegionBoundRect.Bottom());
     277             : 
     278           6 :                 OutputDevice& rTarget = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
     279           6 :                 ImpDrawMembers(aRegionRange, rTarget);
     280             :             }
     281         262 :         }
     282             : 
     283           0 :         void OverlayManager::flush()
     284             :         {
     285             :             // default has nothing to do
     286           0 :         }
     287             : 
     288             :         // #i68597# part of content gets copied, react on it
     289           0 :         void OverlayManager::copyArea(const Point& /*rDestPt*/, const Point& /*rSrcPt*/, const Size& /*rSrcSize*/)
     290             :         {
     291             :             // unbuffered versions do nothing here
     292           0 :         }
     293             : 
     294           0 :         void OverlayManager::restoreBackground(const Region& /*rRegion*/) const
     295             :         {
     296             :             // unbuffered versions do nothing here
     297           0 :         }
     298             : 
     299          12 :         void OverlayManager::add(OverlayObject& rOverlayObject)
     300             :         {
     301             :             OSL_ENSURE(0 == rOverlayObject.mpOverlayManager, "OverlayObject is added twice to an OverlayManager (!)");
     302             : 
     303             :             // add to the end of chain to preserve display order in paint
     304          12 :             maOverlayObjects.push_back(&rOverlayObject);
     305             : 
     306             :             // execute add actions
     307          12 :             impApplyAddActions(rOverlayObject);
     308          12 :         }
     309             : 
     310           6 :         void OverlayManager::remove(OverlayObject& rOverlayObject)
     311             :         {
     312             :             OSL_ENSURE(rOverlayObject.mpOverlayManager == this, "OverlayObject is removed from wrong OverlayManager (!)");
     313             : 
     314             :             // execute remove actions
     315           6 :             impApplyRemoveActions(rOverlayObject);
     316             : 
     317             :             // remove from vector
     318           6 :             const OverlayObjectVector::iterator aFindResult = ::std::find(maOverlayObjects.begin(), maOverlayObjects.end(), &rOverlayObject);
     319           6 :             const bool bFound(aFindResult != maOverlayObjects.end());
     320             :             OSL_ENSURE(bFound, "OverlayObject NOT found at OverlayManager (!)");
     321             : 
     322           6 :             if(bFound)
     323             :             {
     324           6 :                 maOverlayObjects.erase(aFindResult);
     325             :             }
     326           6 :         }
     327             : 
     328           0 :         void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange)
     329             :         {
     330           0 :             if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType())
     331             :             {
     332           0 :                 if(getDrawinglayerOpt().IsAntiAliasing())
     333             :                 {
     334             :                     // assume AA needs one pixel more and invalidate one pixel more
     335           0 :                     const double fDiscreteOne(getDiscreteOne());
     336             :                     const Rectangle aInvalidateRectangle(
     337           0 :                         (sal_Int32)floor(rRange.getMinX() - fDiscreteOne),
     338           0 :                         (sal_Int32)floor(rRange.getMinY() - fDiscreteOne),
     339           0 :                         (sal_Int32)ceil(rRange.getMaxX() + fDiscreteOne),
     340           0 :                         (sal_Int32)ceil(rRange.getMaxY() + fDiscreteOne));
     341             : 
     342             :                     // simply invalidate
     343           0 :                     ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE);
     344             :                 }
     345             :                 else
     346             :                 {
     347             :                     // #i77674# transform to rectangle. Use floor/ceil to get all covered
     348             :                     // discrete pixels, see #i75163# and OverlayManagerBuffered::invalidateRange
     349             :                     const Rectangle aInvalidateRectangle(
     350           0 :                         (sal_Int32)floor(rRange.getMinX()), (sal_Int32)floor(rRange.getMinY()),
     351           0 :                         (sal_Int32)ceil(rRange.getMaxX()), (sal_Int32)ceil(rRange.getMaxY()));
     352             : 
     353             :                     // simply invalidate
     354           0 :                     ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE);
     355             :                 }
     356             :             }
     357           0 :         }
     358             : 
     359             :         // stripe support ColA
     360         133 :         void OverlayManager::setStripeColorA(Color aNew)
     361             :         {
     362         133 :             if(aNew != maStripeColorA)
     363             :             {
     364           0 :                 maStripeColorA = aNew;
     365           0 :                 ImpStripeDefinitionChanged();
     366             :             }
     367         133 :         }
     368             : 
     369             :         // stripe support ColB
     370         133 :         void OverlayManager::setStripeColorB(Color aNew)
     371             :         {
     372         133 :             if(aNew != maStripeColorB)
     373             :             {
     374           0 :                 maStripeColorB = aNew;
     375           0 :                 ImpStripeDefinitionChanged();
     376             :             }
     377         133 :         }
     378             : 
     379             :         // stripe support StripeLengthPixel
     380         133 :         void OverlayManager::setStripeLengthPixel(sal_uInt32 nNew)
     381             :         {
     382         133 :             if(nNew != mnStripeLengthPixel)
     383             :             {
     384         133 :                 mnStripeLengthPixel = nNew;
     385         133 :                 ImpStripeDefinitionChanged();
     386             :             }
     387         133 :         }
     388             : 
     389         281 :         oslInterlockedCount OverlayManager::acquire()
     390             :         {
     391         281 :             return osl_atomic_increment( &mnRefCount );
     392             :         }
     393             : 
     394         156 :         oslInterlockedCount OverlayManager::release()
     395             :         {
     396         156 :             oslInterlockedCount nCount( osl_atomic_decrement( &mnRefCount ) );
     397         156 :             if ( nCount == 0 )
     398           8 :                 delete this;
     399         156 :             return nCount;
     400             :         }
     401             : 
     402             :     } // end of namespace overlay
     403             : } // end of namespace sdr
     404             : 
     405             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10