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

Generated by: LCOV version 1.10