LCOV - code coverage report
Current view: top level - svx/source/sdr/overlay - overlaymanager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 107 132 81.1 %
Date: 2015-06-13 12:38:46 Functions: 16 20 80.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 <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/processor2dtools.hxx>
      29             : #include <boost/scoped_ptr.hpp>
      30             : 
      31             : 
      32             : using namespace com::sun::star;
      33             : 
      34             : 
      35             : 
      36             : namespace sdr
      37             : {
      38             :     namespace overlay
      39             :     {
      40        3545 :         void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const
      41             :         {
      42        3545 :             const sal_uInt32 nSize(maOverlayObjects.size());
      43             : 
      44        3545 :             if(nSize)
      45             :             {
      46        3511 :                 const AntialiasingFlags nOriginalAA(rDestinationDevice.GetAntialiasing());
      47        3511 :                 const bool bIsAntiAliasing(getDrawinglayerOpt().IsAntiAliasing());
      48             : 
      49             :                 // create processor
      50             :                 boost::scoped_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(drawinglayer::processor2d::createProcessor2DFromOutputDevice(
      51             :                     rDestinationDevice,
      52        3511 :                     getCurrentViewInformation2D()));
      53             : 
      54        3511 :                 if(pProcessor)
      55             :                 {
      56       10978 :                     for(OverlayObjectVector::const_iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
      57             :                     {
      58             :                         OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
      59        7467 :                         const OverlayObject& rCandidate = **aIter;
      60             : 
      61        7467 :                         if(rCandidate.isVisible())
      62             :                         {
      63        7467 :                             const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rCandidate.getOverlayObjectPrimitive2DSequence();
      64             : 
      65        7467 :                             if(rSequence.hasElements())
      66             :                             {
      67        7467 :                                 if(rRange.overlaps(rCandidate.getBaseRange()))
      68             :                                 {
      69        3748 :                                     if(bIsAntiAliasing && rCandidate.allowsAntiAliase())
      70             :                                     {
      71           0 :                                         rDestinationDevice.SetAntialiasing(nOriginalAA | AntialiasingFlags::EnableB2dDraw);
      72             :                                     }
      73             :                                     else
      74             :                                     {
      75        3748 :                                         rDestinationDevice.SetAntialiasing(nOriginalAA & ~AntialiasingFlags::EnableB2dDraw);
      76             :                                     }
      77             : 
      78        3748 :                                     pProcessor->process(rSequence);
      79             :                                 }
      80        7467 :                             }
      81             :                         }
      82             :                     }
      83             : 
      84        3511 :                     pProcessor.reset();
      85             :                 }
      86             : 
      87             :                 // restore AA settings
      88        3511 :                 rDestinationDevice.SetAntialiasing(nOriginalAA);
      89             :             }
      90        3545 :         }
      91             : 
      92        1312 :         void OverlayManager::ImpStripeDefinitionChanged()
      93             :         {
      94        1312 :             const sal_uInt32 nSize(maOverlayObjects.size());
      95             : 
      96        1312 :             if(nSize)
      97             :             {
      98           0 :                 for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
      99             :                 {
     100             :                     OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
     101           0 :                     OverlayObject& rCandidate = **aIter;
     102           0 :                     rCandidate.stripeDefinitionHasChanged();
     103             :                 }
     104             :             }
     105        1312 :         }
     106             : 
     107           0 :         double OverlayManager::getDiscreteOne() const
     108             :         {
     109           0 :             if(basegfx::fTools::equalZero(mfDiscreteOne))
     110             :             {
     111           0 :                 const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0));
     112           0 :                 const_cast< OverlayManager* >(this)->mfDiscreteOne = aDiscreteInLogic.getLength();
     113             :             }
     114             : 
     115           0 :             return mfDiscreteOne;
     116             :         }
     117             : 
     118        1312 :         OverlayManager::OverlayManager(OutputDevice& rOutputDevice, const SdrModel* pModel)
     119             :         :   Scheduler(),
     120             :             mrOutputDevice(rOutputDevice),
     121             :             mpModel(pModel),
     122             :             maOverlayObjects(),
     123             :             maStripeColorA(Color(COL_BLACK)),
     124             :             maStripeColorB(Color(COL_WHITE)),
     125             :             mnStripeLengthPixel(5),
     126             :             maDrawinglayerOpt(),
     127             :             maViewTransformation(),
     128             :             maViewInformation2D(),
     129        1312 :             mfDiscreteOne(0.0)
     130             :         {
     131             :             // set Property 'ReducedDisplayQuality' to true to allow simpler interaction
     132             :             // visualisations
     133             :             static bool bUseReducedDisplayQualityForDrag(true);
     134             : 
     135        1312 :             if(bUseReducedDisplayQualityForDrag)
     136             :             {
     137        1312 :                 uno::Sequence< beans::PropertyValue > xProperties(1);
     138        1312 :                 xProperties[0].Name = "ReducedDisplayQuality";
     139        1312 :                 xProperties[0].Value <<= true;
     140        1312 :                 maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties);
     141             :             }
     142        1312 :         }
     143             : 
     144           9 :         rtl::Reference<OverlayManager> OverlayManager::create(OutputDevice& rOutputDevice, const SdrModel* pModel)
     145             :         {
     146           9 :             return rtl::Reference<OverlayManager>(new OverlayManager(rOutputDevice, pModel));
     147             :         }
     148             : 
     149       10596 :         const drawinglayer::geometry::ViewInformation2D OverlayManager::getCurrentViewInformation2D() const
     150             :         {
     151       10596 :             if(getOutputDevice().GetViewTransformation() != maViewTransformation)
     152             :             {
     153         820 :                 basegfx::B2DRange aViewRange(maViewInformation2D.getViewport());
     154             : 
     155         820 :                 if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType())
     156             :                 {
     157         820 :                     const Size aOutputSizePixel(getOutputDevice().GetOutputSizePixel());
     158             : 
     159             :                     // only set when we *have* a output size, else let aViewRange
     160             :                     // stay on empty
     161         820 :                     if(aOutputSizePixel.Width() && aOutputSizePixel.Height())
     162             :                     {
     163         601 :                         aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
     164         601 :                         aViewRange.transform(getOutputDevice().GetInverseViewTransformation());
     165             :                     }
     166             :                 }
     167             : 
     168         820 :                 OverlayManager* pThis = const_cast< OverlayManager* >(this);
     169             : 
     170         820 :                 pThis->maViewTransformation = getOutputDevice().GetViewTransformation();
     171        3280 :                 pThis->maViewInformation2D = drawinglayer::geometry::ViewInformation2D(
     172         820 :                     maViewInformation2D.getObjectTransformation(),
     173             :                     maViewTransformation,
     174             :                     aViewRange,
     175         820 :                     maViewInformation2D.getVisualizedPage(),
     176             :                     maViewInformation2D.getViewTime(),
     177        1640 :                     maViewInformation2D.getExtendedInformationSequence());
     178         820 :                 pThis->mfDiscreteOne = 0.0;
     179             :             }
     180             : 
     181       10596 :             return maViewInformation2D;
     182             :         }
     183             : 
     184        6317 :         void OverlayManager::impApplyRemoveActions(OverlayObject& rTarget)
     185             :         {
     186             :             // handle evtl. animation
     187        6317 :             if(rTarget.allowsAnimation())
     188             :             {
     189             :                 // remove from event chain
     190          12 :                 RemoveEvent(&rTarget);
     191             :             }
     192             : 
     193             :             // make invisible
     194        6317 :             invalidateRange(rTarget.getBaseRange());
     195             : 
     196             :             // clear manager
     197        6317 :             rTarget.mpOverlayManager = 0;
     198        6317 :         }
     199             : 
     200        6328 :         void OverlayManager::impApplyAddActions(OverlayObject& rTarget)
     201             :         {
     202             :             // set manager
     203        6328 :             rTarget.mpOverlayManager = this;
     204             : 
     205             :             // make visible
     206        6328 :             invalidateRange(rTarget.getBaseRange());
     207             : 
     208             :             // handle evtl. animation
     209        6328 :             if(rTarget.allowsAnimation())
     210             :             {
     211             :                 // Trigger at current time to get alive. This will do the
     212             :                 // object-specific next time calculation and hand over adding
     213             :                 // again to the scheduler to the animated object, too. This works for
     214             :                 // a paused or non-paused animator.
     215          12 :                 rTarget.Trigger(GetTime());
     216             :             }
     217        6328 :         }
     218             : 
     219        2591 :         OverlayManager::~OverlayManager()
     220             :         {
     221             :             // The OverlayManager is not the owner of the OverlayObjects
     222             :             // and thus will not delete them, but remove them. Profit here
     223             :             // from knowing that all will be removed
     224        1291 :             const sal_uInt32 nSize(maOverlayObjects.size());
     225             : 
     226        1291 :             if(nSize)
     227             :             {
     228         871 :                 for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
     229             :                 {
     230             :                     OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
     231         593 :                     OverlayObject& rCandidate = **aIter;
     232         593 :                     impApplyRemoveActions(rCandidate);
     233             :                 }
     234             : 
     235             :                 // erase vector
     236         278 :                 maOverlayObjects.clear();
     237             :             }
     238        1300 :         }
     239             : 
     240       13773 :         void OverlayManager::completeRedraw(const vcl::Region& rRegion, OutputDevice* pPreRenderDevice) const
     241             :         {
     242       13773 :             if(!rRegion.IsEmpty() && maOverlayObjects.size())
     243             :             {
     244             :                 // check for changed MapModes. That may influence the
     245             :                 // logical size of pixel based OverlayObjects (like BitmapHandles)
     246             :                 //ImpCheckMapModeChange();
     247             : 
     248             :                 // paint members
     249        2958 :                 const Rectangle aRegionBoundRect(rRegion.GetBoundRect());
     250             :                 const basegfx::B2DRange aRegionRange(
     251        5916 :                     aRegionBoundRect.Left(), aRegionBoundRect.Top(),
     252        8874 :                     aRegionBoundRect.Right(), aRegionBoundRect.Bottom());
     253             : 
     254        2958 :                 OutputDevice& rTarget = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
     255        2958 :                 ImpDrawMembers(aRegionRange, rTarget);
     256             :             }
     257       13773 :         }
     258             : 
     259           0 :         void OverlayManager::flush()
     260             :         {
     261             :             // default has nothing to do
     262           0 :         }
     263             : 
     264             :         // #i68597# part of content gets copied, react on it
     265           0 :         void OverlayManager::copyArea(const Point& /*rDestPt*/, const Point& /*rSrcPt*/, const Size& /*rSrcSize*/)
     266             :         {
     267             :             // unbuffered versions do nothing here
     268           0 :         }
     269             : 
     270           0 :         void OverlayManager::restoreBackground(const vcl::Region& /*rRegion*/) const
     271             :         {
     272             :             // unbuffered versions do nothing here
     273           0 :         }
     274             : 
     275        6328 :         void OverlayManager::add(OverlayObject& rOverlayObject)
     276             :         {
     277             :             OSL_ENSURE(0 == rOverlayObject.mpOverlayManager, "OverlayObject is added twice to an OverlayManager (!)");
     278             : 
     279             :             // add to the end of chain to preserve display order in paint
     280        6328 :             maOverlayObjects.push_back(&rOverlayObject);
     281             : 
     282             :             // execute add actions
     283        6328 :             impApplyAddActions(rOverlayObject);
     284        6328 :         }
     285             : 
     286        5724 :         void OverlayManager::remove(OverlayObject& rOverlayObject)
     287             :         {
     288             :             OSL_ENSURE(rOverlayObject.mpOverlayManager == this, "OverlayObject is removed from wrong OverlayManager (!)");
     289             : 
     290             :             // execute remove actions
     291        5724 :             impApplyRemoveActions(rOverlayObject);
     292             : 
     293             :             // remove from vector
     294        5724 :             const OverlayObjectVector::iterator aFindResult = ::std::find(maOverlayObjects.begin(), maOverlayObjects.end(), &rOverlayObject);
     295        5724 :             const bool bFound(aFindResult != maOverlayObjects.end());
     296             :             OSL_ENSURE(bFound, "OverlayObject NOT found at OverlayManager (!)");
     297             : 
     298        5724 :             if(bFound)
     299             :             {
     300        5724 :                 maOverlayObjects.erase(aFindResult);
     301             :             }
     302        5724 :         }
     303             : 
     304         593 :         void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange)
     305             :         {
     306         593 :             if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType())
     307             :             {
     308         593 :                 if(getDrawinglayerOpt().IsAntiAliasing())
     309             :                 {
     310             :                     // assume AA needs one pixel more and invalidate one pixel more
     311           0 :                     const double fDiscreteOne(getDiscreteOne());
     312             :                     const Rectangle aInvalidateRectangle(
     313           0 :                         (sal_Int32)floor(rRange.getMinX() - fDiscreteOne),
     314           0 :                         (sal_Int32)floor(rRange.getMinY() - fDiscreteOne),
     315           0 :                         (sal_Int32)ceil(rRange.getMaxX() + fDiscreteOne),
     316           0 :                         (sal_Int32)ceil(rRange.getMaxY() + fDiscreteOne));
     317             : 
     318             :                     // simply invalidate
     319           0 :                     static_cast<vcl::Window&>(getOutputDevice()).Invalidate(aInvalidateRectangle, InvalidateFlags::NoErase);
     320             :                 }
     321             :                 else
     322             :                 {
     323             :                     // #i77674# transform to rectangle. Use floor/ceil to get all covered
     324             :                     // discrete pixels, see #i75163# and OverlayManagerBuffered::invalidateRange
     325             :                     const Rectangle aInvalidateRectangle(
     326        1186 :                         (sal_Int32)floor(rRange.getMinX()), (sal_Int32)floor(rRange.getMinY()),
     327        1779 :                         (sal_Int32)ceil(rRange.getMaxX()), (sal_Int32)ceil(rRange.getMaxY()));
     328             : 
     329             :                     // simply invalidate
     330         593 :                     static_cast<vcl::Window&>(getOutputDevice()).Invalidate(aInvalidateRectangle, InvalidateFlags::NoErase);
     331             :                 }
     332             :             }
     333         593 :         }
     334             : 
     335             :         // stripe support ColA
     336        1312 :         void OverlayManager::setStripeColorA(Color aNew)
     337             :         {
     338        1312 :             if(aNew != maStripeColorA)
     339             :             {
     340           0 :                 maStripeColorA = aNew;
     341           0 :                 ImpStripeDefinitionChanged();
     342             :             }
     343        1312 :         }
     344             : 
     345             :         // stripe support ColB
     346        1312 :         void OverlayManager::setStripeColorB(Color aNew)
     347             :         {
     348        1312 :             if(aNew != maStripeColorB)
     349             :             {
     350           0 :                 maStripeColorB = aNew;
     351           0 :                 ImpStripeDefinitionChanged();
     352             :             }
     353        1312 :         }
     354             : 
     355             :         // stripe support StripeLengthPixel
     356        1312 :         void OverlayManager::setStripeLengthPixel(sal_uInt32 nNew)
     357             :         {
     358        1312 :             if(nNew != mnStripeLengthPixel)
     359             :             {
     360        1312 :                 mnStripeLengthPixel = nNew;
     361        1312 :                 ImpStripeDefinitionChanged();
     362             :             }
     363        1312 :         }
     364             : 
     365             :     } // end of namespace overlay
     366             : } // end of namespace sdr
     367             : 
     368             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11