summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@Sun.COM>2009-10-07 14:25:40 +0200
committerArmin Le Grand <Armin.Le.Grand@Sun.COM>2009-10-07 14:25:40 +0200
commit407f7ae14844d0e55b9f0f87a19a7208762b05ed (patch)
tree2a24b06f3a318077961b66210bd097fe9aa66262
parent78fb1283ea0f5a059740790e3933fe60b520c7cf (diff)
#i105323# added FastPath for 3D scene HitTest for 3d CustomShapes by re-using the buffered last render result from the ScenePrimitive2D
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx17
-rw-r--r--drawinglayer/source/primitive2d/sceneprimitive2d.cxx116
-rw-r--r--drawinglayer/source/processor2d/hittestprocessor2d.cxx169
-rw-r--r--svx/inc/svx/svddrgmt.hxx20
-rw-r--r--svx/source/svdraw/svddrgmt.cxx50
5 files changed, 255 insertions, 117 deletions
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx
index 1cb433e6bff1..a86e32adca26 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx
@@ -41,6 +41,7 @@
#include <drawinglayer/attribute/sdrattribute3d.hxx>
#include <drawinglayer/geometry/viewinformation3d.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <vcl/bitmapex.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -70,9 +71,13 @@ namespace drawinglayer
double mfOldDiscreteSizeY;
basegfx::B2DRange maOldUnitVisiblePart;
+ // the last created BitmapEx, e.g. for fast HitTest. This does not really need
+ // memory since BitmapEx is internally RefCounted
+ BitmapEx maOldRenderedBitmap;
+
// private helpers
bool impGetShadow3D(const geometry::ViewInformation2D& rViewInformation) const;
- void calculateDsicreteSizes(
+ void calculateDiscreteSizes(
const geometry::ViewInformation2D& rViewInformation,
basegfx::B2DRange& rDiscreteRange,
basegfx::B2DRange& rVisibleDiscreteRange,
@@ -90,6 +95,16 @@ namespace drawinglayer
Primitive2DSequence getGeometry2D() const;
Primitive2DSequence getShadow2D(const geometry::ViewInformation2D& rViewInformation) const;
+ // Fast HitTest which uses the last buffered BitmapEx from the last
+ // rendered area if available. The return value describes if the check
+ // could be done with the current information, so do NOT use o_rResult
+ // when it returns false. o_rResult will be changed on return true and
+ // then contains a definitive answer if content of this scene is hit or
+ // not. On return false, it is normally necessary to use the geometric
+ // HitTest (see CutFindProcessor usages). The given HitPoint
+ // has to be in logic coordinates in scene's ObjectCoordinateSystem.
+ bool tryToCheckLastVisualisationDirectHit(const basegfx::B2DPoint& rLogicHitPoint, bool& o_rResult) const;
+
// constructor/destructor
ScenePrimitive2D(
const primitive3d::Primitive3DSequence& rxChildren3D,
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index 7fa9fdec336c..6b346d5abdc0 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -100,7 +100,7 @@ namespace drawinglayer
return maShadowPrimitives.hasElements();
}
- void ScenePrimitive2D::calculateDsicreteSizes(
+ void ScenePrimitive2D::calculateDiscreteSizes(
const geometry::ViewInformation2D& rViewInformation,
basegfx::B2DRange& rDiscreteRange,
basegfx::B2DRange& rVisibleDiscreteRange,
@@ -110,23 +110,12 @@ namespace drawinglayer
rDiscreteRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
rDiscreteRange.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
- // force to discrete expanded bounds (it grows, so expanding works perfectly well)
- rDiscreteRange.expand(basegfx::B2DTuple(floor(rDiscreteRange.getMinX()), floor(rDiscreteRange.getMinY())));
- rDiscreteRange.expand(basegfx::B2DTuple(ceil(rDiscreteRange.getMaxX()), ceil(rDiscreteRange.getMaxY())));
-
// clip it against discrete Viewport (if set)
rVisibleDiscreteRange = rDiscreteRange;
if(!rViewInformation.getViewport().isEmpty())
{
rVisibleDiscreteRange.intersect(rViewInformation.getDiscreteViewport());
-
- if(!rVisibleDiscreteRange.isEmpty())
- {
- // force to discrete expanded bounds, too
- rVisibleDiscreteRange.expand(basegfx::B2DTuple(floor(rVisibleDiscreteRange.getMinX()), floor(rVisibleDiscreteRange.getMinY())));
- rVisibleDiscreteRange.expand(basegfx::B2DTuple(ceil(rVisibleDiscreteRange.getMaxX()), ceil(rVisibleDiscreteRange.getMaxY())));
- }
}
if(rVisibleDiscreteRange.isEmpty())
@@ -177,11 +166,11 @@ namespace drawinglayer
}
}
- // get the involved ranges (see helper method calculateDsicreteSizes for details)
+ // get the involved ranges (see helper method calculateDiscreteSizes for details)
basegfx::B2DRange aDiscreteRange;
basegfx::B2DRange aVisibleDiscreteRange;
basegfx::B2DRange aUnitVisibleRange;
- calculateDsicreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
+ calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
if(!aVisibleDiscreteRange.isEmpty())
{
@@ -204,11 +193,25 @@ namespace drawinglayer
{
// when reducing the visualisation is allowed (e.g. an OverlayObject
// only needed for dragging), reduce resolution extra
- // to speed up dragging interactions (1/4th currently)
- const double fReducedVisualisationFactor(0.25);
- fReduceFactor *= fReducedVisualisationFactor;
- fViewSizeX *= fReducedVisualisationFactor;
- fViewSizeY *= fReducedVisualisationFactor;
+ // to speed up dragging interactions
+ const double fArea(fViewSizeX * fViewSizeY);
+ double fReducedVisualisationFactor(1.0 / (sqrt(fArea) * (1.0 / 170.0)));
+
+ if(fReducedVisualisationFactor > 1.0)
+ {
+ fReducedVisualisationFactor = 1.0;
+ }
+ else if(fReducedVisualisationFactor < 0.20)
+ {
+ fReducedVisualisationFactor = 0.20;
+ }
+
+ if(fReducedVisualisationFactor != 1.0)
+ {
+ fReduceFactor *= fReducedVisualisationFactor;
+ fViewSizeX *= fReducedVisualisationFactor;
+ fViewSizeY *= fReducedVisualisationFactor;
+ }
}
// calculate logic render size in world coordinates for usage in renderer
@@ -234,18 +237,16 @@ namespace drawinglayer
aZBufferProcessor3D.processNonTransparent(getChildren3D());
aZBufferProcessor3D.processTransparent(getChildren3D());
- const BitmapEx aNewBitmap(aZBufferProcessor3D.getBitmapEx());
- const Size aBitmapSizePixel(aNewBitmap.GetSizePixel());
+ const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = aZBufferProcessor3D.getBitmapEx();
+ const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())
{
// create transform for the created bitmap in discrete coordinates first.
- // #i97772# Do not forget to apply evtl. render size reduction to scaling
basegfx::B2DHomMatrix aNew2DTransform;
- const double fSizeReductionFactor(1.0 / fReduceFactor);
- aNew2DTransform.set(0, 0, (double)(aBitmapSizePixel.getWidth() - 1) * fSizeReductionFactor);
- aNew2DTransform.set(1, 1, (double)(aBitmapSizePixel.getHeight() - 1) * fSizeReductionFactor);
+ aNew2DTransform.set(0, 0, aVisibleDiscreteRange.getWidth());
+ aNew2DTransform.set(1, 1, aVisibleDiscreteRange.getHeight());
aNew2DTransform.set(0, 2, aVisibleDiscreteRange.getMinX());
aNew2DTransform.set(1, 2, aVisibleDiscreteRange.getMinY());
@@ -253,7 +254,7 @@ namespace drawinglayer
aNew2DTransform *= rViewInformation.getInverseObjectToViewTransformation();
// create bitmap primitive and add
- const Primitive2DReference xRef(new BitmapPrimitive2D(aNewBitmap, aNew2DTransform));
+ const Primitive2DReference xRef(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef);
// test: Allow to add an outline in the debugger when tests are needed
@@ -308,6 +309,47 @@ namespace drawinglayer
return aRetval;
}
+ bool ScenePrimitive2D::tryToCheckLastVisualisationDirectHit(const basegfx::B2DPoint& rLogicHitPoint, bool& o_rResult) const
+ {
+ if(!maOldRenderedBitmap.IsEmpty() && !maOldUnitVisiblePart.isEmpty())
+ {
+ basegfx::B2DHomMatrix aInverseSceneTransform(getObjectTransformation());
+ aInverseSceneTransform.invert();
+ const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rLogicHitPoint);
+
+ if(maOldUnitVisiblePart.isInside(aRelativePoint))
+ {
+ // calculate coordinates relative to visualized part
+ double fDivisorX(maOldUnitVisiblePart.getWidth());
+ double fDivisorY(maOldUnitVisiblePart.getHeight());
+
+ if(basegfx::fTools::equalZero(fDivisorX))
+ {
+ fDivisorX = 1.0;
+ }
+
+ if(basegfx::fTools::equalZero(fDivisorY))
+ {
+ fDivisorY = 1.0;
+ }
+
+ const double fRelativeX((aRelativePoint.getX() - maOldUnitVisiblePart.getMinX()) / fDivisorX);
+ const double fRelativeY((aRelativePoint.getY() - maOldUnitVisiblePart.getMinY()) / fDivisorY);
+
+ // combine with real BitmapSizePixel to get bitmap coordinates
+ const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
+ const sal_Int32 nX(basegfx::fround(fRelativeX * aBitmapSizePixel.Width()));
+ const sal_Int32 nY(basegfx::fround(fRelativeY * aBitmapSizePixel.Height()));
+
+ // try to get a statement about transparency in that pixel
+ o_rResult = (0xff != maOldRenderedBitmap.GetTransparency(nX, nY));
+ return true;
+ }
+ }
+
+ return false;
+ }
+
ScenePrimitive2D::ScenePrimitive2D(
const primitive3d::Primitive3DSequence& rxChildren3D,
const attribute::SdrSceneAttribute& rSdrSceneAttribute,
@@ -324,7 +366,8 @@ namespace drawinglayer
mbShadow3DChecked(false),
mfOldDiscreteSizeX(0.0),
mfOldDiscreteSizeY(0.0),
- maOldUnitVisiblePart()
+ maOldUnitVisiblePart(),
+ maOldRenderedBitmap()
{
}
@@ -375,7 +418,7 @@ namespace drawinglayer
{
::osl::MutexGuard aGuard( m_aMutex );
- // get the involved ranges (see helper method calculateDsicreteSizes for details)
+ // get the involved ranges (see helper method calculateDiscreteSizes for details)
basegfx::B2DRange aDiscreteRange;
basegfx::B2DRange aUnitVisibleRange;
bool bNeedNewDecomposition(false);
@@ -384,21 +427,22 @@ namespace drawinglayer
if(getBuffered2DDecomposition().hasElements())
{
basegfx::B2DRange aVisibleDiscreteRange;
- calculateDsicreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
+ calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
bDiscreteSizesAreCalculated = true;
- // display has changed and cannot be reused when resolution did change
- if(!basegfx::fTools::equal(aDiscreteRange.getWidth(), mfOldDiscreteSizeX) ||
- !basegfx::fTools::equal(aDiscreteRange.getHeight(), mfOldDiscreteSizeY))
+ // needs to be painted when the new part is not part of the last
+ // decomposition
+ if(!maOldUnitVisiblePart.isInside(aUnitVisibleRange))
{
bNeedNewDecomposition = true;
}
+ // display has changed and cannot be reused when resolution got bigger. It
+ // can be reused when resolution got smaller, though.
if(!bNeedNewDecomposition)
{
- // needs to be painted when the new part is not part of the last
- // decomposition
- if(!maOldUnitVisiblePart.isInside(aUnitVisibleRange))
+ if(basegfx::fTools::more(aDiscreteRange.getWidth(), mfOldDiscreteSizeX) ||
+ basegfx::fTools::more(aDiscreteRange.getHeight(), mfOldDiscreteSizeY))
{
bNeedNewDecomposition = true;
}
@@ -416,7 +460,7 @@ namespace drawinglayer
if(!bDiscreteSizesAreCalculated)
{
basegfx::B2DRange aVisibleDiscreteRange;
- calculateDsicreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
+ calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
}
// remember last used NewDiscreteSize and NewUnitVisiblePart
diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
index 98bbe2a82cb8..09eb6e3e71f6 100644
--- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
@@ -170,102 +170,113 @@ namespace drawinglayer
{
// calculate relative point in unified 2D scene
const basegfx::B2DPoint aLogicHitPosition(getViewInformation2D().getInverseObjectToViewTransformation() * getDiscreteHitPosition());
- basegfx::B2DHomMatrix aInverseSceneTransform(rCandidate.getObjectTransformation());
- aInverseSceneTransform.invert();
- const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * aLogicHitPosition);
- // check if test point is inside scene's unified area at all
- if(aRelativePoint.getX() >= 0.0 && aRelativePoint.getX() <= 1.0
- && aRelativePoint.getY() >= 0.0 && aRelativePoint.getY() <= 1.0)
- {
- // get 3D view information
- const geometry::ViewInformation3D& rObjectViewInformation3D = rCandidate.getViewInformation3D();
+ // use bitmap check in ScenePrimitive2D
+ bool bTryFastResult(false);
- // create HitPoint Front and Back, transform to object coordinates
- basegfx::B3DHomMatrix aViewToObject(rObjectViewInformation3D.getObjectToView());
- aViewToObject.invert();
- const basegfx::B3DPoint aFront(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 0.0));
- const basegfx::B3DPoint aBack(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 1.0));
+ if(rCandidate.tryToCheckLastVisualisationDirectHit(aLogicHitPosition, bTryFastResult))
+ {
+ mbHit = bTryFastResult;
+ }
+ else
+ {
+ basegfx::B2DHomMatrix aInverseSceneTransform(rCandidate.getObjectTransformation());
+ aInverseSceneTransform.invert();
+ const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * aLogicHitPosition);
- if(!aFront.equal(aBack))
+ // check if test point is inside scene's unified area at all
+ if(aRelativePoint.getX() >= 0.0 && aRelativePoint.getX() <= 1.0
+ && aRelativePoint.getY() >= 0.0 && aRelativePoint.getY() <= 1.0)
{
- const primitive3d::Primitive3DSequence& rPrimitives = rCandidate.getChildren3D();
+ // get 3D view information
+ const geometry::ViewInformation3D& rObjectViewInformation3D = rCandidate.getViewInformation3D();
+
+ // create HitPoint Front and Back, transform to object coordinates
+ basegfx::B3DHomMatrix aViewToObject(rObjectViewInformation3D.getObjectToView());
+ aViewToObject.invert();
+ const basegfx::B3DPoint aFront(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 0.0));
+ const basegfx::B3DPoint aBack(aViewToObject * basegfx::B3DPoint(aRelativePoint.getX(), aRelativePoint.getY(), 1.0));
- if(rPrimitives.hasElements())
+ if(!aFront.equal(aBack))
{
- // make BoundVolume empty and overlapping test for speedup
- const basegfx::B3DRange aObjectRange(
- drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
- rPrimitives, rObjectViewInformation3D));
+ const primitive3d::Primitive3DSequence& rPrimitives = rCandidate.getChildren3D();
- if(!aObjectRange.isEmpty())
+ if(rPrimitives.hasElements())
{
- const basegfx::B3DRange aFrontBackRange(aFront, aBack);
+ // make BoundVolume empty and overlapping test for speedup
+ const basegfx::B3DRange aObjectRange(
+ drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
+ rPrimitives, rObjectViewInformation3D));
- if(aObjectRange.overlaps(aFrontBackRange))
+ if(!aObjectRange.isEmpty())
{
- // bound volumes hit, geometric cut tests needed
- drawinglayer::processor3d::CutFindProcessor aCutFindProcessor(
- rObjectViewInformation3D,
- aFront,
- aBack,
- true);
- aCutFindProcessor.process(rPrimitives);
-
- mbHit = (0 != aCutFindProcessor.getCutPoints().size());
+ const basegfx::B3DRange aFrontBackRange(aFront, aBack);
+
+ if(aObjectRange.overlaps(aFrontBackRange))
+ {
+ // bound volumes hit, geometric cut tests needed
+ drawinglayer::processor3d::CutFindProcessor aCutFindProcessor(
+ rObjectViewInformation3D,
+ aFront,
+ aBack,
+ true);
+ aCutFindProcessor.process(rPrimitives);
+
+ mbHit = (0 != aCutFindProcessor.getCutPoints().size());
+ }
}
}
}
}
- }
- // This is needed to check hit with 3D shadows, too. HitTest is without shadow
- // to keep compatible with previous versions. Keeping here as reference
- //
- // if(!getHit())
- // {
- // // if scene has shadow, check hit with shadow, too
- // const primitive2d::Primitive2DSequence xExtracted2DSceneShadow(rCandidate.getShadow2D(getViewInformation2D()));
- //
- // if(xExtracted2DSceneShadow.hasElements())
- // {
- // // proccess extracted 2D content
- // process(xExtracted2DSceneShadow);
- // }
- // }
-
- if(!getHit())
- {
- // empty 3D scene; Check for border hit
- basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
- aOutline.transform(rCandidate.getObjectTransformation());
+ // This is needed to check hit with 3D shadows, too. HitTest is without shadow
+ // to keep compatible with previous versions. Keeping here as reference
+ //
+ // if(!getHit())
+ // {
+ // // if scene has shadow, check hit with shadow, too
+ // const primitive2d::Primitive2DSequence xExtracted2DSceneShadow(rCandidate.getShadow2D(getViewInformation2D()));
+ //
+ // if(xExtracted2DSceneShadow.hasElements())
+ // {
+ // // proccess extracted 2D content
+ // process(xExtracted2DSceneShadow);
+ // }
+ // }
+
+ if(!getHit())
+ {
+ // empty 3D scene; Check for border hit
+ basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aOutline.transform(rCandidate.getObjectTransformation());
- mbHit = checkHairlineHitWithTolerance(aOutline, getDiscreteHitTolerance());
- }
+ mbHit = checkHairlineHitWithTolerance(aOutline, getDiscreteHitTolerance());
+ }
- // This is what the previous version did. Keeping it here for reference
- //
- // // 2D Scene primitive containing 3D stuff; extract 2D contour in world coordinates
- // // This may be refined later to an own 3D HitTest renderer which processes the 3D
- // // geometry directly
- // const primitive2d::ScenePrimitive2D& rScenePrimitive2DCandidate(static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate));
- // const primitive2d::Primitive2DSequence xExtracted2DSceneGeometry(rScenePrimitive2DCandidate.getGeometry2D());
- // const primitive2d::Primitive2DSequence xExtracted2DSceneShadow(rScenePrimitive2DCandidate.getShadow2D(getViewInformation2D()));
- //
- // if(xExtracted2DSceneGeometry.hasElements() || xExtracted2DSceneShadow.hasElements())
- // {
- // // proccess extracted 2D content
- // process(xExtracted2DSceneGeometry);
- // process(xExtracted2DSceneShadow);
- // }
- // else
- // {
- // // empty 3D scene; Check for border hit
- // const basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D()));
- // basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
- //
- // mbHit = checkHairlineHitWithTolerance(aOutline, getDiscreteHitTolerance());
- // }
+ // This is what the previous version did. Keeping it here for reference
+ //
+ // // 2D Scene primitive containing 3D stuff; extract 2D contour in world coordinates
+ // // This may be refined later to an own 3D HitTest renderer which processes the 3D
+ // // geometry directly
+ // const primitive2d::ScenePrimitive2D& rScenePrimitive2DCandidate(static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate));
+ // const primitive2d::Primitive2DSequence xExtracted2DSceneGeometry(rScenePrimitive2DCandidate.getGeometry2D());
+ // const primitive2d::Primitive2DSequence xExtracted2DSceneShadow(rScenePrimitive2DCandidate.getShadow2D(getViewInformation2D()));
+ //
+ // if(xExtracted2DSceneGeometry.hasElements() || xExtracted2DSceneShadow.hasElements())
+ // {
+ // // proccess extracted 2D content
+ // process(xExtracted2DSceneGeometry);
+ // process(xExtracted2DSceneShadow);
+ // }
+ // else
+ // {
+ // // empty 3D scene; Check for border hit
+ // const basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D()));
+ // basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
+ //
+ // mbHit = checkHairlineHitWithTolerance(aOutline, getDiscreteHitTolerance());
+ // }
+ }
}
void HitTestProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
diff --git a/svx/inc/svx/svddrgmt.hxx b/svx/inc/svx/svddrgmt.hxx
index fa4e09c9a324..91112a7dd287 100644
--- a/svx/inc/svx/svddrgmt.hxx
+++ b/svx/inc/svx/svddrgmt.hxx
@@ -107,6 +107,22 @@ public:
//////////////////////////////////////////////////////////////////////////////
+class SdrDragEntryPrimitive2DSequence : public SdrDragEntry
+{
+private:
+ drawinglayer::primitive2d::Primitive2DSequence maPrimitive2DSequence;
+
+public:
+ SdrDragEntryPrimitive2DSequence(
+ const drawinglayer::primitive2d::Primitive2DSequence& rSequence,
+ bool bAddToTransparent);
+ virtual ~SdrDragEntryPrimitive2DSequence();
+
+ virtual drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod);
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
class SdrDragEntryPointGlueDrag : public SdrDragEntry
{
private:
@@ -138,6 +154,7 @@ protected:
void clearSdrDragEntries() { for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++) { delete maSdrDragEntries[a]; } maSdrDragEntries.clear(); }
void addSdrDragEntry(SdrDragEntry* pNew) { if(pNew) { maSdrDragEntries.push_back(pNew); }}
virtual void createSdrDragEntries();
+ virtual void createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify);
// access for derivated classes to maOverlayObjectList
void clearOverlayObjectList() { maOverlayObjectList.clear(); }
@@ -236,6 +253,9 @@ private:
void ImpCheckSnap(const Point& rPt);
+protected:
+ virtual void createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify);
+
public:
TYPEINFO();
SdrDragMove(SdrDragView& rNewView);
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
index 254e5daa741f..b953e68a753d 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -207,6 +207,32 @@ drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrim
////////////////////////////////////////////////////////////////////////////////////////////////////
+SdrDragEntryPrimitive2DSequence::SdrDragEntryPrimitive2DSequence(
+ const drawinglayer::primitive2d::Primitive2DSequence& rSequence,
+ bool bAddToTransparent)
+: SdrDragEntry(),
+ maPrimitive2DSequence(rSequence)
+{
+ // add parts to transparent overlay stuff eventually
+ setAddToTransparent(bAddToTransparent);
+}
+
+SdrDragEntryPrimitive2DSequence::~SdrDragEntryPrimitive2DSequence()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPrimitive2DSequence::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
+{
+ drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ rDragMethod.getCurrentTransformation(),
+ maPrimitive2DSequence));
+
+ return drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector< basegfx::B2DPoint >& rPositions, bool bIsPointDrag)
: maPositions(rPositions),
mbIsPointDrag(bIsPointDrag)
@@ -319,6 +345,13 @@ void SdrDragMethod::createSdrDragEntries()
}
}
+void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
+{
+ // add full obejct drag; Clone() at the object has to work
+ // for this
+ addSdrDragEntry(new SdrDragEntrySdrObject(rOriginal, rObjectContact, bModify));
+}
+
void SdrDragMethod::createSdrDragEntries_SolidDrag()
{
const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
@@ -360,7 +393,7 @@ void SdrDragMethod::createSdrDragEntries_SolidDrag()
{
// add full obejct drag; Clone() at the object has to work
// for this
- addSdrDragEntry(new SdrDragEntrySdrObject(*pCandidate, rOC, true));
+ createSdrDragEntryForSdrObject(*pCandidate, rOC, true);
}
if(bAddWireframe)
@@ -1349,6 +1382,21 @@ Pointer SdrDragObjOwn::GetSdrDragPointer() const
TYPEINIT1(SdrDragMove,SdrDragMethod);
+void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool /*bModify*/)
+{
+ // for SdrDragMove, use current Primitive2DSequence of SdrObject visualisation
+ // in given ObjectContact directly
+ sdr::contact::ViewContact& rVC = rOriginal.GetViewContact();
+ sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact);
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
+ // here we want the complete primitive sequence without visibility clippings
+ rObjectContact.resetViewPort();
+
+ addSdrDragEntry(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo), true));
+}
+
void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
{
rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY()));