summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/app/app.cxx9
-rw-r--r--drawinglayer/inc/drawinglayer/geometry/viewinformation2d.hxx7
-rw-r--r--drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx20
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx2
-rw-r--r--drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx2
-rw-r--r--drawinglayer/inc/drawinglayer/processor3d/cutfindprocessor3d.hxx86
-rw-r--r--drawinglayer/prj/d.lst2
-rw-r--r--drawinglayer/source/geometry/viewinformation2d.cxx42
-rw-r--r--drawinglayer/source/primitive2d/sceneprimitive2d.cxx148
-rw-r--r--drawinglayer/source/processor2d/contourextractor2d.cxx9
-rw-r--r--drawinglayer/source/processor2d/hittestprocessor2d.cxx160
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx6
-rw-r--r--drawinglayer/source/processor2d/vclprocessor2d.cxx92
-rw-r--r--drawinglayer/source/processor3d/cutfindprocessor3d.cxx199
-rw-r--r--drawinglayer/source/processor3d/makefile.mk1
-rw-r--r--svx/inc/svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx13
-rw-r--r--svx/inc/svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx9
-rw-r--r--svx/inc/svx/svddrgmt.hxx20
-rw-r--r--svx/source/customshapes/EnhancedCustomShape2d.cxx45
-rw-r--r--svx/source/customshapes/EnhancedCustomShape3d.cxx12
-rw-r--r--svx/source/engine3d/helperhittest3d.cxx183
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx11
-rw-r--r--svx/source/sdr/contact/viewcontactofsdrrectobj.cxx8
-rw-r--r--svx/source/sdr/overlay/overlaymanager.cxx16
-rw-r--r--svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx24
-rw-r--r--svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx10
-rw-r--r--svx/source/svdraw/svddrgmt.cxx50
27 files changed, 895 insertions, 291 deletions
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index a8ebfee188..7f937bbd79 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1738,8 +1738,15 @@ sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& r
aSeq[0] <<= bQuickstart;
// Try to instanciate quickstart service. This service is not mandatory, so
- // do nothing if service is not available.
+ // do nothing if service is not available
+
+ // #i105753# the following if was invented for performance
+ // unfortunately this broke the QUARTZ behavior which is to always run
+ // in quickstart mode since Mac applications do not usually quit
+ // when the last document closes
+ #ifndef QUARTZ
if ( bQuickstart )
+ #endif
{
Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments(
DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ),
diff --git a/drawinglayer/inc/drawinglayer/geometry/viewinformation2d.hxx b/drawinglayer/inc/drawinglayer/geometry/viewinformation2d.hxx
index 3fc837e97c..46cee65b8a 100644
--- a/drawinglayer/inc/drawinglayer/geometry/viewinformation2d.hxx
+++ b/drawinglayer/inc/drawinglayer/geometry/viewinformation2d.hxx
@@ -149,6 +149,13 @@ namespace drawinglayer
/// On-demand prepared Viewport in discrete units for convenience
const basegfx::B2DRange& getDiscreteViewport() const;
+ /** support reduced DisplayQuality, PropertyName is 'ReducedDisplayQuality'. This
+ is used e.g. to allow to lower display quality for OverlayPrimitives and
+ may lead to simpler decompositions in the local create2DDecomposition
+ implementations of the primitives
+ */
+ bool getReducedDisplayQuality() const;
+
/** Get the uno::Sequence< beans::PropertyValue > which contains all ViewInformation
Use this call if You need to extract all contained ViewInformation. The ones
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/sceneprimitive2d.hxx
index 6fc731db03..1383cc418f 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,
@@ -87,7 +92,18 @@ namespace drawinglayer
// Geometry extractor. Shadow will be added as in createLocalDecomposition, but
// the 3D content is not converted to a bitmap visualisation but to projected 2D gemetry. This
// helper is useful e.g. for Contour extraction or HitTests.
- Primitive2DSequence getGeometry2D(const geometry::ViewInformation2D& rViewInformation) const;
+ 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(
diff --git a/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx
index 4a0f1b9c29..46dd1765da 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/hittestprocessor2d.hxx
@@ -43,6 +43,7 @@
namespace basegfx { class B2DPolygon; }
namespace basegfx { class B2DPolyPolygon; }
+namespace drawinglayer { namespace primitive2d { class ScenePrimitive2D; }}
//////////////////////////////////////////////////////////////////////////////
@@ -80,6 +81,7 @@ namespace drawinglayer
bool checkFillHitWithTolerance(
const basegfx::B2DPolyPolygon& rPolyPolygon,
double fDiscreteHitTolerance);
+ void check3DHit(const primitive2d::ScenePrimitive2D& rCandidate);
public:
HitTestProcessor2D(
diff --git a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
index fcf8766dbf..75d2fe39a3 100644
--- a/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
+++ b/drawinglayer/inc/drawinglayer/processor2d/vclprocessor2d.hxx
@@ -51,6 +51,7 @@ namespace drawinglayer { namespace primitive2d {
class BitmapPrimitive2D;
class FillBitmapPrimitive2D;
class PolyPolygonGradientPrimitive2D;
+ class PolyPolygonBitmapPrimitive2D;
class PolyPolygonColorPrimitive2D;
class MetafilePrimitive2D;
class MaskPrimitive2D;
@@ -100,6 +101,7 @@ namespace drawinglayer
void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
void RenderFillBitmapPrimitive2D(const primitive2d::FillBitmapPrimitive2D& rFillBitmapCandidate);
void RenderPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate);
+ void RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate);
void RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate);
void RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rPolygonCandidate);
void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate);
diff --git a/drawinglayer/inc/drawinglayer/processor3d/cutfindprocessor3d.hxx b/drawinglayer/inc/drawinglayer/processor3d/cutfindprocessor3d.hxx
new file mode 100644
index 0000000000..de99d94f48
--- /dev/null
+++ b/drawinglayer/inc/drawinglayer/processor3d/cutfindprocessor3d.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: zbufferprocessor3d.hxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:30:18 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR3D_CUTFINDPROCESSOR3D_HXX
+#define INCLUDED_DRAWINGLAYER_PROCESSOR3D_CUTFINDPROCESSOR3D_HXX
+
+#include <drawinglayer/processor3d/defaultprocessor3d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor3d
+ {
+ class CutFindProcessor : public BaseProcessor3D
+ {
+ private:
+ // the start and stop point for the cut vector
+ basegfx::B3DPoint maFront;
+ basegfx::B3DPoint maBack;
+
+ // the found cut points
+ ::std::vector< basegfx::B3DPoint > maResult;
+
+ // #i102956# the transformation change from TransformPrimitive3D processings
+ // needs to be remembered to be able to transform found cuts to the
+ // basic coordinate system the processor starts with
+ basegfx::B3DHomMatrix maCombinedTransform;
+
+ // bitfield
+ bool mbAnyHit : 1;
+
+ // as tooling, the process() implementation takes over API handling and calls this
+ // virtual render method when the primitive implementation is BasePrimitive3D-based.
+ virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate);
+
+ public:
+ CutFindProcessor(const geometry::ViewInformation3D& rViewInformation,
+ const basegfx::B3DPoint& rFront,
+ const basegfx::B3DPoint& rBack,
+ bool bAnyHit);
+
+ // data access
+ const ::std::vector< basegfx::B3DPoint >& getCutPoints() const { return maResult; }
+ bool getAnyHit() const { return mbAnyHit; }
+ };
+ } // end of namespace processor3d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif //INCLUDED_DRAWINGLAYER_PROCESSOR3D_CUTFINDPROCESSOR3D_HXX
+
+// eof
diff --git a/drawinglayer/prj/d.lst b/drawinglayer/prj/d.lst
index 0068b32c24..1ba3c2e7b6 100644
--- a/drawinglayer/prj/d.lst
+++ b/drawinglayer/prj/d.lst
@@ -90,6 +90,8 @@ mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor2d
mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor3d
..\inc\drawinglayer\processor3d\baseprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\baseprocessor3d.hxx
+..\inc\drawinglayer\processor3d\cutfindprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\cutfindprocessor3d.hxx
+..\inc\drawinglayer\processor3d\defaultprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\defaultprocessor3d.hxx
..\inc\drawinglayer\processor3d\zbufferprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\zbufferprocessor3d.hxx
..\inc\drawinglayer\processor3d\tbufferprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\tbufferprocessor3d.hxx
diff --git a/drawinglayer/source/geometry/viewinformation2d.cxx b/drawinglayer/source/geometry/viewinformation2d.cxx
index e697540772..d7029fc067 100644
--- a/drawinglayer/source/geometry/viewinformation2d.cxx
+++ b/drawinglayer/source/geometry/viewinformation2d.cxx
@@ -81,12 +81,18 @@ namespace drawinglayer
basegfx::B2DRange maDiscreteViewport;
// the DrawPage which is target of visualisation. This is needed e.g. for
- // the view-dependent decomposition of PageNumber TextFields
+ // the view-dependent decomposition of PageNumber TextFields.
+ // This parameter is buffered here, but mainly resides in mxExtendedInformation,
+ // so it will be interpreted, but held there. It will also not be added
+ // to mxExtendedInformation in impFillViewInformationFromContent (it's there already)
uno::Reference< drawing::XDrawPage > mxVisualizedPage;
// the point in time
double mfViewTime;
+ // bitfield
+ bool mbReducedDisplayQuality : 1;
+
// the complete PropertyValue representation (if already created)
uno::Sequence< beans::PropertyValue > mxViewInformation;
@@ -125,6 +131,12 @@ namespace drawinglayer
return s_sNameProperty;
}
+ const ::rtl::OUString& getNamePropertyReducedDisplayQuality()
+ {
+ static ::rtl::OUString s_sNameProperty(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality"));
+ return s_sNameProperty;
+ }
+
void impInterpretPropertyValues(const uno::Sequence< beans::PropertyValue >& rViewParameters)
{
if(rViewParameters.hasElements())
@@ -138,8 +150,18 @@ namespace drawinglayer
for(sal_Int32 a(0); a < nCount; a++)
{
const beans::PropertyValue& rProp = rViewParameters[a];
-
- if(rProp.Name == getNamePropertyObjectTransformation())
+
+ if(rProp.Name == getNamePropertyReducedDisplayQuality())
+ {
+ // extra information; add to filtered information
+ mxExtendedInformation[nExtendedInsert++] = rProp;
+
+ // for performance reasons, also cache content locally
+ sal_Bool bSalBool = sal_True;
+ rProp.Value >>= bSalBool;
+ mbReducedDisplayQuality = bSalBool;
+ }
+ else if(rProp.Name == getNamePropertyObjectTransformation())
{
com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D;
rProp.Value >>= aAffineMatrix2D;
@@ -185,6 +207,7 @@ namespace drawinglayer
const bool bViewportUsed(!maViewport.isEmpty());
const bool bTimeUsed(0.0 < mfViewTime);
const bool bVisualizedPageUsed(mxVisualizedPage.is());
+ const bool bReducedDisplayQualityUsed(true == mbReducedDisplayQuality);
const bool bExtraInformation(mxExtendedInformation.hasElements());
sal_uInt32 nIndex(0);
const sal_uInt32 nCount(
@@ -193,6 +216,7 @@ namespace drawinglayer
(bViewportUsed ? 1 : 0) +
(bTimeUsed ? 1 : 0) +
(bVisualizedPageUsed ? 1 : 0) +
+ (bReducedDisplayQualityUsed ? 1 : 0) +
(bExtraInformation ? mxExtendedInformation.getLength() : 0));
mxViewInformation.realloc(nCount);
@@ -265,6 +289,7 @@ namespace drawinglayer
maDiscreteViewport(),
mxVisualizedPage(rxDrawPage),
mfViewTime(fViewTime),
+ mbReducedDisplayQuality(false),
mxViewInformation(),
mxExtendedInformation()
{
@@ -281,6 +306,7 @@ namespace drawinglayer
maDiscreteViewport(),
mxVisualizedPage(),
mfViewTime(),
+ mbReducedDisplayQuality(false),
mxViewInformation(rViewParameters),
mxExtendedInformation()
{
@@ -355,6 +381,11 @@ namespace drawinglayer
return mxVisualizedPage;
}
+ bool getReducedDisplayQuality() const
+ {
+ return mbReducedDisplayQuality;
+ }
+
const uno::Sequence< beans::PropertyValue >& getViewInformationSequence() const
{
if(!mxViewInformation.hasElements())
@@ -501,6 +532,11 @@ namespace drawinglayer
return mpViewInformation2D->getDiscreteViewport();
}
+ bool ViewInformation2D::getReducedDisplayQuality() const
+ {
+ return mpViewInformation2D->getReducedDisplayQuality();
+ }
+
const uno::Sequence< beans::PropertyValue >& ViewInformation2D::getViewInformationSequence() const
{
return mpViewInformation2D->getViewInformationSequence();
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index a50ab8ed05..acf3307bbf 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())
{
@@ -200,6 +189,31 @@ namespace drawinglayer
fViewSizeY *= fReduceFactor;
}
+ if(rViewInformation.getReducedDisplayQuality())
+ {
+ // when reducing the visualisation is allowed (e.g. an OverlayObject
+ // only needed for dragging), reduce resolution extra
+ // 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
basegfx::B2DVector aLogicRenderSize(
aDiscreteRange.getWidth() * fReduceFactor,
@@ -207,9 +221,8 @@ namespace drawinglayer
aLogicRenderSize *= rViewInformation.getInverseObjectToViewTransformation();
// determine the oversample value
- static bool bDoOversample(false);
static sal_uInt16 nDefaultOversampleValue(3);
- const sal_uInt16 nOversampleValue((bDoOversample || aDrawinglayerOpt.IsAntiAliasing()) ? nDefaultOversampleValue : 0);
+ const sal_uInt16 nOversampleValue(aDrawinglayerOpt.IsAntiAliasing() ? nDefaultOversampleValue : 0);
// use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process
processor3d::ZBufferProcessor3D aZBufferProcessor3D(
@@ -224,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());
@@ -243,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
@@ -262,17 +273,10 @@ namespace drawinglayer
return aRetval;
}
- Primitive2DSequence ScenePrimitive2D::getGeometry2D(const geometry::ViewInformation2D& rViewInformation) const
+ Primitive2DSequence ScenePrimitive2D::getGeometry2D() const
{
Primitive2DSequence aRetval;
- // create 2D shadows from contained 3D primitives
- if(impGetShadow3D(rViewInformation))
- {
- // add extracted 2d shadows (before 3d scene creations itself)
- aRetval = maShadowPrimitives;
- }
-
// create 2D projected geometry from 3D geometry
if(getChildren3D().hasElements())
{
@@ -284,14 +288,68 @@ namespace drawinglayer
// process local primitives
aGeometryProcessor.process(getChildren3D());
- // fetch result and append
- Primitive2DSequence a2DExtractedPrimitives(aGeometryProcessor.getPrimitive2DSequence());
- appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, a2DExtractedPrimitives);
+ // fetch result
+ aRetval = aGeometryProcessor.getPrimitive2DSequence();
}
return aRetval;
}
+ Primitive2DSequence ScenePrimitive2D::getShadow2D(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+
+ // create 2D shadows from contained 3D primitives
+ if(impGetShadow3D(rViewInformation))
+ {
+ // add extracted 2d shadows (before 3d scene creations itself)
+ aRetval = maShadowPrimitives;
+ }
+
+ 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,
@@ -308,7 +366,8 @@ namespace drawinglayer
mbShadow3DChecked(false),
mfOldDiscreteSizeX(0.0),
mfOldDiscreteSizeY(0.0),
- maOldUnitVisiblePart()
+ maOldUnitVisiblePart(),
+ maOldRenderedBitmap()
{
}
@@ -359,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);
@@ -368,21 +427,22 @@ namespace drawinglayer
if(getLocalDecomposition().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;
}
@@ -400,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/contourextractor2d.cxx b/drawinglayer/source/processor2d/contourextractor2d.cxx
index 096585d0a4..dc2cedad31 100644
--- a/drawinglayer/source/processor2d/contourextractor2d.cxx
+++ b/drawinglayer/source/processor2d/contourextractor2d.cxx
@@ -162,7 +162,8 @@ namespace drawinglayer
{
// 2D Scene primitive containing 3D stuff; extract 2D contour in world coordinates
const primitive2d::ScenePrimitive2D& rScenePrimitive2DCandidate(static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate));
- const primitive2d::Primitive2DSequence xExtracted2DSceneGeometry(rScenePrimitive2DCandidate.getGeometry2D(getViewInformation2D()));
+ const primitive2d::Primitive2DSequence xExtracted2DSceneGeometry(rScenePrimitive2DCandidate.getGeometry2D());
+ const primitive2d::Primitive2DSequence xExtracted2DSceneShadow(rScenePrimitive2DCandidate.getShadow2D(getViewInformation2D()));
// proccess content
if(xExtracted2DSceneGeometry.hasElements())
@@ -170,6 +171,12 @@ namespace drawinglayer
process(xExtracted2DSceneGeometry);
}
+ // proccess content
+ if(xExtracted2DSceneShadow.hasElements())
+ {
+ process(xExtracted2DSceneShadow);
+ }
+
break;
}
case PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D :
diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
index cc71ea19ab..16d69646cb 100644
--- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
@@ -48,6 +48,8 @@
#include <drawinglayer/primitive2d/sceneprimitive2d.hxx>
#include <drawinglayer/primitive2d/hittestprimitive2d.hxx>
#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+#include <drawinglayer/processor3d/cutfindprocessor3d.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -164,6 +166,121 @@ namespace drawinglayer
return bRetval;
}
+ void HitTestProcessor2D::check3DHit(const primitive2d::ScenePrimitive2D& rCandidate)
+ {
+ // calculate relative point in unified 2D scene
+ const basegfx::B2DPoint aLogicHitPosition(getViewInformation2D().getInverseObjectToViewTransformation() * getDiscreteHitPosition());
+
+ // use bitmap check in ScenePrimitive2D
+ bool bTryFastResult(false);
+
+ if(rCandidate.tryToCheckLastVisualisationDirectHit(aLogicHitPosition, bTryFastResult))
+ {
+ mbHit = bTryFastResult;
+ }
+ else
+ {
+ 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();
+
+ // 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(!aFront.equal(aBack))
+ {
+ const primitive3d::Primitive3DSequence& rPrimitives = rCandidate.getChildren3D();
+
+ if(rPrimitives.hasElements())
+ {
+ // make BoundVolume empty and overlapping test for speedup
+ const basegfx::B3DRange aObjectRange(
+ drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(
+ rPrimitives, rObjectViewInformation3D));
+
+ if(!aObjectRange.isEmpty())
+ {
+ 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());
+
+ 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()));
+ // if(!aRange.isEmpty())
+ // {
+ // const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
+ // mbHit = checkHairlineHitWithTolerance(aOutline, getDiscreteHitTolerance());
+ // }
+ // }
+ }
+ }
+
void HitTestProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate)
{
if(getHit())
@@ -334,25 +451,8 @@ namespace drawinglayer
{
if(!getHitTextOnly())
{
- // 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(getViewInformation2D()));
-
- if(xExtracted2DSceneGeometry.hasElements())
- {
- // proccess extracted 2D content
- process(xExtracted2DSceneGeometry);
- }
- 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());
- }
+ const primitive2d::ScenePrimitive2D& rSceneCandidate(static_cast< const primitive2d::ScenePrimitive2D& >(rCandidate));
+ check3DHit(rSceneCandidate);
}
break;
@@ -365,14 +465,23 @@ namespace drawinglayer
// ignorable primitives
break;
}
+ case PRIMITIVE2D_ID_SHADOWPRIMITIVE2D :
+ {
+ // Ignore shadows; we do not want to have shadows hittable.
+ // Remove this one to make shadows hittable on demand.
+ break;
+ }
case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D :
case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D :
{
// for text use the BoundRect of the primitive itself
const basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D()));
- basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
- mbHit = checkFillHitWithTolerance(basegfx::B2DPolyPolygon(aOutline), getDiscreteHitTolerance());
+ if(!aRange.isEmpty())
+ {
+ const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
+ mbHit = checkFillHitWithTolerance(basegfx::B2DPolyPolygon(aOutline), getDiscreteHitTolerance());
+ }
break;
}
@@ -392,9 +501,12 @@ namespace drawinglayer
// - For Bitamps, the mask and/or alpha information may be used
// - For MetaFiles, the MetaFile content may be used
const basegfx::B2DRange aRange(rCandidate.getB2DRange(getViewInformation2D()));
- basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
-
- mbHit = checkFillHitWithTolerance(basegfx::B2DPolyPolygon(aOutline), getDiscreteHitTolerance());
+
+ if(!aRange.isEmpty())
+ {
+ const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
+ mbHit = checkFillHitWithTolerance(basegfx::B2DPolyPolygon(aOutline), getDiscreteHitTolerance());
+ }
}
break;
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 705670c402..df0e6cbd27 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -218,6 +218,12 @@ namespace drawinglayer
}
break;
}
+ case PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D :
+ {
+ // direct draw of bitmap
+ RenderPolyPolygonBitmapPrimitive2D(static_cast< const primitive2d::PolyPolygonBitmapPrimitive2D& >(rCandidate));
+ break;
+ }
case PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D :
{
// direct draw of PolyPolygon with color
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index 4f803e9366..05a73e1e5e 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -565,6 +565,98 @@ namespace drawinglayer
}
}
+ // direct draw of bitmap
+ void VclProcessor2D::RenderPolyPolygonBitmapPrimitive2D(const primitive2d::PolyPolygonBitmapPrimitive2D& rPolygonCandidate)
+ {
+ bool bDone(false);
+ const basegfx::B2DPolyPolygon& rPolyPolygon = rPolygonCandidate.getB2DPolyPolygon();
+
+ if(rPolyPolygon.count())
+ {
+ const attribute::FillBitmapAttribute& rFillBitmapAttribute = rPolygonCandidate.getFillBitmap();
+ const Bitmap& rBitmap = rFillBitmapAttribute.getBitmap();
+
+ if(rBitmap.IsEmpty())
+ {
+ // empty bitmap, done
+ bDone = true;
+ }
+ else
+ {
+ // try to catch cases where the bitmap will be color-modified to a single
+ // color (e.g. shadow). This would NOT be optimizable with an alpha channel
+ // at the Bitmap which we do not have here. When this should change, this
+ // optimization has to be reworked accordingly.
+ const sal_uInt32 nBColorModifierStackCount(maBColorModifierStack.count());
+
+ if(nBColorModifierStackCount)
+ {
+ const basegfx::BColorModifier& rTopmostModifier = maBColorModifierStack.getBColorModifier(nBColorModifierStackCount - 1);
+
+ if(basegfx::BCOLORMODIFYMODE_REPLACE == rTopmostModifier.getMode())
+ {
+ // the bitmap fill is in unified color, so we can replace it with
+ // a single polygon fill. The form of the fill depends on tiling
+ if(rFillBitmapAttribute.getTiling())
+ {
+ // with tiling, fill the whole PolyPolygon with the modifier color
+ basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon);
+
+ aLocalPolyPolygon.transform(maCurrentTransformation);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor()));
+ mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
+ }
+ else
+ {
+ // without tiling, only the area common to the bitmap tile and the
+ // PolyPolygon is filled. Create the bitmap tile area in object
+ // coordinates. For this, the object transformation needs to be created
+ // from the already scaled PolyPolygon. The tile area in object
+ // coordinates wil always be non-rotated, so it's not necessary to
+ // work with a polygon here
+ basegfx::B2DRange aTileRange(rFillBitmapAttribute.getTopLeft(),
+ rFillBitmapAttribute.getTopLeft() + rFillBitmapAttribute.getSize());
+ const basegfx::B2DRange aPolyPolygonRange(rPolyPolygon.getB2DRange());
+ basegfx::B2DHomMatrix aNewObjectTransform;
+
+ aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth());
+ aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight());
+ aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX());
+ aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY());
+ aTileRange.transform(aNewObjectTransform);
+
+ // now clip the object polyPolygon against the tile range
+ // to get the common area (OR)
+ basegfx::B2DPolyPolygon aTarget = basegfx::tools::clipPolyPolygonOnRange(rPolyPolygon, aTileRange, true, false);
+
+ if(aTarget.count())
+ {
+ aTarget.transform(maCurrentTransformation);
+ mpOutputDevice->SetLineColor();
+ mpOutputDevice->SetFillColor(Color(rTopmostModifier.getBColor()));
+ mpOutputDevice->DrawPolyPolygon(aTarget);
+ }
+ }
+
+ bDone = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ // empty polyPolygon, done
+ bDone = true;
+ }
+
+ if(!bDone)
+ {
+ // use default decomposition
+ process(rPolygonCandidate.get2DDecomposition(getViewInformation2D()));
+ }
+ }
+
// direct draw of PolyPolygon with color
void VclProcessor2D::RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate)
{
diff --git a/drawinglayer/source/processor3d/cutfindprocessor3d.cxx b/drawinglayer/source/processor3d/cutfindprocessor3d.cxx
new file mode 100644
index 0000000000..5705ba74ca
--- /dev/null
+++ b/drawinglayer/source/processor3d/cutfindprocessor3d.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: zbufferprocessor3d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:09 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/processor3d/cutfindprocessor3d.hxx>
+#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
+#include <drawinglayer/primitive3d/transformprimitive3d.hxx>
+#include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
+#include <drawinglayer/primitive3d/hittestprimitive3d.hxx>
+#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
+#include <basegfx/polygon/b3dpolygon.hxx>
+#include <basegfx/polygon/b3dpolygontools.hxx>
+#include <basegfx/polygon/b3dpolypolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor3d
+ {
+ CutFindProcessor::CutFindProcessor(const geometry::ViewInformation3D& rViewInformation,
+ const basegfx::B3DPoint& rFront,
+ const basegfx::B3DPoint& rBack,
+ bool bAnyHit)
+ : BaseProcessor3D(rViewInformation),
+ maFront(rFront),
+ maBack(rBack),
+ maResult(),
+ maCombinedTransform(),
+ mbAnyHit(bAnyHit)
+ {
+ }
+
+ void CutFindProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
+ {
+ if(getAnyHit() && maResult.size())
+ {
+ // stop processing as soon as a hit was recognized
+ return;
+ }
+
+ // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch
+ switch(rCandidate.getPrimitiveID())
+ {
+ case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
+ {
+ // transform group.
+ const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
+
+ // remember old and transform front, back to object coordinates
+ const basegfx::B3DPoint aLastFront(maFront);
+ const basegfx::B3DPoint aLastBack(maBack);
+ basegfx::B3DHomMatrix aInverseTrans(rPrimitive.getTransformation());
+ aInverseTrans.invert();
+ maFront *= aInverseTrans;
+ maBack *= aInverseTrans;
+
+ // remember current and create new transformation; add new object transform from right side
+ const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
+ const geometry::ViewInformation3D aNewViewInformation3D(
+ aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
+ aLastViewInformation3D.getOrientation(),
+ aLastViewInformation3D.getProjection(),
+ aLastViewInformation3D.getDeviceToView(),
+ aLastViewInformation3D.getViewTime(),
+ aLastViewInformation3D.getExtendedInformationSequence());
+ updateViewInformation(aNewViewInformation3D);
+
+ // #i102956# remember needed back-transform for found cuts (combine from right side)
+ const basegfx::B3DHomMatrix aLastCombinedTransform(maCombinedTransform);
+ maCombinedTransform = maCombinedTransform * rPrimitive.getTransformation();
+
+ // let break down
+ process(rPrimitive.getChildren());
+
+ // restore transformations and front, back
+ maCombinedTransform = aLastCombinedTransform;
+ updateViewInformation(aLastViewInformation3D);
+ maFront = aLastFront;
+ maBack = aLastBack;
+ break;
+ }
+ case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
+ {
+ // PolygonHairlinePrimitive3D, not used for hit test with planes, ignore. This
+ // means that also thick line expansion will not be hit-tested as
+ // PolyPolygonMaterialPrimitive3D
+ break;
+ }
+ case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D :
+ {
+ // #i97321#
+ // For HatchTexturePrimitive3D, do not use the decomposition since it will produce
+ // clipped hatch lines in 3D. It can be used when the hatch also has a filling, but for
+ // simplicity, just use the children which are the PolyPolygonMaterialPrimitive3D
+ // which define the hatched areas anyways; for HitTest this is more than adequate
+ const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rCandidate);
+ process(rPrimitive.getChildren());
+ break;
+ }
+ case PRIMITIVE3D_ID_HITTESTPRIMITIVE3D :
+ {
+ // HitTestPrimitive3D, force usage due to we are doing a hit test and this
+ // primitive only gets generated on 3d objects without fill, exactly for this
+ // purpose
+ const primitive3d::HitTestPrimitive3D& rPrimitive = static_cast< const primitive3d::HitTestPrimitive3D& >(rCandidate);
+ process(rPrimitive.getChildren());
+ break;
+ }
+ case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
+ {
+ // PolyPolygonMaterialPrimitive3D
+ const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
+
+ if(!maFront.equal(maBack))
+ {
+ const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon();
+ const sal_uInt32 nPolyCount(rPolyPolygon.count());
+
+ if(nPolyCount)
+ {
+ const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(0));
+ const sal_uInt32 nPointCount(aPolygon.count());
+
+ if(nPointCount > 2)
+ {
+ const basegfx::B3DVector aPlaneNormal(aPolygon.getNormal());
+
+ if(!aPlaneNormal.equalZero())
+ {
+ const basegfx::B3DPoint aPointOnPlane(aPolygon.getB3DPoint(0));
+ double fCut(0.0);
+
+ if(basegfx::tools::getCutBetweenLineAndPlane(aPlaneNormal, aPointOnPlane, maFront, maBack, fCut))
+ {
+ const basegfx::B3DPoint aCutPoint(basegfx::interpolate(maFront, maBack, fCut));
+
+ if(basegfx::tools::isInside(rPolyPolygon, aCutPoint, false))
+ {
+ // #i102956# add result. Do not forget to do this in the coordinate
+ // system the processor get started with, so use the collected
+ // combined transformation from processed TransformPrimitive3D's
+ maResult.push_back(maCombinedTransform * aCutPoint);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ default :
+ {
+ // process recursively
+ process(rCandidate.get3DDecomposition(getViewInformation3D()));
+ break;
+ }
+ }
+ }
+ } // end of namespace processor3d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/processor3d/makefile.mk b/drawinglayer/source/processor3d/makefile.mk
index 8ca0097c43..2ae2ae52f2 100644
--- a/drawinglayer/source/processor3d/makefile.mk
+++ b/drawinglayer/source/processor3d/makefile.mk
@@ -46,6 +46,7 @@ ENABLE_EXCEPTIONS=TRUE
SLOFILES= \
$(SLO)$/baseprocessor3d.obj \
+ $(SLO)$/cutfindprocessor3d.obj \
$(SLO)$/defaultprocessor3d.obj \
$(SLO)$/shadow3dextractor.obj \
$(SLO)$/geometry2dextractor.obj \
diff --git a/svx/inc/svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx b/svx/inc/svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx
index 09da0ee8ee..2193dd63af 100644
--- a/svx/inc/svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx
+++ b/svx/inc/svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx
@@ -56,8 +56,13 @@ namespace drawinglayer
// defines if SdrTextWordWrapItem was set at SdrObjCustomShape which means
// that the text needs to be block formatted
unsigned mbWordWrap : 1;
- // #SJ# Allow text clipping against TextBox in special cases (used for SC)
- unsigned mbForceTextClipToTextRange : 1;
+
+ // #SJ# Allow text clipping against TextBox in special cases (used for SC)
+ unsigned mbForceTextClipToTextRange : 1;
+
+ // defines that the object contains/is a 3D AutoShape. Needed for
+ // making exceptions with shadow generation
+ unsigned mb3DShape : 1;
protected:
// local decomposition.
@@ -69,7 +74,8 @@ namespace drawinglayer
const Primitive2DSequence& rSubPrimitives,
const basegfx::B2DHomMatrix& rTextBox,
bool bWordWrap,
- bool bForceTextClipToTextRange);
+ bool bForceTextClipToTextRange,
+ bool b3DShape);
// data access
const attribute::SdrShadowTextAttribute& getSdrSTAttribute() const { return maSdrSTAttribute; }
@@ -77,6 +83,7 @@ namespace drawinglayer
const basegfx::B2DHomMatrix& getTextBox() const { return maTextBox; }
bool getWordWrap() const { return mbWordWrap; }
bool isForceTextClipToTextRange() const { return mbForceTextClipToTextRange; }
+ bool get3DShape() const { return mb3DShape; }
// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
diff --git a/svx/inc/svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx b/svx/inc/svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx
index c604b4e1e9..20dede7f44 100644
--- a/svx/inc/svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx
+++ b/svx/inc/svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx
@@ -55,9 +55,8 @@ namespace drawinglayer
double mfCornerRadiusY; // [0.0..1.0] relative to 1/2 height
// bitfield
- // flag which decides if this is a text frame. If Yes, the HitArea
- // should be the filled geometry
- bool mbTextFrame : 1;
+ // flag which decides if the HitArea should be the filled geometry
+ bool mbForceFillForHitTest : 1;
protected:
// local decomposition.
@@ -69,7 +68,7 @@ namespace drawinglayer
const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute,
double fCornerRadiusX,
double fCornerRadiusY,
- bool bTextFrame);
+ bool bForceFillForHitTest);
// data access
const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
@@ -77,7 +76,7 @@ namespace drawinglayer
double getCornerRadiusX() const { return mfCornerRadiusX; }
double getCornerRadiusY() const { return mfCornerRadiusY; }
bool isCornerRadiusUsed() const { return (0.0 != mfCornerRadiusX || 0.0 != mfCornerRadiusY); }
- bool getTextFrame() const { return mbTextFrame; }
+ bool getForceFillForHitTest() const { return mbForceFillForHitTest; }
// compare operator
virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
diff --git a/svx/inc/svx/svddrgmt.hxx b/svx/inc/svx/svddrgmt.hxx
index f1890c3bc7..96fb97c7e6 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/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index dc3b010afc..ed0b16bb82 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -696,7 +696,16 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created
- // For primitive rendering, shadow handling is done completely based on the geometry, so i removed it here
+ // #i105323# For 2D AtoShapes, the shadow attirbute does not need to be applied to any
+ // of the constucted helper SdrObjects. This would lead to problems since the shadow
+ // of one helper object would fall on one helper object behind it (e.g. with the
+ // eyes of the smiley shape). This is not wanted; instead a single shadow 'behind'
+ // the AutoShape visualisation is wanted. This is done with primitive functionailty
+ // now in SdrCustomShapePrimitive2D::create2DDecomposition, but only for 2D objects
+ // (see there and in EnhancedCustomShape3d::Create3DObject to read more).
+ // This exception may be removed later when AutoShapes will create primitives directly.
+ // So, currently remove the ShadowAttribute from the ItemSet to not apply it to any
+ // 2D helper shape.
ClearItem(SDRATTR_SHADOW);
Point aP( pCustomShapeObj->GetSnapRect().Center() );
@@ -731,23 +740,23 @@ EnhancedCustomShape2d::EnhancedCustomShape2d( SdrObject* pAObj ) :
/*const sal_Int32* pDefData =*/ ApplyShapeAttributes( rGeometryItem );
switch( eSpType )
{
- case mso_sptCan : nColorData = 0x20400000; break;
- case mso_sptCube : nColorData = 0x302e0000; break;
- case mso_sptActionButtonBlank : nColorData = 0x502ce400; break;
- case mso_sptActionButtonHome : nColorData = 0x702ce4ce; break;
- case mso_sptActionButtonHelp : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonInformation : nColorData = 0x702ce4c5; break;
- case mso_sptActionButtonBackPrevious : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonForwardNext : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonBeginning : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonEnd : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonReturn : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonDocument : nColorData = 0x702ce4ec; break;
- case mso_sptActionButtonSound : nColorData = 0x602ce4c0; break;
- case mso_sptActionButtonMovie : nColorData = 0x602ce4c0; break;
- case mso_sptBevel : nColorData = 0x502ce400; break;
- case mso_sptFoldedCorner : nColorData = 0x20e00000; break;
- case mso_sptSmileyFace : nColorData = 0x20e00000; break;
+ case mso_sptCan : nColorData = 0x20400000; break;
+ case mso_sptCube : nColorData = 0x302e0000; break;
+ case mso_sptActionButtonBlank : nColorData = 0x502ce400; break;
+ case mso_sptActionButtonHome : nColorData = 0x702ce4ce; break;
+ case mso_sptActionButtonHelp : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonInformation : nColorData = 0x702ce4c5; break;
+ case mso_sptActionButtonBackPrevious : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonForwardNext : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonBeginning : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonEnd : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonReturn : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonDocument : nColorData = 0x702ce4ec; break;
+ case mso_sptActionButtonSound : nColorData = 0x602ce4c0; break;
+ case mso_sptActionButtonMovie : nColorData = 0x602ce4c0; break;
+ case mso_sptBevel : nColorData = 0x502ce400; break;
+ case mso_sptFoldedCorner : nColorData = 0x20e00000; break;
+ case mso_sptSmileyFace : nColorData = 0x20e00000; break;
case mso_sptNil :
{
if( sShapeType.getLength() > 4 &&
diff --git a/svx/source/customshapes/EnhancedCustomShape3d.cxx b/svx/source/customshapes/EnhancedCustomShape3d.cxx
index ed94bcf075..4fec059147 100644
--- a/svx/source/customshapes/EnhancedCustomShape3d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape3d.cxx
@@ -323,7 +323,17 @@ SdrObject* EnhancedCustomShape3d::Create3DObject( const SdrObject* pShape2d, con
Point aCenter( aSnapRect.Center() );
SfxItemSet aSet( pCustomShape->GetMergedItemSet() );
- aSet.ClearItem( SDRATTR_TEXTDIRECTION ); //SJ: vertical writing is not required, by removing this item no outliner is created
+
+ //SJ: vertical writing is not required, by removing this item no outliner is created
+ aSet.ClearItem( SDRATTR_TEXTDIRECTION );
+
+ // #i105323# For 3D AutoShapes, the shadow attribute has to be applied to each
+ // created visualisation helper model shape individually. The shadow itself
+ // will then be rendered from the 3D renderer correctly for the whole 3D scene
+ // (and thus behind all objects of which the visualisation may be built). So,
+ // dio NOT remove it from the ItemSet here.
+ // aSet.ClearItem(SDRATTR_SHADOW);
+
std::vector< E3dCompoundObject* > aPlaceholderObjectList;
double fExtrusionBackward, fExtrusionForward;
diff --git a/svx/source/engine3d/helperhittest3d.cxx b/svx/source/engine3d/helperhittest3d.cxx
index 401111be85..270e725024 100644
--- a/svx/source/engine3d/helperhittest3d.cxx
+++ b/svx/source/engine3d/helperhittest3d.cxx
@@ -36,18 +36,10 @@
#include <svx/svdpage.hxx>
#include <svx/scene3d.hxx>
#include <svditer.hxx>
-#include <drawinglayer/processor3d/baseprocessor3d.hxx>
-#include <drawinglayer/primitive3d/drawinglayer_primitivetypes3d.hxx>
-#include <drawinglayer/primitive3d/transformprimitive3d.hxx>
-#include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
-#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
+#include <drawinglayer/processor3d/cutfindprocessor3d.hxx>
#include <svx/sdr/contact/viewcontactofe3d.hxx>
#include <svx/sdr/contact/viewcontactofe3dscene.hxx>
-#include <basegfx/polygon/b3dpolygontools.hxx>
-#include <basegfx/polygon/b3dpolypolygontools.hxx>
-#include <drawinglayer/primitive3d/hittestprimitive3d.hxx>
#include <com/sun/star/uno/Sequence.h>
-#include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -80,176 +72,13 @@ public:
//////////////////////////////////////////////////////////////////////////////
-namespace drawinglayer
-{
- namespace processor3d
- {
- class CutFindProcessor : public BaseProcessor3D
- {
- private:
- // the start and stop point for the cut vector
- basegfx::B3DPoint maFront;
- basegfx::B3DPoint maBack;
-
- // the found cut points
- ::std::vector< basegfx::B3DPoint > maResult;
-
- // #i102956# the transformation change from TransformPrimitive3D processings
- // needs to be remembered to be able to transform found cuts to the
- // basic coordinate system the processor starts with
- basegfx::B3DHomMatrix maCombinedTransform;
-
- // as tooling, the process() implementation takes over API handling and calls this
- // virtual render method when the primitive implementation is BasePrimitive3D-based.
- virtual void processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate);
-
- public:
- CutFindProcessor(const geometry::ViewInformation3D& rViewInformation,
- const basegfx::B3DPoint& rFront,
- const basegfx::B3DPoint& rBack)
- : BaseProcessor3D(rViewInformation),
- maFront(rFront),
- maBack(rBack),
- maResult(),
- maCombinedTransform()
- {}
-
- // data access
- const ::std::vector< basegfx::B3DPoint >& getCutPoints() const { return maResult; }
- };
-
- void CutFindProcessor::processBasePrimitive3D(const primitive3d::BasePrimitive3D& rCandidate)
- {
- // it is a BasePrimitive3D implementation, use getPrimitiveID() call for switch
- switch(rCandidate.getPrimitiveID())
- {
- case PRIMITIVE3D_ID_TRANSFORMPRIMITIVE3D :
- {
- // transform group.
- const primitive3d::TransformPrimitive3D& rPrimitive = static_cast< const primitive3d::TransformPrimitive3D& >(rCandidate);
-
- // remember old and transform front, back to object coordinates
- const basegfx::B3DPoint aLastFront(maFront);
- const basegfx::B3DPoint aLastBack(maBack);
- basegfx::B3DHomMatrix aInverseTrans(rPrimitive.getTransformation());
- aInverseTrans.invert();
- maFront *= aInverseTrans;
- maBack *= aInverseTrans;
-
- // remember current and create new transformation; add new object transform from right side
- const geometry::ViewInformation3D aLastViewInformation3D(getViewInformation3D());
- const geometry::ViewInformation3D aNewViewInformation3D(
- aLastViewInformation3D.getObjectTransformation() * rPrimitive.getTransformation(),
- aLastViewInformation3D.getOrientation(),
- aLastViewInformation3D.getProjection(),
- aLastViewInformation3D.getDeviceToView(),
- aLastViewInformation3D.getViewTime(),
- aLastViewInformation3D.getExtendedInformationSequence());
- updateViewInformation(aNewViewInformation3D);
-
- // #i102956# remember needed back-transform for found cuts (combine from right side)
- const basegfx::B3DHomMatrix aLastCombinedTransform(maCombinedTransform);
- maCombinedTransform = maCombinedTransform * rPrimitive.getTransformation();
-
- // let break down
- process(rPrimitive.getChildren());
-
- // restore transformations and front, back
- maCombinedTransform = aLastCombinedTransform;
- updateViewInformation(aLastViewInformation3D);
- maFront = aLastFront;
- maBack = aLastBack;
- break;
- }
- case PRIMITIVE3D_ID_POLYGONHAIRLINEPRIMITIVE3D :
- {
- // PolygonHairlinePrimitive3D, not used for hit test with planes, ignore. This
- // means that also thick line expansion will not be hit-tested as
- // PolyPolygonMaterialPrimitive3D
- break;
- }
- case PRIMITIVE3D_ID_HATCHTEXTUREPRIMITIVE3D :
- {
- // #i97321#
- // For HatchTexturePrimitive3D, do not use the decomposition since it will produce
- // clipped hatch lines in 3D. It can be used when the hatch also has a filling, but for
- // simplicity, just use the children which are the PolyPolygonMaterialPrimitive3D
- // which define the hatched areas anyways; for HitTest this is more than adequate
- const primitive3d::HatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::HatchTexturePrimitive3D& >(rCandidate);
- process(rPrimitive.getChildren());
- break;
- }
- case PRIMITIVE3D_ID_HITTESTPRIMITIVE3D :
- {
- // HitTestPrimitive3D, force usage due to we are doing a hit test and this
- // primitive only gets generated on 3d objects without fill, exactly for this
- // purpose
- const primitive3d::HitTestPrimitive3D& rPrimitive = static_cast< const primitive3d::HitTestPrimitive3D& >(rCandidate);
- process(rPrimitive.getChildren());
- break;
- }
- case PRIMITIVE3D_ID_POLYPOLYGONMATERIALPRIMITIVE3D :
- {
- // PolyPolygonMaterialPrimitive3D
- const primitive3d::PolyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::PolyPolygonMaterialPrimitive3D& >(rCandidate);
-
- if(!maFront.equal(maBack))
- {
- const basegfx::B3DPolyPolygon& rPolyPolygon = rPrimitive.getB3DPolyPolygon();
- const sal_uInt32 nPolyCount(rPolyPolygon.count());
-
- if(nPolyCount)
- {
- const basegfx::B3DPolygon aPolygon(rPolyPolygon.getB3DPolygon(0));
- const sal_uInt32 nPointCount(aPolygon.count());
-
- if(nPointCount > 2)
- {
- const basegfx::B3DVector aPlaneNormal(aPolygon.getNormal());
-
- if(!aPlaneNormal.equalZero())
- {
- const basegfx::B3DPoint aPointOnPlane(aPolygon.getB3DPoint(0));
- double fCut(0.0);
-
- if(basegfx::tools::getCutBetweenLineAndPlane(aPlaneNormal, aPointOnPlane, maFront, maBack, fCut))
- {
- const basegfx::B3DPoint aCutPoint(basegfx::interpolate(maFront, maBack, fCut));
-
- if(basegfx::tools::isInside(rPolyPolygon, aCutPoint, false))
- {
- // #i102956# add result. Do not forget to do this in the coordinate
- // system the processor get started with, so use the collected
- // combined transformation from processed TransformPrimitive3D's
- maResult.push_back(maCombinedTransform * aCutPoint);
- }
- }
- }
- }
- }
- }
-
- break;
- }
- default :
- {
- // process recursively
- process(rCandidate.get3DDecomposition(getViewInformation3D()));
- break;
- }
- }
- }
- } // end of namespace processor3d
-} // end of namespace drawinglayer
-
-//////////////////////////////////////////////////////////////////////////////
-
void getAllHit3DObjectWithRelativePoint(
const basegfx::B3DPoint& rFront,
const basegfx::B3DPoint& rBack,
const E3dCompoundObject& rObject,
const drawinglayer::geometry::ViewInformation3D& rObjectViewInformation3D,
- ::std::vector< basegfx::B3DPoint >& o_rResult)
+ ::std::vector< basegfx::B3DPoint >& o_rResult,
+ bool bAnyHit)
{
o_rResult.clear();
@@ -271,7 +100,7 @@ void getAllHit3DObjectWithRelativePoint(
if(aObjectRange.overlaps(aFrontBackRange))
{
// bound volumes hit, geometric cut tests needed
- drawinglayer::processor3d::CutFindProcessor aCutFindProcessor(rObjectViewInformation3D, rFront, rBack);
+ drawinglayer::processor3d::CutFindProcessor aCutFindProcessor(rObjectViewInformation3D, rFront, rBack, bAnyHit);
aCutFindProcessor.process(aPrimitives);
o_rResult = aCutFindProcessor.getCutPoints();
}
@@ -388,7 +217,7 @@ SVX_DLLPUBLIC void getAllHit3DObjectsSortedFrontToBack(
{
// get all hit points with object
::std::vector< basegfx::B3DPoint > aHitsWithObject;
- getAllHit3DObjectWithRelativePoint(aFront, aBack, *pCandidate, aViewInfo3D, aHitsWithObject);
+ getAllHit3DObjectWithRelativePoint(aFront, aBack, *pCandidate, aViewInfo3D, aHitsWithObject, false);
for(sal_uInt32 a(0); a < aHitsWithObject.size(); a++)
{
@@ -452,7 +281,7 @@ bool checkHitSingle3DObject(
{
// get all hit points with object
::std::vector< basegfx::B3DPoint > aHitsWithObject;
- getAllHit3DObjectWithRelativePoint(aFront, aBack, rCandidate, aViewInfo3D, aHitsWithObject);
+ getAllHit3DObjectWithRelativePoint(aFront, aBack, rCandidate, aViewInfo3D, aHitsWithObject, true);
if(aHitsWithObject.size())
{
diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx
index ef7df1ae32..28ab8cbff6 100644
--- a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx
@@ -39,6 +39,7 @@
#include <svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
+#include <svx/obj3d.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -134,6 +135,7 @@ namespace sdr
// create Primitive2DSequence from sub-geometry
const SdrObject* pSdrObjRepresentation = GetCustomShapeObj().GetSdrObjectFromCustomShape();
+ bool b3DShape(false);
if(pSdrObjRepresentation)
{
@@ -142,6 +144,12 @@ namespace sdr
while(aIterator.IsMore())
{
SdrObject& rCandidate = *aIterator.Next();
+
+ if(!b3DShape && dynamic_cast< E3dObject* >(&rCandidate))
+ {
+ b3DShape = true;
+ }
+
const drawinglayer::primitive2d::Primitive2DSequence xNew(rCandidate.GetViewContact().getViewIndependentPrimitive2DSequence());
drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xGroup, xNew);
}
@@ -220,7 +228,8 @@ namespace sdr
xGroup,
aTextBoxMatrix,
bWordWrap,
- false)); // #SJ# New parameter to force to clipped BlockText for SC
+ false, // #SJ# New parameter to force to clipped BlockText for SC
+ b3DShape));
xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
}
diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx
index 9c7810ea46..f9113d7b64 100644
--- a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx
@@ -39,6 +39,7 @@
#include <svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx>
#include <svtools/itemset.hxx>
#include <svx/sdr/primitive2d/sdrprimitivetools.hxx>
+#include <svx/svdmodel.hxx>
//////////////////////////////////////////////////////////////////////////////
@@ -104,6 +105,10 @@ namespace sdr
double fCornerRadiusY;
drawinglayer::primitive2d::calculateRelativeCornerRadius(nCornerRadius, aObjectRange, fCornerRadiusX, fCornerRadiusY);
+ // #i105856# use knowledge about pickthrough from the model
+ const bool bPickThroughTransparentTextFrames(
+ GetRectObj().GetModel() && GetRectObj().GetModel()->IsPickThroughTransparentTextFrames());
+
// create primitive
const drawinglayer::primitive2d::Primitive2DReference xReference(
new drawinglayer::primitive2d::SdrRectanglePrimitive2D(
@@ -111,7 +116,8 @@ namespace sdr
*pAttribute,
fCornerRadiusX,
fCornerRadiusY,
- GetRectObj().IsTextFrame()));
+ // #i105856# use fill for HitTest when TextFrame and not PickThrough
+ GetRectObj().IsTextFrame() && !bPickThroughTransparentTextFrames));
xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
}
diff --git a/svx/source/sdr/overlay/overlaymanager.cxx b/svx/source/sdr/overlay/overlaymanager.cxx
index f77b533a0e..64ac530e55 100644
--- a/svx/source/sdr/overlay/overlaymanager.cxx
+++ b/svx/source/sdr/overlay/overlaymanager.cxx
@@ -44,6 +44,10 @@
//////////////////////////////////////////////////////////////////////////////
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
namespace sdr
{
namespace overlay
@@ -140,6 +144,18 @@ namespace sdr
maViewInformation2D(0),
mfDiscreteOne(0.0)
{
+ // set Property 'ReducedDisplayQuality' to true to allow simpler interaction
+ // visualisations
+ static bool bUseReducedDisplayQualityForDrag(true);
+
+ if(bUseReducedDisplayQualityForDrag)
+ {
+ uno::Sequence< beans::PropertyValue > xProperties(1);
+ xProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality"));
+ xProperties[0].Value <<= true;
+ maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties);
+ }
+
if(pOldOverlayManager)
{
// take over OverlayObjects from given OverlayManager. Copy
diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx
index e38cb57378..93e8b3a6e7 100644
--- a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx
@@ -68,7 +68,20 @@ namespace drawinglayer
// add shadow
if(aRetval.hasElements() && getSdrSTAttribute().getShadow())
{
- aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrSTAttribute().getShadow());
+ // #i105323# add generic shadow only for 2D shapes. For
+ // 3D shapes shadow will be set at the individual created
+ // visualisation objects and be visualized by the 3d renderer
+ // as a single shadow.
+ //
+ // The shadow for AutoShapes could be handled uniformely by not setting any
+ // shadow items at the helper model objects and only adding shadow here for
+ // 2D and 3D (and it works, too), but this would lead to two 3D scenes for
+ // the 3D object; one for the shadow aond one for the content. The one for the
+ // shadow will be correct (using ColorModifierStack), but expensive.
+ if(!get3DShape())
+ {
+ aRetval = createEmbeddedShadowPrimitive(aRetval, *getSdrSTAttribute().getShadow());
+ }
}
return aRetval;
@@ -79,13 +92,15 @@ namespace drawinglayer
const Primitive2DSequence& rSubPrimitives,
const basegfx::B2DHomMatrix& rTextBox,
bool bWordWrap,
- bool bForceTextClipToTextRange)
+ bool bForceTextClipToTextRange,
+ bool b3DShape)
: BasePrimitive2D(),
maSdrSTAttribute(rSdrSTAttribute),
maSubPrimitives(rSubPrimitives),
maTextBox(rTextBox),
mbWordWrap(bWordWrap),
- mbForceTextClipToTextRange(bForceTextClipToTextRange)
+ mbForceTextClipToTextRange(bForceTextClipToTextRange),
+ mb3DShape(b3DShape)
{
}
@@ -99,7 +114,8 @@ namespace drawinglayer
&& getSubPrimitives() == rCompare.getSubPrimitives()
&& getTextBox() == rCompare.getTextBox()
&& getWordWrap() == rCompare.getWordWrap()
- && isForceTextClipToTextRange() == rCompare.isForceTextClipToTextRange());
+ && isForceTextClipToTextRange() == rCompare.isForceTextClipToTextRange()
+ && get3DShape() == rCompare.get3DShape());
}
return false;
diff --git a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx
index 209684653a..6449859318 100644
--- a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx
@@ -68,7 +68,7 @@ namespace drawinglayer
*getSdrLFSTAttribute().getFill(),
getSdrLFSTAttribute().getFillFloatTransGradient()));
}
- else if(getTextFrame())
+ else if(getForceFillForHitTest())
{
// if no fill and it's a text frame, create a fill for HitTest and
// BoundRect fallback
@@ -89,7 +89,7 @@ namespace drawinglayer
getTransform(),
*getSdrLFSTAttribute().getLine()));
}
- else if(!getTextFrame())
+ else if(!getForceFillForHitTest())
{
// if initially no line is defined and it's not a text frame, create
// a line for HitTest and BoundRect
@@ -127,13 +127,13 @@ namespace drawinglayer
const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute,
double fCornerRadiusX,
double fCornerRadiusY,
- bool bTextFrame)
+ bool bForceFillForHitTest)
: BasePrimitive2D(),
maTransform(rTransform),
maSdrLFSTAttribute(rSdrLFSTAttribute),
mfCornerRadiusX(fCornerRadiusX),
mfCornerRadiusY(fCornerRadiusY),
- mbTextFrame(bTextFrame)
+ mbForceFillForHitTest(bForceFillForHitTest)
{
}
@@ -147,7 +147,7 @@ namespace drawinglayer
&& getCornerRadiusY() == rCompare.getCornerRadiusY()
&& getTransform() == rCompare.getTransform()
&& getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()
- && getTextFrame() == rCompare.getTextFrame());
+ && getForceFillForHitTest() == rCompare.getForceFillForHitTest());
}
return false;
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
index 93d9b9c907..47f7324b8a 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -206,6 +206,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)
@@ -318,6 +344,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());
@@ -359,7 +392,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)
@@ -1358,6 +1391,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()));