LCOV - code coverage report
Current view: top level - libreoffice/drawinglayer/source/primitive2d - sceneprimitive2d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 211 0.0 %
Date: 2012-12-27 Functions: 0 11 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             : #include <drawinglayer/primitive2d/sceneprimitive2d.hxx>
      21             : #include <basegfx/tools/canvastools.hxx>
      22             : #include <basegfx/polygon/b2dpolygontools.hxx>
      23             : #include <basegfx/polygon/b2dpolygon.hxx>
      24             : #include <basegfx/polygon/b2dpolygonclipper.hxx>
      25             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      26             : #include <basegfx/matrix/b2dhommatrix.hxx>
      27             : #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
      28             : #include <drawinglayer/processor3d/zbufferprocessor3d.hxx>
      29             : #include <drawinglayer/processor3d/shadow3dextractor.hxx>
      30             : #include <drawinglayer/geometry/viewinformation2d.hxx>
      31             : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
      32             : #include <svtools/optionsdrawinglayer.hxx>
      33             : #include <drawinglayer/processor3d/geometry2dextractor.hxx>
      34             : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
      35             : 
      36             : //////////////////////////////////////////////////////////////////////////////
      37             : 
      38             : using namespace com::sun::star;
      39             : 
      40             : //////////////////////////////////////////////////////////////////////////////
      41             : 
      42             : namespace drawinglayer
      43             : {
      44             :     namespace primitive2d
      45             :     {
      46           0 :         bool ScenePrimitive2D::impGetShadow3D(const geometry::ViewInformation2D& /*rViewInformation*/) const
      47             :         {
      48           0 :             ::osl::MutexGuard aGuard( m_aMutex );
      49             : 
      50             :             // create on demand
      51           0 :             if(!mbShadow3DChecked && getChildren3D().hasElements())
      52             :             {
      53           0 :                 basegfx::B3DVector aLightNormal;
      54           0 :                 const double fShadowSlant(getSdrSceneAttribute().getShadowSlant());
      55           0 :                 const basegfx::B3DRange aScene3DRange(primitive3d::getB3DRangeFromPrimitive3DSequence(getChildren3D(), getViewInformation3D()));
      56             : 
      57           0 :                 if(maSdrLightingAttribute.getLightVector().size())
      58             :                 {
      59             :                     // get light normal from first light and normalize
      60           0 :                     aLightNormal = maSdrLightingAttribute.getLightVector()[0].getDirection();
      61           0 :                     aLightNormal.normalize();
      62             :                 }
      63             : 
      64             :                 // create shadow extraction processor
      65             :                 processor3d::Shadow3DExtractingProcessor aShadowProcessor(
      66           0 :                     getViewInformation3D(),
      67           0 :                     getObjectTransformation(),
      68             :                     aLightNormal,
      69             :                     fShadowSlant,
      70           0 :                     aScene3DRange);
      71             : 
      72             :                 // process local primitives
      73           0 :                 aShadowProcessor.process(getChildren3D());
      74             : 
      75             :                 // fetch result and set checked flag
      76           0 :                 const_cast< ScenePrimitive2D* >(this)->maShadowPrimitives = aShadowProcessor.getPrimitive2DSequence();
      77           0 :                 const_cast< ScenePrimitive2D* >(this)->mbShadow3DChecked = true;
      78             :             }
      79             : 
      80             :             // return if there are shadow primitives
      81           0 :             return maShadowPrimitives.hasElements();
      82             :         }
      83             : 
      84           0 :         void ScenePrimitive2D::calculateDiscreteSizes(
      85             :             const geometry::ViewInformation2D& rViewInformation,
      86             :             basegfx::B2DRange& rDiscreteRange,
      87             :             basegfx::B2DRange& rVisibleDiscreteRange,
      88             :             basegfx::B2DRange& rUnitVisibleRange) const
      89             :         {
      90             :             // use unit range and transform to discrete coordinates
      91           0 :             rDiscreteRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
      92           0 :             rDiscreteRange.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
      93             : 
      94             :             // clip it against discrete Viewport (if set)
      95           0 :             rVisibleDiscreteRange = rDiscreteRange;
      96             : 
      97           0 :             if(!rViewInformation.getViewport().isEmpty())
      98             :             {
      99           0 :                 rVisibleDiscreteRange.intersect(rViewInformation.getDiscreteViewport());
     100             :             }
     101             : 
     102           0 :             if(rVisibleDiscreteRange.isEmpty())
     103             :             {
     104           0 :                 rUnitVisibleRange = rVisibleDiscreteRange;
     105             :             }
     106             :             else
     107             :             {
     108             :                 // create UnitVisibleRange containing unit range values [0.0 .. 1.0] describing
     109             :                 // the relative position of rVisibleDiscreteRange inside rDiscreteRange
     110           0 :                 const double fDiscreteScaleFactorX(basegfx::fTools::equalZero(rDiscreteRange.getWidth()) ? 1.0 : 1.0 / rDiscreteRange.getWidth());
     111           0 :                 const double fDiscreteScaleFactorY(basegfx::fTools::equalZero(rDiscreteRange.getHeight()) ? 1.0 : 1.0 / rDiscreteRange.getHeight());
     112             : 
     113           0 :                 const double fMinX(basegfx::fTools::equal(rVisibleDiscreteRange.getMinX(), rDiscreteRange.getMinX())
     114             :                     ? 0.0
     115           0 :                     : (rVisibleDiscreteRange.getMinX() - rDiscreteRange.getMinX()) * fDiscreteScaleFactorX);
     116           0 :                 const double fMinY(basegfx::fTools::equal(rVisibleDiscreteRange.getMinY(), rDiscreteRange.getMinY())
     117             :                     ? 0.0
     118           0 :                     : (rVisibleDiscreteRange.getMinY() - rDiscreteRange.getMinY()) * fDiscreteScaleFactorY);
     119             : 
     120           0 :                 const double fMaxX(basegfx::fTools::equal(rVisibleDiscreteRange.getMaxX(), rDiscreteRange.getMaxX())
     121             :                     ? 1.0
     122           0 :                     : (rVisibleDiscreteRange.getMaxX() - rDiscreteRange.getMinX()) * fDiscreteScaleFactorX);
     123           0 :                 const double fMaxY(basegfx::fTools::equal(rVisibleDiscreteRange.getMaxY(), rDiscreteRange.getMaxY())
     124             :                     ? 1.0
     125           0 :                     : (rVisibleDiscreteRange.getMaxY() - rDiscreteRange.getMinY()) * fDiscreteScaleFactorY);
     126             : 
     127           0 :                 rUnitVisibleRange = basegfx::B2DRange(fMinX, fMinY, fMaxX, fMaxY);
     128             :             }
     129           0 :         }
     130             : 
     131           0 :         Primitive2DSequence ScenePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
     132             :         {
     133           0 :             Primitive2DSequence aRetval;
     134             : 
     135             :             // create 2D shadows from contained 3D primitives. This creates the shadow primitives on demand and tells if
     136             :             // there are some or not. Do this at start, the shadow might still be visible even when the scene is not
     137           0 :             if(impGetShadow3D(rViewInformation))
     138             :             {
     139             :                 // test visibility
     140             :                 const basegfx::B2DRange aShadow2DRange(
     141           0 :                     getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
     142             :                 const basegfx::B2DRange aViewRange(
     143           0 :                     rViewInformation.getViewport());
     144             : 
     145           0 :                 if(aViewRange.isEmpty() || aShadow2DRange.overlaps(aViewRange))
     146             :                 {
     147             :                     // add extracted 2d shadows (before 3d scene creations itself)
     148           0 :                     aRetval = maShadowPrimitives;
     149             :                 }
     150             :             }
     151             : 
     152             :             // get the involved ranges (see helper method calculateDiscreteSizes for details)
     153           0 :             basegfx::B2DRange aDiscreteRange;
     154           0 :             basegfx::B2DRange aVisibleDiscreteRange;
     155           0 :             basegfx::B2DRange aUnitVisibleRange;
     156             : 
     157           0 :             calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
     158             : 
     159           0 :             if(!aVisibleDiscreteRange.isEmpty())
     160             :             {
     161             :                 // test if discrete view size (pixel) maybe too big and limit it
     162           0 :                 double fViewSizeX(aVisibleDiscreteRange.getWidth());
     163           0 :                 double fViewSizeY(aVisibleDiscreteRange.getHeight());
     164           0 :                 const double fViewVisibleArea(fViewSizeX * fViewSizeY);
     165           0 :                 const SvtOptionsDrawinglayer aDrawinglayerOpt;
     166           0 :                 const double fMaximumVisibleArea(aDrawinglayerOpt.GetQuadratic3DRenderLimit());
     167           0 :                 double fReduceFactor(1.0);
     168             : 
     169           0 :                 if(fViewVisibleArea > fMaximumVisibleArea)
     170             :                 {
     171           0 :                     fReduceFactor = sqrt(fMaximumVisibleArea / fViewVisibleArea);
     172           0 :                     fViewSizeX *= fReduceFactor;
     173           0 :                     fViewSizeY *= fReduceFactor;
     174             :                 }
     175             : 
     176           0 :                 if(rViewInformation.getReducedDisplayQuality())
     177             :                 {
     178             :                     // when reducing the visualisation is allowed (e.g. an OverlayObject
     179             :                     // only needed for dragging), reduce resolution extra
     180             :                     // to speed up dragging interactions
     181           0 :                     const double fArea(fViewSizeX * fViewSizeY);
     182           0 :                     double fReducedVisualisationFactor(1.0 / (sqrt(fArea) * (1.0 / 170.0)));
     183             : 
     184           0 :                     if(fReducedVisualisationFactor > 1.0)
     185             :                     {
     186           0 :                         fReducedVisualisationFactor = 1.0;
     187             :                     }
     188           0 :                     else if(fReducedVisualisationFactor < 0.20)
     189             :                     {
     190           0 :                         fReducedVisualisationFactor = 0.20;
     191             :                     }
     192             : 
     193           0 :                     if(fReducedVisualisationFactor != 1.0)
     194             :                     {
     195           0 :                         fReduceFactor *= fReducedVisualisationFactor;
     196           0 :                         fViewSizeX *= fReducedVisualisationFactor;
     197           0 :                         fViewSizeY *= fReducedVisualisationFactor;
     198             :                     }
     199             :                 }
     200             : 
     201             :                 // determine the oversample value
     202             :                 static sal_uInt16 nDefaultOversampleValue(3);
     203           0 :                 const sal_uInt16 nOversampleValue(aDrawinglayerOpt.IsAntiAliasing() ? nDefaultOversampleValue : 0);
     204             : 
     205           0 :                 geometry::ViewInformation3D aViewInformation3D(getViewInformation3D());
     206             :                 {
     207             :                     // calculate a transformation from DiscreteRange to evtl. rotated/sheared content.
     208             :                     // Start with full transformation from object to discrete units
     209           0 :                     basegfx::B2DHomMatrix aObjToUnit(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
     210             : 
     211             :                     // bring to unit coordinates by applying inverse DiscreteRange
     212           0 :                     aObjToUnit.translate(-aDiscreteRange.getMinX(), -aDiscreteRange.getMinY());
     213           0 :                     aObjToUnit.scale(1.0 / aDiscreteRange.getWidth(), 1.0 / aDiscreteRange.getHeight());
     214             : 
     215             :                     // calculate transformed user coordinate system
     216           0 :                     const basegfx::B2DPoint aStandardNull(0.0, 0.0);
     217           0 :                     const basegfx::B2DPoint aUnitRangeTopLeft(aObjToUnit * aStandardNull);
     218           0 :                     const basegfx::B2DVector aStandardXAxis(1.0, 0.0);
     219           0 :                     const basegfx::B2DVector aUnitRangeXAxis(aObjToUnit * aStandardXAxis);
     220           0 :                     const basegfx::B2DVector aStandardYAxis(0.0, 1.0);
     221           0 :                     const basegfx::B2DVector aUnitRangeYAxis(aObjToUnit * aStandardYAxis);
     222             : 
     223           0 :                     if(!aUnitRangeTopLeft.equal(aStandardNull) || !aUnitRangeXAxis.equal(aStandardXAxis) || !aUnitRangeYAxis.equal(aStandardYAxis))
     224             :                     {
     225             :                         // build transformation from unit range to user coordinate system; the unit range
     226             :                         // X and Y axes are the column vectors, the null point is the offset
     227           0 :                         basegfx::B2DHomMatrix aUnitRangeToUser;
     228             : 
     229             :                         aUnitRangeToUser.set3x2(
     230             :                             aUnitRangeXAxis.getX(), aUnitRangeYAxis.getX(), aUnitRangeTopLeft.getX(),
     231           0 :                             aUnitRangeXAxis.getY(), aUnitRangeYAxis.getY(), aUnitRangeTopLeft.getY());
     232             : 
     233             :                         // decompose to allow to apply this to the 3D transformation
     234           0 :                         basegfx::B2DVector aScale, aTranslate;
     235             :                         double fRotate, fShearX;
     236           0 :                         aUnitRangeToUser.decompose(aScale, aTranslate, fRotate, fShearX);
     237             : 
     238             :                         // apply before DeviceToView and after Projection, 3D is in range [-1.0 .. 1.0] in X,Y and Z
     239             :                         // and not yet flipped in Y
     240           0 :                         basegfx::B3DHomMatrix aExtendedProjection(aViewInformation3D.getProjection());
     241             : 
     242             :                         // bring to unit coordiantes, flip Y, leave Z unchanged
     243           0 :                         aExtendedProjection.scale(0.5, -0.5, 1.0);
     244           0 :                         aExtendedProjection.translate(0.5, 0.5, 0.0);
     245             : 
     246             :                         // apply extra; Y is flipped now, go with positive shear and rotate values
     247           0 :                         aExtendedProjection.scale(aScale.getX(), aScale.getY(), 1.0);
     248           0 :                         aExtendedProjection.shearXZ(fShearX, 0.0);
     249           0 :                         aExtendedProjection.rotate(0.0, 0.0, fRotate);
     250           0 :                         aExtendedProjection.translate(aTranslate.getX(), aTranslate.getY(), 0.0);
     251             : 
     252             :                         // back to state after projection
     253           0 :                         aExtendedProjection.translate(-0.5, -0.5, 0.0);
     254           0 :                         aExtendedProjection.scale(2.0, -2.0, 1.0);
     255             : 
     256             :                         aViewInformation3D = geometry::ViewInformation3D(
     257           0 :                             aViewInformation3D.getObjectTransformation(),
     258           0 :                             aViewInformation3D.getOrientation(),
     259             :                             aExtendedProjection,
     260           0 :                             aViewInformation3D.getDeviceToView(),
     261             :                             aViewInformation3D.getViewTime(),
     262           0 :                             aViewInformation3D.getExtendedInformationSequence());
     263           0 :                     }
     264             :                 }
     265             : 
     266             :                 // calculate logic render size in world coordinates for usage in renderer
     267           0 :                 const basegfx::B2DHomMatrix aInverseOToV(rViewInformation.getInverseObjectToViewTransformation());
     268           0 :                 const double fLogicX((aInverseOToV * basegfx::B2DVector(aDiscreteRange.getWidth() * fReduceFactor, 0.0)).getLength());
     269           0 :                 const double fLogicY((aInverseOToV * basegfx::B2DVector(0.0, aDiscreteRange.getHeight() * fReduceFactor)).getLength());
     270             : 
     271             :                 // use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process
     272             :                 processor3d::ZBufferProcessor3D aZBufferProcessor3D(
     273             :                     aViewInformation3D,
     274             :                     rViewInformation,
     275           0 :                     getSdrSceneAttribute(),
     276           0 :                     getSdrLightingAttribute(),
     277             :                     fLogicX,
     278             :                     fLogicY,
     279             :                     aUnitVisibleRange,
     280           0 :                     nOversampleValue);
     281             : 
     282           0 :                 aZBufferProcessor3D.process(getChildren3D());
     283           0 :                 aZBufferProcessor3D.finish();
     284             : 
     285           0 :                 const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = aZBufferProcessor3D.getBitmapEx();
     286           0 :                 const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
     287             : 
     288           0 :                 if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())
     289             :                 {
     290             :                     // create transform for the created bitmap in discrete coordinates first.
     291           0 :                     basegfx::B2DHomMatrix aNew2DTransform;
     292             : 
     293           0 :                     aNew2DTransform.set(0, 0, aVisibleDiscreteRange.getWidth());
     294           0 :                     aNew2DTransform.set(1, 1, aVisibleDiscreteRange.getHeight());
     295           0 :                     aNew2DTransform.set(0, 2, aVisibleDiscreteRange.getMinX());
     296           0 :                     aNew2DTransform.set(1, 2, aVisibleDiscreteRange.getMinY());
     297             : 
     298             :                     // transform back to world coordinates for usage in primitive creation
     299           0 :                     aNew2DTransform *= aInverseOToV;
     300             : 
     301             :                     // create bitmap primitive and add
     302           0 :                     const Primitive2DReference xRef(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
     303           0 :                     appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef);
     304             : 
     305             :                     // test: Allow to add an outline in the debugger when tests are needed
     306             :                     static bool bAddOutlineToCreated3DSceneRepresentation(false);
     307             : 
     308           0 :                     if(bAddOutlineToCreated3DSceneRepresentation)
     309             :                     {
     310           0 :                         basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon());
     311           0 :                         aOutline.transform(aNew2DTransform);
     312           0 :                         const Primitive2DReference xRef2(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0)));
     313           0 :                         appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef2);
     314           0 :                     }
     315           0 :                 }
     316             :             }
     317             : 
     318           0 :             return aRetval;
     319             :         }
     320             : 
     321           0 :         Primitive2DSequence ScenePrimitive2D::getGeometry2D() const
     322             :         {
     323           0 :             Primitive2DSequence aRetval;
     324             : 
     325             :             // create 2D projected geometry from 3D geometry
     326           0 :             if(getChildren3D().hasElements())
     327             :             {
     328             :                 // create 2D geometry extraction processor
     329             :                 processor3d::Geometry2DExtractingProcessor aGeometryProcessor(
     330           0 :                     getViewInformation3D(),
     331           0 :                     getObjectTransformation());
     332             : 
     333             :                 // process local primitives
     334           0 :                 aGeometryProcessor.process(getChildren3D());
     335             : 
     336             :                 // fetch result
     337           0 :                 aRetval = aGeometryProcessor.getPrimitive2DSequence();
     338             :             }
     339             : 
     340           0 :             return aRetval;
     341             :         }
     342             : 
     343           0 :         Primitive2DSequence ScenePrimitive2D::getShadow2D(const geometry::ViewInformation2D& rViewInformation) const
     344             :         {
     345           0 :             Primitive2DSequence aRetval;
     346             : 
     347             :             // create 2D shadows from contained 3D primitives
     348           0 :             if(impGetShadow3D(rViewInformation))
     349             :             {
     350             :                 // add extracted 2d shadows (before 3d scene creations itself)
     351           0 :                 aRetval = maShadowPrimitives;
     352             :             }
     353             : 
     354           0 :             return aRetval;
     355             :         }
     356             : 
     357           0 :         bool ScenePrimitive2D::tryToCheckLastVisualisationDirectHit(const basegfx::B2DPoint& rLogicHitPoint, bool& o_rResult) const
     358             :         {
     359           0 :             if(!maOldRenderedBitmap.IsEmpty() && !maOldUnitVisiblePart.isEmpty())
     360             :             {
     361           0 :                 basegfx::B2DHomMatrix aInverseSceneTransform(getObjectTransformation());
     362           0 :                 aInverseSceneTransform.invert();
     363           0 :                 const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rLogicHitPoint);
     364             : 
     365           0 :                 if(maOldUnitVisiblePart.isInside(aRelativePoint))
     366             :                 {
     367             :                     // calculate coordinates relative to visualized part
     368           0 :                     double fDivisorX(maOldUnitVisiblePart.getWidth());
     369           0 :                     double fDivisorY(maOldUnitVisiblePart.getHeight());
     370             : 
     371           0 :                     if(basegfx::fTools::equalZero(fDivisorX))
     372             :                     {
     373           0 :                         fDivisorX = 1.0;
     374             :                     }
     375             : 
     376           0 :                     if(basegfx::fTools::equalZero(fDivisorY))
     377             :                     {
     378           0 :                         fDivisorY = 1.0;
     379             :                     }
     380             : 
     381           0 :                     const double fRelativeX((aRelativePoint.getX() - maOldUnitVisiblePart.getMinX()) / fDivisorX);
     382           0 :                     const double fRelativeY((aRelativePoint.getY() - maOldUnitVisiblePart.getMinY()) / fDivisorY);
     383             : 
     384             :                     // combine with real BitmapSizePixel to get bitmap coordinates
     385           0 :                     const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
     386           0 :                     const sal_Int32 nX(basegfx::fround(fRelativeX * aBitmapSizePixel.Width()));
     387           0 :                     const sal_Int32 nY(basegfx::fround(fRelativeY * aBitmapSizePixel.Height()));
     388             : 
     389             :                     // try to get a statement about transparency in that pixel
     390           0 :                     o_rResult = (0xff != maOldRenderedBitmap.GetTransparency(nX, nY));
     391           0 :                     return true;
     392           0 :                 }
     393             :             }
     394             : 
     395           0 :             return false;
     396             :         }
     397             : 
     398           0 :         ScenePrimitive2D::ScenePrimitive2D(
     399             :             const primitive3d::Primitive3DSequence& rxChildren3D,
     400             :             const attribute::SdrSceneAttribute& rSdrSceneAttribute,
     401             :             const attribute::SdrLightingAttribute& rSdrLightingAttribute,
     402             :             const basegfx::B2DHomMatrix& rObjectTransformation,
     403             :             const geometry::ViewInformation3D& rViewInformation3D)
     404             :         :   BufferedDecompositionPrimitive2D(),
     405             :             mxChildren3D(rxChildren3D),
     406             :             maSdrSceneAttribute(rSdrSceneAttribute),
     407             :             maSdrLightingAttribute(rSdrLightingAttribute),
     408             :             maObjectTransformation(rObjectTransformation),
     409             :             maViewInformation3D(rViewInformation3D),
     410             :             maShadowPrimitives(),
     411             :             mbShadow3DChecked(false),
     412             :             mfOldDiscreteSizeX(0.0),
     413             :             mfOldDiscreteSizeY(0.0),
     414             :             maOldUnitVisiblePart(),
     415           0 :             maOldRenderedBitmap()
     416             :         {
     417           0 :         }
     418             : 
     419           0 :         bool ScenePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
     420             :         {
     421           0 :             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
     422             :             {
     423           0 :                 const ScenePrimitive2D& rCompare = (ScenePrimitive2D&)rPrimitive;
     424             : 
     425           0 :                 return (primitive3d::arePrimitive3DSequencesEqual(getChildren3D(), rCompare.getChildren3D())
     426           0 :                     && getSdrSceneAttribute() == rCompare.getSdrSceneAttribute()
     427           0 :                     && getSdrLightingAttribute() == rCompare.getSdrLightingAttribute()
     428           0 :                     && getObjectTransformation() == rCompare.getObjectTransformation()
     429           0 :                     && getViewInformation3D() == rCompare.getViewInformation3D());
     430             :             }
     431             : 
     432           0 :             return false;
     433             :         }
     434             : 
     435           0 :         basegfx::B2DRange ScenePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
     436             :         {
     437             :             // transform unit range to discrete coordinate range
     438           0 :             basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
     439           0 :             aRetval.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
     440             : 
     441             :             // force to discrete expanded bounds (it grows, so expanding works perfectly well)
     442           0 :             aRetval.expand(basegfx::B2DTuple(floor(aRetval.getMinX()), floor(aRetval.getMinY())));
     443           0 :             aRetval.expand(basegfx::B2DTuple(ceil(aRetval.getMaxX()), ceil(aRetval.getMaxY())));
     444             : 
     445             :             // transform back from discrete (view) to world coordinates
     446           0 :             aRetval.transform(rViewInformation.getInverseObjectToViewTransformation());
     447             : 
     448             :             // expand by evtl. existing shadow primitives
     449           0 :             if(impGetShadow3D(rViewInformation))
     450             :             {
     451           0 :                 const basegfx::B2DRange aShadow2DRange(getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
     452             : 
     453           0 :                 if(!aShadow2DRange.isEmpty())
     454             :                 {
     455           0 :                     aRetval.expand(aShadow2DRange);
     456             :                 }
     457             :             }
     458             : 
     459           0 :             return aRetval;
     460             :         }
     461             : 
     462           0 :         Primitive2DSequence ScenePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
     463             :         {
     464           0 :             ::osl::MutexGuard aGuard( m_aMutex );
     465             : 
     466             :             // get the involved ranges (see helper method calculateDiscreteSizes for details)
     467           0 :             basegfx::B2DRange aDiscreteRange;
     468           0 :             basegfx::B2DRange aUnitVisibleRange;
     469           0 :             bool bNeedNewDecomposition(false);
     470           0 :             bool bDiscreteSizesAreCalculated(false);
     471             : 
     472           0 :             if(getBuffered2DDecomposition().hasElements())
     473             :             {
     474           0 :                 basegfx::B2DRange aVisibleDiscreteRange;
     475           0 :                 calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
     476           0 :                 bDiscreteSizesAreCalculated = true;
     477             : 
     478             :                 // needs to be painted when the new part is not part of the last
     479             :                 // decomposition
     480           0 :                 if(!maOldUnitVisiblePart.isInside(aUnitVisibleRange))
     481             :                 {
     482           0 :                     bNeedNewDecomposition = true;
     483             :                 }
     484             : 
     485             :                 // display has changed and cannot be reused when resolution got bigger. It
     486             :                 // can be reused when resolution got smaller, though.
     487           0 :                 if(!bNeedNewDecomposition)
     488             :                 {
     489           0 :                     if(basegfx::fTools::more(aDiscreteRange.getWidth(), mfOldDiscreteSizeX) ||
     490           0 :                         basegfx::fTools::more(aDiscreteRange.getHeight(), mfOldDiscreteSizeY))
     491             :                     {
     492           0 :                         bNeedNewDecomposition = true;
     493             :                     }
     494             :                 }
     495             :             }
     496             : 
     497           0 :             if(bNeedNewDecomposition)
     498             :             {
     499             :                 // conditions of last local decomposition have changed, delete
     500           0 :                 const_cast< ScenePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
     501             :             }
     502             : 
     503           0 :             if(!getBuffered2DDecomposition().hasElements())
     504             :             {
     505           0 :                 if(!bDiscreteSizesAreCalculated)
     506             :                 {
     507           0 :                     basegfx::B2DRange aVisibleDiscreteRange;
     508           0 :                     calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
     509             :                 }
     510             : 
     511             :                 // remember last used NewDiscreteSize and NewUnitVisiblePart
     512           0 :                 ScenePrimitive2D* pThat = const_cast< ScenePrimitive2D* >(this);
     513           0 :                 pThat->mfOldDiscreteSizeX = aDiscreteRange.getWidth();
     514           0 :                 pThat->mfOldDiscreteSizeY = aDiscreteRange.getHeight();
     515           0 :                 pThat->maOldUnitVisiblePart = aUnitVisibleRange;
     516             :             }
     517             : 
     518             :             // use parent implementation
     519           0 :             return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
     520             :         }
     521             : 
     522             :         // provide unique ID
     523           0 :         ImplPrimitrive2DIDBlock(ScenePrimitive2D, PRIMITIVE2D_ID_SCENEPRIMITIVE2D)
     524             : 
     525             :     } // end of namespace primitive2d
     526             : } // end of namespace drawinglayer
     527             : 
     528             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10