summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorArmin Weiss <aw@openoffice.org>2006-08-09 16:00:16 +0000
committerArmin Weiss <aw@openoffice.org>2006-08-09 16:00:16 +0000
commit9927e1ca23c8353c880a3ae0a196caabdf747c4b (patch)
tree474f197a8ec74e16d64c3f31f389dbb07e7cd7f9 /drawinglayer
parent4d0a693b85b6191d351f7a6bb0e5c30b2e47eca8 (diff)
#i39532#
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/prj/build.lst23
-rw-r--r--drawinglayer/prj/d.lst58
-rw-r--r--drawinglayer/source/processor3d/baseprocessor3d.cxx86
-rw-r--r--drawinglayer/source/processor3d/defaultprocessor3d.cxx1905
-rw-r--r--drawinglayer/source/processor3d/makefile.mk54
-rw-r--r--drawinglayer/source/processor3d/shadow3dextractor.cxx345
-rw-r--r--drawinglayer/source/texture/makefile.mk51
-rw-r--r--drawinglayer/source/texture/texture.cxx1090
-rw-r--r--drawinglayer/util/makefile.mk9
9 files changed, 3586 insertions, 35 deletions
diff --git a/drawinglayer/prj/build.lst b/drawinglayer/prj/build.lst
index ffa43f6e4b32..63d56b2b047c 100644
--- a/drawinglayer/prj/build.lst
+++ b/drawinglayer/prj/build.lst
@@ -1,10 +1,13 @@
-dx drawinglayer : goodies sal vcl basegfx offuh cppuhelper cppu NULL
-dx drawinglayer usr1 - all dx_mkout NULL
-dx drawinglayer\inc get - all dx_inc NULL
-dx drawinglayer\prj get - all dx_prj NULL
-dx drawinglayer\source\primitive nmake - all dx_primitive NULL
-dx drawinglayer\source\primitive3d nmake - all dx_primitive3d NULL
-dx drawinglayer\source\animation nmake - all dx_animation NULL
-dx drawinglayer\source\geometry nmake - all dx_geometry NULL
-dx drawinglayer\source\processor nmake - all dx_processor NULL
-dx drawinglayer\util nmake - all dx_util dx_primitive dx_primitive3d dx_animation dx_geometry dx_processor NULL
+fx drawinglayer : goodies sal vcl basegfx offuh cppuhelper cppu NULL
+fx drawinglayer usr1 - all fx_mkout NULL
+fx drawinglayer\inc get - all fx_inc NULL
+fx drawinglayer\prj get - all fx_prj NULL
+fx drawinglayer\source\primitive nmake - all fx_primitive NULL
+fx drawinglayer\source\primitive3d nmake - all fx_primitive3d NULL
+fx drawinglayer\source\animation nmake - all fx_animation NULL
+fx drawinglayer\source\geometry nmake - all fx_geometry NULL
+fx drawinglayer\source\processor nmake - all fx_processor NULL
+fx drawinglayer\source\processor3d nmake - all fx_processor3d NULL
+fx drawinglayer\source\attribute nmake - all fx_attribute NULL
+fx drawinglayer\source\texture nmake - all fx_texture NULL
+fx drawinglayer\util nmake - all fx_util fx_primitive fx_primitive3d fx_animation fx_geometry fx_processor fx_processor3d fx_attribute fx_texture NULL
diff --git a/drawinglayer/prj/d.lst b/drawinglayer/prj/d.lst
index 9bd83fa6bbed..f0d41821a911 100644
--- a/drawinglayer/prj/d.lst
+++ b/drawinglayer/prj/d.lst
@@ -10,62 +10,76 @@ mkdir: %_DEST%\inc%_EXT%\drawinglayer\primitive
..\inc\drawinglayer\primitive\animatedprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\animatedprimitive.hxx
..\inc\drawinglayer\primitive\backgroundcolorprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\backgroundcolorprimitive.hxx
..\inc\drawinglayer\primitive\bitmapprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\bitmapprimitive.hxx
-..\inc\drawinglayer\primitive\fillattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\fillattribute.hxx
-..\inc\drawinglayer\primitive\fillbitmapattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\fillbitmapattribute.hxx
..\inc\drawinglayer\primitive\fillbitmapprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\fillbitmapprimitive.hxx
+..\inc\drawinglayer\primitive\embedded3dprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\embedded3dprimitive.hxx
..\inc\drawinglayer\primitive\fillgradientprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\fillgradientprimitive.hxx
..\inc\drawinglayer\primitive\fillhatchprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\fillhatchprimitive.hxx
..\inc\drawinglayer\primitive\gridprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\gridprimitive.hxx
..\inc\drawinglayer\primitive\helplineprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\helplineprimitive.hxx
-..\inc\drawinglayer\primitive\vectorprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\vectorprimitive.hxx
..\inc\drawinglayer\primitive\markerprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\markerprimitive.hxx
..\inc\drawinglayer\primitive\maskprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\maskprimitive.hxx
-..\inc\drawinglayer\primitive\transformprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\transformprimitive.hxx
..\inc\drawinglayer\primitive\metafileprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\metafileprimitive.hxx
..\inc\drawinglayer\primitive\modifiedcolorprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\modifiedcolorprimitive.hxx
..\inc\drawinglayer\primitive\polygonprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\polygonprimitive.hxx
..\inc\drawinglayer\primitive\polypolygonprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\polypolygonprimitive.hxx
..\inc\drawinglayer\primitive\primitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\primitive.hxx
+..\inc\drawinglayer\primitive\primitivedefines.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\primitivedefines.hxx
..\inc\drawinglayer\primitive\sceneprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\sceneprimitive.hxx
-..\inc\drawinglayer\primitive\sdrattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\sdrattribute.hxx
-..\inc\drawinglayer\primitive\sdrfillbitmapattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\sdrfillbitmapattribute.hxx
..\inc\drawinglayer\primitive\shadowprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\shadowprimitive.hxx
..\inc\drawinglayer\primitive\simpletransparenceprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\simpletransparenceprimitive.hxx
-..\inc\drawinglayer\primitive\strokearrowattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\strokearrowattribute.hxx
-..\inc\drawinglayer\primitive\strokeattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\strokeattribute.hxx
..\inc\drawinglayer\primitive\textlayoutdevice.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\textlayoutdevice.hxx
..\inc\drawinglayer\primitive\textprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\textprimitive.hxx
-..\inc\drawinglayer\primitive\texture.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\texture.hxx
+..\inc\drawinglayer\primitive\transformprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\transformprimitive.hxx
..\inc\drawinglayer\primitive\transparenceprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\transparenceprimitive.hxx
+..\inc\drawinglayer\primitive\vectorprimitive.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\vectorprimitive.hxx
mkdir: %_DEST%\inc%_EXT%\drawinglayer\primitive3d
-..\inc\drawinglayer\primitive3d\materialattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\materialattribute3d.hxx
-..\inc\drawinglayer\primitive3d\sdrallattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrallattribute3d.hxx
-..\inc\drawinglayer\primitive3d\sdrattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrattribute3d.hxx
+..\inc\drawinglayer\primitive3d\hatchtextureprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\hatchtextureprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\modifiedcolorprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\modifiedcolorprimitive3d.hxx
..\inc\drawinglayer\primitive3d\polygonprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\polygonprimitive3d.hxx
..\inc\drawinglayer\primitive3d\polygontubeprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\polygontubeprimitive3d.hxx
..\inc\drawinglayer\primitive3d\polypolygonprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\polypolygonprimitive3d.hxx
-..\inc\drawinglayer\primitive3d\transformprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\transformprimitive3d.hxx
-..\inc\drawinglayer\primitive3d\shadowprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\shadowprimitive3d.hxx
-..\inc\drawinglayer\primitive3d\textureprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\textureprimitive3d.hxx
-..\inc\drawinglayer\primitive3d\hatchtextureprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\hatchtextureprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\primitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\primitive3d.hxx
+..\inc\drawinglayer\primitive3d\sdrcubeprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrcubeprimitive3d.hxx
..\inc\drawinglayer\primitive3d\sdrdecompositiontools3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrdecompositiontools3d.hxx
..\inc\drawinglayer\primitive3d\sdrextrudelathetools3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrextrudelathetools3d.hxx
-..\inc\drawinglayer\primitive3d\sdrprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrprimitive3d.hxx
-..\inc\drawinglayer\primitive3d\sdrcubeprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrcubeprimitive3d.hxx
..\inc\drawinglayer\primitive3d\sdrextrudeprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrextrudeprimitive3d.hxx
-..\inc\drawinglayer\primitive3d\sdrsphereprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrsphereprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\sdrlabelprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrlabelprimitive3d.hxx
..\inc\drawinglayer\primitive3d\sdrlatheprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrlatheprimitive3d.hxx
..\inc\drawinglayer\primitive3d\sdrpolygonprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrpolygonprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\sdrprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\sdrsphereprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\sdrsphereprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\shadowprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\shadowprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\textureprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\textureprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\transformprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\transformprimitive3d.hxx
+..\inc\drawinglayer\primitive3d\vectorprimitive3d.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive3d\vectorprimitive3d.hxx
mkdir: %_DEST%\inc%_EXT%\drawinglayer\animation
..\inc\drawinglayer\animation\animationtiming.hxx %_DEST%\inc%_EXT%\drawinglayer\animation\animationtiming.hxx
mkdir: %_DEST%\inc%_EXT%\drawinglayer\geometry
-..\inc\drawinglayer\geometry\viewinformation.hxx %_DEST%\inc%_EXT%\drawinglayer\geometry\viewinformation.hxx
..\inc\drawinglayer\geometry\transformation3d.hxx %_DEST%\inc%_EXT%\drawinglayer\geometry\transformation3d.hxx
+..\inc\drawinglayer\geometry\viewinformation.hxx %_DEST%\inc%_EXT%\drawinglayer\geometry\viewinformation.hxx
mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor
-..\inc\drawinglayer\processor\processor.hxx %_DEST%\inc%_EXT%\drawinglayer\processor\processor.hxx
+..\inc\drawinglayer\processor\animatedextractor.hxx %_DEST%\inc%_EXT%\drawinglayer\processor\animatedextractor.hxx
+..\inc\drawinglayer\processor\baseprocessor.hxx %_DEST%\inc%_EXT%\drawinglayer\processor\baseprocessor.hxx
..\inc\drawinglayer\processor\vclprocessor.hxx %_DEST%\inc%_EXT%\drawinglayer\processor\vclprocessor.hxx
-..\inc\drawinglayer\processor\processor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor\processor3d.hxx
+
+mkdir: %_DEST%\inc%_EXT%\drawinglayer\processor3d
+..\inc\drawinglayer\processor3d\baseprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\baseprocessor3d.hxx
+..\inc\drawinglayer\processor3d\defaultprocessor3d.hxx %_DEST%\inc%_EXT%\drawinglayer\processor3d\defaultprocessor3d.hxx
+
+mkdir: %_DEST%\inc%_EXT%\drawinglayer\attribute
+..\inc\drawinglayer\attribute\fillattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\fillattribute.hxx
+..\inc\drawinglayer\attribute\fillbitmapattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\fillbitmapattribute.hxx
+..\inc\drawinglayer\attribute\materialattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\materialattribute3d.hxx
+..\inc\drawinglayer\attribute\sdrallattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\sdrallattribute3d.hxx
+..\inc\drawinglayer\attribute\sdrattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\sdrattribute.hxx
+..\inc\drawinglayer\attribute\sdrattribute3d.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\sdrattribute3d.hxx
+..\inc\drawinglayer\attribute\sdrfillbitmapattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\sdrfillbitmapattribute.hxx
+..\inc\drawinglayer\attribute\strokearrowattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\strokearrowattribute.hxx
+..\inc\drawinglayer\attribute\strokeattribute.hxx %_DEST%\inc%_EXT%\drawinglayer\attribute\strokeattribute.hxx
+
+mkdir: %_DEST%\inc%_EXT%\drawinglayer\texture
+..\inc\drawinglayer\texture\texture.hxx %_DEST%\inc%_EXT%\drawinglayer\primitive\texture.hxx
diff --git a/drawinglayer/source/processor3d/baseprocessor3d.cxx b/drawinglayer/source/processor3d/baseprocessor3d.cxx
new file mode 100644
index 000000000000..01e40b43f904
--- /dev/null
+++ b/drawinglayer/source/processor3d/baseprocessor3d.cxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: baseprocessor3d.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: aw $ $Date: 2006-08-09 16:57:47 $
+ *
+ * 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 _DRAWINGLAYER_PROCESSOR3D_BASEPROCESSOR3D_HXX
+#include <drawinglayer/processor3d/baseprocessor3d.hxx>
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor3d
+ {
+ baseProcessor3D::baseProcessor3D(
+ const geometry::viewInformation& rViewInformation,
+ const geometry::transformation3D& rTransformation3D)
+ : maViewInformation(rViewInformation),
+ maTransformation3D(rTransformation3D)
+ {
+ }
+
+ baseProcessor3D::~baseProcessor3D()
+ {
+ }
+ } // end of namespace processor3d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor3d
+ {
+ collectingProcessor3D::collectingProcessor3D(
+ const geometry::viewInformation& rViewInformation,
+ const geometry::transformation3D& rTransformation3D)
+ : baseProcessor3D(rViewInformation, rTransformation3D)
+ {
+ }
+
+ collectingProcessor3D::~collectingProcessor3D()
+ {
+ }
+
+ void collectingProcessor3D::process(const primitive3d::primitiveVector3D& rSource)
+ {
+ // accept everything
+ maPrimitiveVector.insert(maPrimitiveVector.end(), rSource.begin(), rSource.end());
+ }
+ } // end of namespace processor3d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
new file mode 100644
index 000000000000..4d11f2bd8fb7
--- /dev/null
+++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
@@ -0,0 +1,1905 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: defaultprocessor3d.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: aw $ $Date: 2006-08-09 16:57:47 $
+ *
+ * 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 _DRAWINGLAYER_PROCESSOR3D_DEFAULTPROCESSOR3D_HXX
+#include <drawinglayer/processor3d/defaultprocessor3d.hxx>
+#endif
+
+#ifndef _SV_BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+
+#ifndef _BGFX_POLYGON_B3DPOLYGON_HXX
+#include <basegfx/polygon/b3dpolygon.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_POLYGONPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_MODIFIEDCOLORPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_POLYPOLYGONPRIMITIVE_HXX
+#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
+#endif
+
+#ifndef _BGFX_POLYPOLYGON_B3DPOLYGONCLIPPER_HXX
+#include <basegfx/polygon/b3dpolygonclipper.hxx>
+#endif
+
+#ifndef _BGFX_RASTER_BZPIXELRASTER_HXX
+#include <basegfx/raster/bzpixelraster.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_ATTRIBUTE_SDRATTRIBUTE3D_HXX
+#include <drawinglayer/attribute/sdrattribute3d.hxx>
+#endif
+
+#ifndef _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX
+#include <basegfx/polygon/b3dpolygontools.hxx>
+#endif
+
+#ifndef _BGFX_POLYPOLYGON_B3DPOLYGONTOOLS_HXX
+#include <basegfx/polygon/b3dpolypolygontools.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_TEXTUREPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/textureprimitive3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_HATCHTEXTUREPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_TRANSFORMPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/transformprimitive3d.hxx>
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BDInterpolator
+ {
+ protected:
+ double mfVal;
+ double mfInc;
+
+ public:
+ BDInterpolator() {}
+ BDInterpolator(double fValA, double fValB, sal_uInt32 nCount) : mfVal(fValA), mfInc((fValB - fValA) / (double)nCount) {}
+
+ double getVal() const { return mfVal; }
+ double getInc() const { return mfInc; }
+ void increment() { mfVal += mfInc; }
+ void increment(double fStep) { mfVal += fStep * mfInc; }
+ };
+
+ class BColorInterpolator
+ {
+ protected:
+ BColor maVal;
+ BColor maInc;
+
+ public:
+ BColorInterpolator() {}
+ BColorInterpolator(const BColor& rValA, const BColor& rValB, sal_uInt32 nCount) : maVal(rValA), maInc((rValB - rValA) / (double)nCount) {}
+
+ const BColor& getVal() const { return maVal; }
+ const BColor& getInc() const { return maInc; }
+ void increment() { maVal += maInc; }
+ void increment(double fStep) { maVal += fStep * maInc; }
+ };
+
+ class B3DVectorInterpolator
+ {
+ protected:
+ B3DVector maVal;
+ B3DVector maInc;
+
+ public:
+ B3DVectorInterpolator() {}
+ B3DVectorInterpolator(const B3DVector& rValA, const B3DVector& rValB, sal_uInt32 nCount) : maVal(rValA), maInc((rValB - rValA) / (double)nCount) {}
+
+ const B3DVector& getVal() const { return maVal; }
+ const B3DVector& getInc() const { return maInc; }
+ void increment() { maVal += maInc; }
+ void increment(double fStep) { maVal += fStep * maInc; }
+ };
+
+ class B2DPointInterpolator
+ {
+ protected:
+ B2DPoint maVal;
+ B2DPoint maInc;
+ BDInterpolator maZInv;
+
+ public:
+ B2DPointInterpolator() {}
+ B2DPointInterpolator(const B2DPoint& rValA, const B2DPoint& rValB, double fInvZEyeA, double fInvZEyeB, sal_uInt32 nCount)
+ : maVal(rValA),
+ maInc((rValB - rValA) / (double)nCount),
+ maZInv(fInvZEyeA, fInvZEyeB, nCount)
+ {}
+
+ const B2DPoint& getVal() const { return maVal; }
+ const B2DPoint& getInc() const { return maInc; }
+ double getZVal() const { return maZInv.getVal(); }
+ double getZInc() const { return maZInv.getInc(); }
+ void increment() { maVal += maInc; maZInv.increment(); }
+ void increment(double fStep) { maVal += fStep * maInc; maZInv.increment(fStep); }
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#define SCANLINE_EMPTY_INDEX (0xffffffff)
+
+namespace basegfx
+{
+ class B3DScanlineEntry
+ {
+ protected:
+ sal_Int32 mnLine;
+ sal_uInt32 mnLineCount;
+ BDInterpolator maX;
+ BDInterpolator maZ;
+
+ // values for normal and texture coordinate interpolation are optional,
+ // held simply by an index. Empty is marked by SCANLINE_EMPTY_INDEX to which it needs
+ // to be initialized
+ sal_uInt32 mnBColorIndex;
+ sal_uInt32 mnNormalIndex;
+ sal_uInt32 mnTextureCoordinateIndex;
+
+ public:
+ B3DScanlineEntry() {}
+
+ // data write access
+ void setLine(sal_Int32 nLine) { mnLine = nLine; }
+ void setLineCount(sal_uInt32 nLineCount) { mnLineCount = nLineCount; }
+ void setXInterpolator(const BDInterpolator& rInt) { maX = rInt; }
+ void setZInterpolator(const BDInterpolator& rInt) { maZ = rInt; }
+ void setBColorIndex(sal_uInt32 nIndex) { mnBColorIndex = nIndex; }
+ void setNormalIndex(sal_uInt32 nIndex) { mnNormalIndex = nIndex; }
+ void setTextureCoordinateIndex(sal_uInt32 nIndex) { mnTextureCoordinateIndex = nIndex; }
+
+ // data read access
+ sal_Int32 getLine() const { return mnLine; }
+ sal_uInt32 getLineCount() const { return mnLineCount; }
+ const BDInterpolator& getXInterpolator() const { return maX; }
+ const BDInterpolator& getZInterpolator() const { return maZ; }
+ sal_uInt32 getBColorIndex() const {return mnBColorIndex; }
+ sal_uInt32 getNormalIndex() const {return mnNormalIndex; }
+ sal_uInt32 getTextureCoordinateIndex() const {return mnTextureCoordinateIndex; }
+
+ bool simpleLineSortComparator(const B3DScanlineEntry& rComp) const
+ {
+ return (maX.getVal() < rComp.maX.getVal());
+ }
+
+ bool operator<(const B3DScanlineEntry& rComp) const
+ {
+ if(mnLine == rComp.mnLine)
+ {
+ return simpleLineSortComparator(rComp);
+ }
+
+ return (mnLine < rComp.mnLine);
+ }
+
+ bool isValid() const
+ {
+ return (0L != mnLineCount);
+ }
+
+ bool decrement(sal_uInt32 nCount = 1L)
+ {
+ if(mnLineCount > nCount)
+ {
+ mnLineCount -= nCount;
+ return true;
+ }
+ else
+ {
+ mnLineCount = 0L;
+ return false;
+ }
+ }
+
+ void increment()
+ {
+ maX.increment();
+ maZ.increment();
+ }
+
+ void increment(double fStep)
+ {
+ maX.increment(fStep);
+ maZ.increment(fStep);
+ }
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class B3DPolyPolygonRasterConverter
+ {
+ protected:
+ ::std::vector< B3DScanlineEntry > maGlobalEntries;
+ ::std::vector< BColorInterpolator > maGlobalBColorInterpolators;
+ ::std::vector< B3DVectorInterpolator > maGlobalNormalInterpolators;
+ ::std::vector< B2DPointInterpolator > maGlobalTextureCoordinateInterpolators;
+
+ // bitfield
+ unsigned mbAreaMode : 1;
+
+ struct scanlineEntryComparator
+ {
+ bool operator()( const B3DScanlineEntry* pA, const B3DScanlineEntry* pB)
+ {
+ // here, Y is the same anyways (sorting a scanline), so simple compare is enough
+ OSL_ENSURE(pA && pB, "scanlineEntryComparator: empty pointer (!)");
+ return pA->simpleLineSortComparator(*pB);
+ }
+ };
+
+ // add BColor interpolator, return index
+ sal_uInt32 addBColor(const BColor& rA, const BColor& rB, sal_uInt32 nDelta)
+ {
+ maGlobalBColorInterpolators.push_back(BColorInterpolator(rA, rB, nDelta));
+ return (maGlobalBColorInterpolators.size() - 1L);
+ }
+
+ // add normal interpolator, return index
+ sal_uInt32 addNormal(const B3DVector& rA, const B3DVector& rB, sal_uInt32 nDelta)
+ {
+ maGlobalNormalInterpolators.push_back(B3DVectorInterpolator(rA, rB, nDelta));
+ return (maGlobalNormalInterpolators.size() - 1L);
+ }
+
+ // add texture interpolator, return index
+ sal_uInt32 addTextureCoordinate(const B2DPoint& rA, const B2DPoint& rB, double fZEyeA, double fZEyeB, sal_uInt32 nDelta)
+ {
+ const double fInvZEyeA(fTools::equalZero(fZEyeA) ? fZEyeA : 1.0 / fZEyeA);
+ const double fInvZEyeB(fTools::equalZero(fZEyeB) ? fZEyeB : 1.0 / fZEyeB);
+ maGlobalTextureCoordinateInterpolators.push_back(B2DPointInterpolator(rA * fInvZEyeA, rB * fInvZEyeB, fInvZEyeA, fInvZEyeB, nDelta));
+ return (maGlobalTextureCoordinateInterpolators.size() - 1L);
+ }
+
+ void increment(B3DScanlineEntry& rScanEntry)
+ {
+ rScanEntry.increment();
+
+ const sal_uInt32 nBColor(rScanEntry.getBColorIndex());
+
+ if(SCANLINE_EMPTY_INDEX != nBColor)
+ {
+ maGlobalBColorInterpolators[nBColor].increment();
+ }
+
+ const sal_uInt32 nNormal(rScanEntry.getNormalIndex());
+
+ if(SCANLINE_EMPTY_INDEX != nNormal)
+ {
+ maGlobalNormalInterpolators[nNormal].increment();
+ }
+
+ const sal_uInt32 nTextureCoordinate(rScanEntry.getTextureCoordinateIndex());
+
+ if(SCANLINE_EMPTY_INDEX != nTextureCoordinate)
+ {
+ maGlobalTextureCoordinateInterpolators[nTextureCoordinate].increment();
+ }
+ }
+
+ void increment(B3DScanlineEntry& rScanEntry, double fStep)
+ {
+ rScanEntry.increment(fStep);
+
+ const sal_uInt32 nBColor(rScanEntry.getBColorIndex());
+
+ if(SCANLINE_EMPTY_INDEX != nBColor)
+ {
+ maGlobalBColorInterpolators[nBColor].increment(fStep);
+ }
+
+ const sal_uInt32 nNormal(rScanEntry.getNormalIndex());
+
+ if(SCANLINE_EMPTY_INDEX != nNormal)
+ {
+ maGlobalNormalInterpolators[nNormal].increment(fStep);
+ }
+
+ const sal_uInt32 nTextureCoordinate(rScanEntry.getTextureCoordinateIndex());
+
+ if(SCANLINE_EMPTY_INDEX != nTextureCoordinate)
+ {
+ maGlobalTextureCoordinateInterpolators[nTextureCoordinate].increment(fStep);
+ }
+ }
+
+ void addEdge(const B3DPolygon& rPolygon, const B3DHomMatrix& rInvEyeToView, sal_uInt32 nIndA, sal_uInt32 nIndB)
+ {
+ B3DPoint aPntA(rPolygon.getB3DPoint(nIndA));
+ B3DPoint aPntB(rPolygon.getB3DPoint(nIndB));
+ sal_Int32 nLineA((sal_Int32)(aPntA.getY()));
+ sal_Int32 nLineB((sal_Int32)(aPntB.getY()));
+
+ if(nLineA == nLineB)
+ {
+ if(!mbAreaMode)
+ {
+ B3DScanlineEntry aNewEntry;
+
+ aNewEntry.setLine(nLineA);
+ aNewEntry.setLineCount(0L);
+ aNewEntry.setXInterpolator(BDInterpolator(aPntA.getX(), aPntB.getX(), 1L));
+ aNewEntry.setZInterpolator(BDInterpolator(aPntA.getZ(), aPntB.getZ(), 1L));
+ aNewEntry.setBColorIndex(SCANLINE_EMPTY_INDEX);
+ aNewEntry.setNormalIndex(SCANLINE_EMPTY_INDEX);
+ aNewEntry.setTextureCoordinateIndex(SCANLINE_EMPTY_INDEX);
+
+ maGlobalEntries.push_back(aNewEntry);
+ }
+ }
+ else
+ {
+ if(nLineB < nLineA)
+ {
+ ::std::swap(aPntA, aPntB);
+ ::std::swap(nLineA, nLineB);
+ ::std::swap(nIndA, nIndB);
+ }
+
+ const sal_uInt32 nLineDelta(nLineB - nLineA);
+ B3DScanlineEntry aNewEntry;
+
+ aNewEntry.setLine(nLineA);
+ aNewEntry.setLineCount(nLineDelta);
+ aNewEntry.setXInterpolator(BDInterpolator(aPntA.getX(), aPntB.getX(), nLineDelta));
+ aNewEntry.setZInterpolator(BDInterpolator(aPntA.getZ(), aPntB.getZ(), nLineDelta));
+
+ const bool bColUsed(mbAreaMode && rPolygon.areBColorsUsed());
+ aNewEntry.setBColorIndex(bColUsed ? addBColor(rPolygon.getBColor(nIndA), rPolygon.getBColor(nIndB), nLineDelta) : SCANLINE_EMPTY_INDEX);
+
+ const bool bNrmUsed(mbAreaMode && rPolygon.areNormalsUsed());
+ aNewEntry.setNormalIndex(bNrmUsed ? addNormal(rPolygon.getNormal(nIndA), rPolygon.getNormal(nIndB), nLineDelta) : SCANLINE_EMPTY_INDEX);
+
+ const bool bTexUsed(mbAreaMode && rPolygon.areTextureCoordinatesUsed());
+ if(bTexUsed)
+ {
+ const double fEyeA((rInvEyeToView * aPntA).getZ());
+ const double fEyeB((rInvEyeToView * aPntB).getZ());
+ aNewEntry.setTextureCoordinateIndex(addTextureCoordinate(
+ rPolygon.getTextureCoordinate(nIndA),
+ rPolygon.getTextureCoordinate(nIndB),
+ fEyeA, fEyeB, nLineDelta));
+ }
+ else
+ {
+ aNewEntry.setTextureCoordinateIndex(SCANLINE_EMPTY_INDEX);
+ }
+
+ maGlobalEntries.push_back(aNewEntry);
+ }
+ }
+
+ // virtual rasterconverter
+ virtual void processSpan(const B3DScanlineEntry& rA, const B3DScanlineEntry& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) = 0;
+ virtual void processLine(const B3DScanlineEntry& rEntry, sal_Int32 nLine) = 0;
+
+ public:
+ B3DPolyPolygonRasterConverter(bool bArea)
+ : mbAreaMode(bArea)
+ {
+ }
+
+ void addPolygon(const B3DPolygon& rPolygon, const B3DHomMatrix& rInvEyeToView)
+ {
+ const sal_uInt32 nPointCount(rPolygon.count());
+
+ if(nPointCount)
+ {
+ const sal_uInt32 nLoopCount((mbAreaMode || rPolygon.isClosed()) ? nPointCount : nPointCount - 1L);
+ const bool bEnoughEdges(mbAreaMode ? (nLoopCount > 2L) : (nLoopCount > 0L));
+
+ if(bEnoughEdges)
+ {
+ for(sal_uInt32 a(0L); a < nLoopCount; a++)
+ {
+ addEdge(rPolygon, rInvEyeToView, a, (a + 1L) % nPointCount);
+ }
+ }
+ }
+ }
+
+ void rasterconvert(sal_Int32 nStartLine, sal_Int32 nStopLine)
+ {
+ OSL_ENSURE(nStartLine <= nStopLine, "rasterconvert: wrong start/stop line (!)");
+
+ if(maGlobalEntries.size())
+ {
+ // sort global entries by YStart, xPos once
+ ::std::sort(maGlobalEntries.begin(), maGlobalEntries.end());
+
+ // local parameters
+ ::std::vector< B3DScanlineEntry >::iterator aCurrentGlobalEntry(maGlobalEntries.begin());
+ ::std::vector< B3DScanlineEntry* > aCurrentScanLine;
+ ::std::vector< B3DScanlineEntry* > aNextScanLine;
+ ::std::vector< B3DScanlineEntry* >::iterator aScanLineEntry;
+ sal_Int32 nLineNumber(nStartLine);
+ sal_uInt32 nPairCount;
+
+ while((nLineNumber < nStopLine) && (aCurrentScanLine.size() || aCurrentGlobalEntry != maGlobalEntries.end()))
+ {
+ // add all global entries which start at current Y to current scanline
+ while(aCurrentGlobalEntry != maGlobalEntries.end() && aCurrentGlobalEntry->getLine() <= nLineNumber)
+ {
+ if(aCurrentGlobalEntry->getLine() < nLineNumber)
+ {
+ // adapt to current line in nLineNumber by decrementing count incrementing accordigly
+ const sal_uInt32 nLineDiff(nLineNumber - aCurrentGlobalEntry->getLine());
+
+ if(aCurrentGlobalEntry->decrement(nLineDiff))
+ {
+ increment(*aCurrentGlobalEntry, (double)nLineDiff);
+ aCurrentScanLine.push_back(&(*(aCurrentGlobalEntry)));
+ }
+ }
+ else
+ {
+ aCurrentScanLine.push_back(&(*(aCurrentGlobalEntry)));
+ }
+
+ aCurrentGlobalEntry++;
+ }
+
+ if(mbAreaMode)
+ {
+ // sort current scanline using simple comparator (only X is compared)
+ ::std::sort(aCurrentScanLine.begin(), aCurrentScanLine.end(), scanlineEntryComparator());
+ }
+
+ // process current scanline
+ aScanLineEntry = aCurrentScanLine.begin();
+ aNextScanLine.clear();
+ nPairCount = 0L;
+
+ while(aScanLineEntry != aCurrentScanLine.end())
+ {
+ B3DScanlineEntry& rPrevScanLineEntry(**aScanLineEntry++);
+
+ if(mbAreaMode)
+ {
+ // area mode, look for 2nd span
+ if(aScanLineEntry != aCurrentScanLine.end())
+ {
+ // work on span from rPrevScanLineEntry to aScanLineEntry, nLineNumber is valid
+ processSpan(rPrevScanLineEntry, **aScanLineEntry, nLineNumber, nPairCount++);
+ }
+ }
+ else
+ {
+ // work on line position rPrevScanLineEntry
+ processLine(rPrevScanLineEntry, nLineNumber);
+ }
+
+ // do decrement counter and (evtl) increment to next line
+ if(rPrevScanLineEntry.decrement())
+ {
+ increment(rPrevScanLineEntry);
+ aNextScanLine.push_back(&rPrevScanLineEntry);
+ }
+ }
+
+ // copy back next scanline if count has changed
+ if(aNextScanLine.size() != aCurrentScanLine.size())
+ {
+ aCurrentScanLine = aNextScanLine;
+ }
+
+ // increment nLineNumber
+ nLineNumber++;
+ }
+ }
+ }
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ BitmapEx getBitmapEx(const BPixelRaster& rRaster)
+ {
+ BitmapEx aRetval;
+ const sal_uInt32 nWidth(rRaster.getWidth());
+ const sal_uInt32 nHeight(rRaster.getHeight());
+
+ if(nWidth && nHeight)
+ {
+ sal_uInt8 nInitAlpha(255);
+ Bitmap aContent(Size(nWidth, nHeight), 24);
+ AlphaMask aAlpha(Size(nWidth, nHeight), &nInitAlpha);
+ BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
+ BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
+
+ if(pContent && pAlpha)
+ {
+ sal_uInt32 nIndex(0L);
+
+ for(sal_uInt32 y(0L); y < nHeight; y++)
+ {
+ for(sal_uInt32 x(0L); x < nWidth; x++)
+ {
+ const BPixel& rPixel(rRaster.getBPixel(nIndex++));
+
+ if(rPixel.getOpacity())
+ {
+ pContent->SetPixel(y, x, BitmapColor(rPixel.getRed(), rPixel.getGreen(), rPixel.getBlue()));
+ pAlpha->SetPixel(y, x, BitmapColor(255 - rPixel.getOpacity()));
+ }
+ }
+ }
+
+ delete pContent;
+ delete pAlpha;
+ }
+
+ aRetval = BitmapEx(aContent, aAlpha);
+ }
+
+ return aRetval;
+ }
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace
+ {
+ class BZPolyRaCon : public basegfx::B3DPolyPolygonRasterConverter
+ {
+ protected:
+ basegfx::BZPixelRaster& mrBuffer;
+ const attribute::materialAttribute3D& mrMaterial;
+ const processor3d::defaultProcessor3D& mrProcessor;
+
+ // virtual rasterconverter
+ virtual void processSpan(const basegfx::B3DScanlineEntry& rA, const basegfx::B3DScanlineEntry& rB, sal_Int32 nLine, sal_uInt32 nSpanCount);
+ virtual void processLine(const basegfx::B3DScanlineEntry& rEntry, sal_Int32 nLine);
+
+ public:
+ BZPolyRaCon(
+ bool bArea,
+ basegfx::BZPixelRaster& rBuffer,
+ const attribute::materialAttribute3D& rMaterial,
+ const processor3d::defaultProcessor3D& rProcessor)
+ : B3DPolyPolygonRasterConverter(bArea),
+ mrBuffer(rBuffer),
+ mrMaterial(rMaterial),
+ mrProcessor(rProcessor)
+ {}
+ };
+
+ void BZPolyRaCon::processSpan(const basegfx::B3DScanlineEntry& rA, const basegfx::B3DScanlineEntry& rB, sal_Int32 nLine, sal_uInt32 nSpanCount)
+ {
+ if(!(nSpanCount & 0x0001))
+ {
+ if(nLine >= 0L && nLine < (sal_Int32)mrBuffer.getHeight())
+ {
+ sal_Int32 nXA((sal_Int32)(rA.getXInterpolator().getVal()));
+ sal_Int32 nXB((sal_Int32)(rB.getXInterpolator().getVal()));
+ OSL_ENSURE(nXB >= nXA,"processSpan: positive run expected (!)");
+
+ if(nXB > nXA)
+ {
+ // initialize Z interpolator
+ const sal_uInt32 nSpanLength(nXB - nXA);
+ basegfx::BDInterpolator aZ(rA.getZInterpolator().getVal(), rB.getZInterpolator().getVal(), nSpanLength);
+
+ // prepare some references to used variables
+ const basegfx::BColor& rColor(mrMaterial.getColor());
+ const basegfx::BColor& rSpecular(mrMaterial.getSpecular());
+ const basegfx::BColor& rEmission(mrMaterial.getEmission());
+ const sal_uInt16 nSpecularIntensity(mrMaterial.getSpecularIntensity());
+
+ // get bools and init other interpolators on demand accordingly
+ const bool bUseTex((mrProcessor.getGeoTexSvx() || mrProcessor.getTransparenceGeoTexSvx()) && rA.getTextureCoordinateIndex() != SCANLINE_EMPTY_INDEX && rB.getTextureCoordinateIndex() != SCANLINE_EMPTY_INDEX);
+ const bool bUseColorTex(bUseTex && mrProcessor.getGeoTexSvx());
+ const bool bNeedOthers(!bUseColorTex || (bUseColorTex && mrProcessor.getModulate()));
+ const bool bUseNrm(bNeedOthers && rA.getNormalIndex() != SCANLINE_EMPTY_INDEX && rB.getNormalIndex() != SCANLINE_EMPTY_INDEX);
+ const bool bUseCol(!bUseNrm && bNeedOthers && rA.getBColorIndex() != SCANLINE_EMPTY_INDEX && rB.getBColorIndex() != SCANLINE_EMPTY_INDEX);
+ const bool bModifyColor(mrProcessor.getBColorModifierStack().count());
+ basegfx::B2DPointInterpolator aTex;
+ basegfx::B3DVectorInterpolator aNrm;
+ basegfx::BColorInterpolator aCol;
+
+ if(bUseTex)
+ {
+ const basegfx::B2DPointInterpolator& rA(maGlobalTextureCoordinateInterpolators[rA.getTextureCoordinateIndex()]);
+ const basegfx::B2DPointInterpolator& rB(maGlobalTextureCoordinateInterpolators[rB.getTextureCoordinateIndex()]);
+ aTex = basegfx::B2DPointInterpolator(rA.getVal(), rB.getVal(), rA.getZVal(), rB.getZVal(), nSpanLength);
+ }
+
+ if(bUseNrm)
+ {
+ aNrm = basegfx::B3DVectorInterpolator(
+ maGlobalNormalInterpolators[rA.getNormalIndex()].getVal(),
+ maGlobalNormalInterpolators[rB.getNormalIndex()].getVal(),
+ nSpanLength);
+ }
+
+ if(bUseCol)
+ {
+ aCol = basegfx::BColorInterpolator(
+ maGlobalBColorInterpolators[rA.getBColorIndex()].getVal(),
+ maGlobalBColorInterpolators[rB.getBColorIndex()].getVal(),
+ nSpanLength);
+ }
+
+ if(nXA < 0L)
+ {
+ const double fIncrement(-nXA);
+ nXA = 0L;
+ aZ.increment(fIncrement);
+
+ if(bUseTex)
+ {
+ aTex.increment(fIncrement);
+ }
+
+ if(bUseNrm)
+ {
+ aNrm.increment(fIncrement);
+ }
+
+ if(bUseCol)
+ {
+ aCol.increment(fIncrement);
+ }
+ }
+
+ if(nXB > (sal_Int32)mrBuffer.getWidth())
+ {
+ nXB = mrBuffer.getWidth();
+ }
+
+ if(nXA < nXB)
+ {
+ sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY((sal_uInt32)nXA, (sal_uInt32)nLine));
+
+ while(nXA < nXB)
+ {
+ // get old and new Z to see if we need to do somethng at all
+ sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex));
+ const sal_uInt16 nNewZ((sal_uInt16)(aZ.getVal()));
+
+ if(nNewZ > rOldZ)
+ {
+ // prepare color
+ basegfx::BColor aNewColor(rColor);
+ double fOpacity(1.0);
+ bool bOpacity(true);
+
+ if(bUseTex)
+ {
+ // get texture coor
+ const basegfx::B2DPoint aTexCoor(aTex.getVal() / aTex.getZVal());
+
+ if(mrProcessor.getGeoTexSvx())
+ {
+ // calc color in spot
+ mrProcessor.getGeoTexSvx()->modifyBColor(aTexCoor, aNewColor, fOpacity);
+ bOpacity = basegfx::fTools::more(fOpacity, 0.0);
+ }
+
+ if(bOpacity && mrProcessor.getTransparenceGeoTexSvx())
+ {
+ // calc opacity
+ mrProcessor.getTransparenceGeoTexSvx()->modifyOpacity(aTexCoor, fOpacity);
+ bOpacity = basegfx::fTools::more(fOpacity, 0.0);
+ }
+ }
+
+ if(bOpacity)
+ {
+ if(mrProcessor.getGeoTexSvx())
+ {
+ if(bUseNrm)
+ {
+ // blend texture with phong
+ aNewColor = mrProcessor.getSdrLightingAttribute().solveColorModel(aNrm.getVal(), aNewColor, rSpecular, rEmission, nSpecularIntensity);
+ }
+ else if(bUseCol)
+ {
+ // blend texture with gouraud
+ aNewColor *= aCol.getVal();
+ }
+ else if(mrProcessor.getModulate())
+ {
+ // blend texture with single material color
+ aNewColor *= rColor;
+ }
+ }
+ else
+ {
+ if(bUseNrm)
+ {
+ // modify color with phong
+ aNewColor = mrProcessor.getSdrLightingAttribute().solveColorModel(aNrm.getVal(), rColor, rSpecular, rEmission, nSpecularIntensity);
+ }
+ else if(bUseCol)
+ {
+ // modify color with gouraud
+ aNewColor = aCol.getVal();
+ }
+ }
+
+ if(bModifyColor)
+ {
+ aNewColor = mrProcessor.getBColorModifierStack().getModifiedColor(aNewColor);
+ }
+
+ if(basegfx::fTools::moreOrEqual(fOpacity, 1.0))
+ {
+ // full opacity, set z and color
+ rOldZ = nNewZ;
+ mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(aNewColor, 0xff);
+ }
+ else
+ {
+ basegfx::BPixel& rDest = mrBuffer.getBPixel(nScanlineIndex);
+
+ if(rDest.getOpacity())
+ {
+ // mix color and existing color
+ const double fOld(1.0 - fOpacity);
+ fOpacity *= 255.0;
+ rDest.setRed((sal_uInt8)(((double)rDest.getRed() * fOld) + (aNewColor.getRed() * fOpacity)));
+ rDest.setGreen((sal_uInt8)(((double)rDest.getGreen() * fOld) + (aNewColor.getGreen() * fOpacity)));
+ rDest.setBlue((sal_uInt8)(((double)rDest.getBlue() * fOld) + (aNewColor.getBlue() * fOpacity)));
+
+ if((sal_uInt8)255 != rDest.getOpacity())
+ {
+ // mix opacities by adding
+ double fNewOpacity(rDest.getOpacity() + fOpacity);
+
+ if(fNewOpacity > 255.0)
+ {
+ // set full opacity
+ rDest.setOpacity(0xff);
+ }
+ else
+ {
+ // set new opacity which is still transparent, so set no z
+ rDest.setOpacity((sal_uInt8)(fNewOpacity));
+ }
+ }
+ }
+ else
+ {
+ // set color and opacity
+ rDest = basegfx::BPixel(aNewColor, (sal_uInt8)(fOpacity * 255.0));
+ }
+ }
+ }
+ }
+
+ // increments
+ {
+ nScanlineIndex++;
+ nXA++;
+ aZ.increment();
+
+ if(bUseTex)
+ {
+ aTex.increment();
+ }
+
+ if(bUseNrm)
+ {
+ aNrm.increment();
+ }
+
+ if(bUseCol)
+ {
+ aCol.increment();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void BZPolyRaCon::processLine(const basegfx::B3DScanlineEntry& rEntry, sal_Int32 nLine)
+ {
+ if(nLine >= 0L && nLine < (sal_Int32)mrBuffer.getHeight())
+ {
+ sal_Int32 nXA((sal_uInt32)(rEntry.getXInterpolator().getVal()));
+ sal_Int32 nXB((sal_uInt32)(rEntry.getXInterpolator().getVal() + rEntry.getXInterpolator().getInc()));
+
+ if(nXA == nXB)
+ {
+ // only one position, get values and set direct
+ if(nXA >= 0L && nXA < (sal_Int32)mrBuffer.getWidth())
+ {
+ const sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY((sal_uInt32)nXA, (sal_uInt32)nLine));
+ sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex));
+ const sal_uInt16 nNewZ((sal_uInt16)(rEntry.getZInterpolator().getVal()) + 0x00ff);
+
+ if(nNewZ > rOldZ)
+ {
+ rOldZ = nNewZ;
+ mrBuffer.getBPixel(nScanlineIndex) = basegfx::BPixel(mrMaterial.getColor(), 0xff);
+ }
+ }
+ }
+ else
+ {
+ const sal_uInt32 nScanlineIndexLine(mrBuffer.getIndexFromXY(0L, (sal_uInt32)nLine));
+ double fZStart(rEntry.getZInterpolator().getVal());
+ double fZStop(fZStart + rEntry.getZInterpolator().getInc());
+
+ if(nXB < nXA)
+ {
+ ::std::swap(nXB, nXA);
+ ::std::swap(fZStart, fZStop);
+ }
+
+ const basegfx::BPixel aPixel(mrMaterial.getColor(), 0xff);
+ const sal_uInt32 nSpanLength(nXB - nXA);
+ basegfx::BDInterpolator aZ(fZStart, fZStop, nSpanLength);
+
+ if(nXA < 0L)
+ {
+ const double fIncrement(-nXA);
+ nXA = 0L;
+ aZ.increment(fIncrement);
+ }
+
+ if(nXB > (sal_Int32)mrBuffer.getWidth())
+ {
+ nXB = mrBuffer.getWidth();
+ }
+
+ if(nXA < nXB)
+ {
+ sal_uInt32 nScanlineIndex(mrBuffer.getIndexFromXY((sal_uInt32)nXA, (sal_uInt32)nLine));
+
+ while(nXA < nXB)
+ {
+ sal_uInt16& rOldZ(mrBuffer.getZ(nScanlineIndex));
+ const sal_uInt16 nNewZ((sal_uInt16)(aZ.getVal()) + 0x00ff);
+
+ if(nNewZ > rOldZ)
+ {
+ rOldZ = nNewZ;
+ mrBuffer.getBPixel(nScanlineIndex) = aPixel;
+ }
+
+ nScanlineIndex++;
+ nXA++;
+ aZ.increment();
+ }
+ }
+ }
+ }
+ }
+ } // end of anonymous namespace
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ class geoTexSvxMono : public geoTexSvx
+ {
+ protected:
+ basegfx::BColor maSingleColor;
+ double mfOpacity;
+
+ public:
+ geoTexSvxMono(const basegfx::BColor& rSingleColor, double fOpacity);
+ virtual ~geoTexSvxMono();
+
+ // compare operator
+ virtual bool operator==(const geoTexSvx& rGeoTexSvx) const;
+ virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
+ virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
+ };
+
+ geoTexSvxMono::geoTexSvxMono(const basegfx::BColor& rSingleColor, double fOpacity)
+ : maSingleColor(rSingleColor),
+ mfOpacity(fOpacity)
+ {
+ }
+
+ geoTexSvxMono::~geoTexSvxMono()
+ {
+ }
+
+ bool geoTexSvxMono::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxMono* pCompare = dynamic_cast< const geoTexSvxMono* >(&rGeoTexSvx);
+ return (pCompare
+ && maSingleColor == pCompare->maSingleColor
+ && mfOpacity == pCompare->mfOpacity);
+ }
+
+ void geoTexSvxMono::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ rBColor = maSingleColor;
+ }
+
+ void geoTexSvxMono::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ {
+ rfOpacity = mfOpacity;
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ class geoTexSvxBitmap : public geoTexSvx
+ {
+ protected:
+ Bitmap maBitmap;
+ BitmapReadAccess* mpRead;
+ basegfx::B2DPoint maTopLeft;
+ basegfx::B2DVector maSize;
+ double mfMulX;
+ double mfMulY;
+
+ // helpers
+ bool impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const;
+
+ public:
+ geoTexSvxBitmap(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize);
+ virtual ~geoTexSvxBitmap();
+ virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
+ virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
+ };
+
+ geoTexSvxBitmap::geoTexSvxBitmap(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
+ : maBitmap(rBitmap),
+ mpRead(0L),
+ maTopLeft(rTopLeft),
+ maSize(rSize),
+ mfMulX(0.0),
+ mfMulY(0.0)
+ {
+ mpRead = maBitmap.AcquireReadAccess();
+ OSL_ENSURE(mpRead, "geoTexSvxBitmap: Got no read access to Bitmap (!)");
+ mfMulX = (double)mpRead->Width() / maSize.getX();
+ mfMulY = (double)mpRead->Height() / maSize.getY();
+ }
+
+ geoTexSvxBitmap::~geoTexSvxBitmap()
+ {
+ delete mpRead;
+ }
+
+ bool geoTexSvxBitmap::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const
+ {
+ if(mpRead)
+ {
+ rX = (sal_Int32)((rUV.getX() - maTopLeft.getX()) * mfMulX);
+
+ if(rX >= 0L && rX < mpRead->Width())
+ {
+ rY = (sal_Int32)((rUV.getY() - maTopLeft.getY()) * mfMulY);
+
+ return (rY >= 0L && rY < mpRead->Height());
+ }
+ }
+
+ return false;
+ }
+
+ void geoTexSvxBitmap::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ sal_Int32 nX, nY;
+
+ if(impIsValid(rUV, nX, nY))
+ {
+ rBColor = Color(mpRead->GetColor(nY, nX)).getBColor();
+ }
+ else
+ {
+ rfOpacity = 0.0;
+ }
+ }
+
+ void geoTexSvxBitmap::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ {
+ sal_Int32 nX, nY;
+
+ if(impIsValid(rUV, nX, nY))
+ {
+ rfOpacity = ((double)(0xff - Color(mpRead->GetColor(nY, nX)).GetLuminance()) * (1.0 / 255.0));
+ }
+ else
+ {
+ rfOpacity = 0.0;
+ }
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ class geoTexSvxBitmapTiled : public geoTexSvxBitmap
+ {
+ protected:
+ // helpers
+ basegfx::B2DPoint impGetCorrected(const basegfx::B2DPoint& rUV) const
+ {
+ double fX(fmod(rUV.getX() - maTopLeft.getX(), maSize.getX()));
+ double fY(fmod(rUV.getY() - maTopLeft.getY(), maSize.getY()));
+
+ if(fX < 0.0)
+ {
+ fX += maSize.getX();
+ }
+
+ if(fY < 0.0)
+ {
+ fY += maSize.getY();
+ }
+
+ return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY());
+ }
+
+ public:
+ geoTexSvxBitmapTiled(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize);
+ virtual ~geoTexSvxBitmapTiled();
+ virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
+ virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
+ };
+
+ geoTexSvxBitmapTiled::geoTexSvxBitmapTiled(const Bitmap& rBitmap, const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
+ : geoTexSvxBitmap(rBitmap, rTopLeft, rSize)
+ {
+ }
+
+ geoTexSvxBitmapTiled::~geoTexSvxBitmapTiled()
+ {
+ }
+
+ void geoTexSvxBitmapTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ if(mpRead)
+ {
+ geoTexSvxBitmap::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity);
+ }
+ }
+
+ void geoTexSvxBitmapTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ {
+ if(mpRead)
+ {
+ geoTexSvxBitmap::modifyOpacity(impGetCorrected(rUV), rfOpacity);
+ }
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ class geoTexSvxMultiHatch : public geoTexSvx
+ {
+ protected:
+ basegfx::BColor maColor;
+ double mfLogicPixelSize;
+ geoTexSvxHatch* mp0;
+ geoTexSvxHatch* mp1;
+ geoTexSvxHatch* mp2;
+
+ // bitfield
+ unsigned mbFillBackground : 1;
+
+ // helpers
+ bool impIsOnHatch(const basegfx::B2DPoint& rUV) const;
+
+ public:
+ geoTexSvxMultiHatch(const primitive3d::hatchTexturePrimitive3D& rPrimitive, double fLogicPixelSize);
+ virtual ~geoTexSvxMultiHatch();
+ virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
+ virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
+
+ // dada access
+ bool getFillBackground() const { return mbFillBackground; }
+ };
+
+ geoTexSvxMultiHatch::geoTexSvxMultiHatch(const primitive3d::hatchTexturePrimitive3D& rPrimitive, double fLogicPixelSize)
+ : mfLogicPixelSize(fLogicPixelSize),
+ mp0(0L),
+ mp1(0L),
+ mp2(0L)
+ {
+ const attribute::fillHatchAttribute& rHatch(rPrimitive.getHatch());
+ const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY());
+ const double fAngleA(-rHatch.getAngle());
+ maColor = rHatch.getColor();
+ mbFillBackground = rHatch.isFillBackground();
+ mp0 = new geoTexSvxHatch(aOutlineRange, rHatch.getDistance(), fAngleA);
+
+ if(attribute::HATCHSTYLE_DOUBLE == rHatch.getStyle() || attribute::HATCHSTYLE_TRIPLE == rHatch.getStyle())
+ {
+ mp1 = new geoTexSvxHatch(aOutlineRange, rHatch.getDistance(), fAngleA + F_PI2);
+ }
+
+ if(attribute::HATCHSTYLE_TRIPLE == rHatch.getStyle())
+ {
+ mp2 = new geoTexSvxHatch(aOutlineRange, rHatch.getDistance(), fAngleA + F_PI4);
+ }
+ }
+
+ geoTexSvxMultiHatch::~geoTexSvxMultiHatch()
+ {
+ delete mp0;
+ delete mp1;
+ delete mp2;
+ }
+
+ bool geoTexSvxMultiHatch::impIsOnHatch(const basegfx::B2DPoint& rUV) const
+ {
+ double fSmallestDistance();
+
+ if(mp0->getDistanceToHatch(rUV) < mfLogicPixelSize)
+ {
+ return true;
+ }
+
+ if(mp1 && mp1->getDistanceToHatch(rUV) < mfLogicPixelSize)
+ {
+ return true;
+ }
+
+ if(mp2 && mp2->getDistanceToHatch(rUV) < mfLogicPixelSize)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ void geoTexSvxMultiHatch::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ if(impIsOnHatch(rUV))
+ {
+ rBColor = maColor;
+ }
+ else if(!mbFillBackground)
+ {
+ rfOpacity = 0.0;
+ }
+ }
+
+ void geoTexSvxMultiHatch::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ {
+ if(mbFillBackground || impIsOnHatch(rUV))
+ {
+ rfOpacity = 1.0;
+ }
+ else
+ {
+ rfOpacity = 0.0;
+ }
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor3d
+ {
+ void defaultProcessor3D::impRender_GRX3(const primitive3d::gradientTexturePrimitive3D& rPrimitive, bool bTransparence)
+ {
+ const primitive3d::primitiveVector3D& rSubList = rPrimitive.getPrimitives();
+
+ if(rSubList.size())
+ {
+ // rescue values
+ const bool bOldModulate(mbModulate); mbModulate = rPrimitive.getModulate();
+ const bool bOldFilter(mbFilter); mbFilter = rPrimitive.getFilter();
+ texture::geoTexSvx* pOldTex = (bTransparence) ? mpTransparenceGeoTexSvx : mpGeoTexSvx;
+
+ // create texture
+ const attribute::fillGradientAttribute& rFillGradient = rPrimitive.getGradient();
+ const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY());
+ const attribute::GradientStyle aGradientStyle(rFillGradient.getStyle());
+ sal_uInt32 nSteps(rFillGradient.getSteps());
+ const basegfx::BColor aStart(rFillGradient.getStartColor());
+ const basegfx::BColor aEnd(rFillGradient.getEndColor());
+ const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
+ texture::geoTexSvx* pNewTex = 0L;
+
+ if(nMaxSteps)
+ {
+ // there IS a color distance
+ if(nSteps == 0L)
+ {
+ nSteps = nMaxSteps;
+ }
+
+ if(nSteps < 2L)
+ {
+ nSteps = 2L;
+ }
+
+ if(nSteps > nMaxSteps)
+ {
+ nSteps = nMaxSteps;
+ }
+
+ switch(aGradientStyle)
+ {
+ case attribute::GRADIENTSTYLE_LINEAR:
+ {
+ pNewTex = new texture::geoTexSvxGradientLinear(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), -rFillGradient.getAngle());
+ break;
+ }
+ case attribute::GRADIENTSTYLE_AXIAL:
+ {
+ pNewTex = new texture::geoTexSvxGradientAxial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), -rFillGradient.getAngle());
+ break;
+ }
+ case attribute::GRADIENTSTYLE_RADIAL:
+ {
+ pNewTex = new texture::geoTexSvxGradientRadial(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY());
+ break;
+ }
+ case attribute::GRADIENTSTYLE_ELLIPTICAL:
+ {
+ pNewTex = new texture::geoTexSvxGradientElliptical(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle());
+ break;
+ }
+ case attribute::GRADIENTSTYLE_SQUARE:
+ {
+ pNewTex = new texture::geoTexSvxGradientSquare(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle());
+ break;
+ }
+ case attribute::GRADIENTSTYLE_RECT:
+ {
+ pNewTex = new texture::geoTexSvxGradientRect(aOutlineRange, aStart, aEnd, nSteps, rFillGradient.getBorder(), rFillGradient.getOffsetX(), rFillGradient.getOffsetY(), -rFillGradient.getAngle());
+ break;
+ }
+ }
+ }
+ else
+ {
+ // no color distance -> same color, use simple texture
+ pNewTex = new texture::geoTexSvxMono(aStart, 1.0 - aStart.luminance());
+ }
+
+ // set created texture
+ if(bTransparence)
+ {
+ mpTransparenceGeoTexSvx = pNewTex;
+ }
+ else
+ {
+ mpGeoTexSvx = pNewTex;
+ }
+
+ // process sub-list
+ process(rSubList);
+
+ // delete texture
+ delete pNewTex;
+
+ // restore values
+ mbModulate = bOldModulate;
+ mbFilter = bOldFilter;
+
+ if(bTransparence)
+ {
+ mpTransparenceGeoTexSvx = pOldTex;
+ }
+ else
+ {
+ mpGeoTexSvx = pOldTex;
+ }
+ }
+ }
+
+ void defaultProcessor3D::impRender_HAX3(const primitive3d::hatchTexturePrimitive3D& rPrimitive)
+ {
+ const primitive3d::primitiveVector3D& rSubList = rPrimitive.getPrimitives();
+
+ if(rSubList.size())
+ {
+ // rescue values
+ const bool bOldModulate(mbModulate); mbModulate = rPrimitive.getModulate();
+ const bool bOldFilter(mbFilter); mbFilter = rPrimitive.getFilter();
+ texture::geoTexSvx* pOldTex = mpGeoTexSvx;
+
+ // calculate logic pixel size in world coordinates
+ const basegfx::B3DPoint aZero(maInvWorldToView * basegfx::B3DPoint(0.0, 0.0, 0.0));
+ const basegfx::B3DPoint aOne(maInvWorldToView * basegfx::B3DPoint(1.0, 1.0, 1.0));
+ const basegfx::B3DVector aLogicPixelSizeWorld(aOne - aZero);
+ double fLogicPixelSizeWorld(fabs(aLogicPixelSizeWorld.getX()));
+
+ if(fabs(aLogicPixelSizeWorld.getY()) > fLogicPixelSizeWorld)
+ {
+ fLogicPixelSizeWorld = fabs(aLogicPixelSizeWorld.getY());
+ }
+
+ if(fabs(aLogicPixelSizeWorld.getZ()) > fLogicPixelSizeWorld)
+ {
+ fLogicPixelSizeWorld = fabs(aLogicPixelSizeWorld.getZ());
+ }
+
+ // calculate logic pixel size in texture coordinates
+ const double fLogicTexSizeX(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getX());
+ const double fLogicTexSizeY(fLogicPixelSizeWorld / rPrimitive.getTextureSize().getY());
+ const double fLogicTexSize(fLogicTexSizeX > fLogicTexSizeY ? fLogicTexSizeX : fLogicTexSizeY);
+
+ // create texture and set
+ texture::geoTexSvxMultiHatch* pNewTex = new texture::geoTexSvxMultiHatch(rPrimitive, fLogicTexSize);
+ mpGeoTexSvx = pNewTex;
+
+ // process sub-list
+ process(rSubList);
+
+ // delete texture
+ delete mpGeoTexSvx;
+
+ // restore values
+ mbModulate = bOldModulate;
+ mbFilter = bOldFilter;
+ mpGeoTexSvx = pOldTex;
+ }
+ }
+
+ void defaultProcessor3D::impRender_BMX3(const primitive3d::bitmapTexturePrimitive3D& rPrimitive)
+ {
+ const primitive3d::primitiveVector3D& rSubList = rPrimitive.getPrimitives();
+
+ if(rSubList.size())
+ {
+ // rescue values
+ const bool bOldModulate(mbModulate); mbModulate = rPrimitive.getModulate();
+ const bool bOldFilter(mbFilter); mbFilter = rPrimitive.getFilter();
+ texture::geoTexSvx* pOldTex = mpGeoTexSvx;
+
+ // create texture
+ const attribute::fillBitmapAttribute& rFillBitmapAttribute = rPrimitive.getBitmap();
+
+ if(rFillBitmapAttribute.getTiling())
+ {
+ mpGeoTexSvx = new texture::geoTexSvxBitmapTiled(
+ rFillBitmapAttribute.getBitmap(),
+ rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(),
+ rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize());
+ }
+ else
+ {
+ mpGeoTexSvx = new texture::geoTexSvxBitmap(
+ rFillBitmapAttribute.getBitmap(),
+ rFillBitmapAttribute.getTopLeft() * rPrimitive.getTextureSize(),
+ rFillBitmapAttribute.getSize() * rPrimitive.getTextureSize());
+ }
+
+ // process sub-list
+ process(rSubList);
+
+ // delete texture
+ delete mpGeoTexSvx;
+
+ // restore values
+ mbModulate = bOldModulate;
+ mbFilter = bOldFilter;
+ mpGeoTexSvx = pOldTex;
+ }
+ }
+
+ void defaultProcessor3D::impRender_MCOL(const primitive3d::modifiedColorPrimitive3D& rModifiedCandidate)
+ {
+ const primitive3d::primitiveVector3D& rSubList = rModifiedCandidate.getPrimitives();
+
+ if(rSubList.size())
+ {
+ maBColorModifierStack.push(rModifiedCandidate.getColorModifier());
+ process(rModifiedCandidate.getPrimitives());
+ maBColorModifierStack.pop();
+ }
+ }
+
+ void defaultProcessor3D::impRender_POH3(const primitive3d::polygonHairlinePrimitive3D& rPrimitive)
+ {
+ basegfx::B3DPolygon aHairline(rPrimitive.getB3DPolygon());
+
+ if(aHairline.count() && mpBZPixelRaster)
+ {
+ // hairlines need no extra data, clear it
+ aHairline.clearTextureCoordinates();
+ aHairline.clearNormals();
+ aHairline.clearBColors();
+
+ // transform to device coordinates (-1.0 .. 1.0) and check for visibility
+ aHairline.transform(maWorldToView);
+ const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aHairline));
+ const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
+
+ if(a2DRange.overlaps(maRasterRange))
+ {
+ const attribute::materialAttribute3D aMaterial(rPrimitive.getBColor());
+ BZPolyRaCon aNewRaCon(false, *mpBZPixelRaster, aMaterial, *this);
+ aNewRaCon.addPolygon(aHairline, maInvEyeToView);
+ aNewRaCon.rasterconvert(0L, mpBZPixelRaster->getHeight());
+ }
+ }
+ }
+
+ void defaultProcessor3D::impRender_POM3(const primitive3d::polyPolygonMaterialPrimitive3D& rPrimitive)
+ {
+ basegfx::B3DPolyPolygon aFill(rPrimitive.getB3DPolyPolygon());
+ basegfx::BColor aObjectColor(rPrimitive.getMaterial().getColor());
+ bool bPaintIt(aFill.count() && mpBZPixelRaster);
+
+ if(bPaintIt)
+ {
+ // get rid of texture coordinates if there is no texture
+ if(aFill.areTextureCoordinatesUsed() && !mpGeoTexSvx && !mpTransparenceGeoTexSvx)
+ {
+ aFill.clearTextureCoordinates();
+ }
+
+ // transform to device coordinates (-1.0 .. 1.0) and check for visibility
+ aFill.transform(maWorldToView);
+ const basegfx::B3DRange a3DRange(basegfx::tools::getRange(aFill));
+ const basegfx::B2DRange a2DRange(a3DRange.getMinX(), a3DRange.getMinY(), a3DRange.getMaxX(), a3DRange.getMaxY());
+
+ bPaintIt = a2DRange.overlaps(maRasterRange);
+ }
+
+ // check if it shall be painted regarding hiding of normals (backface culling)
+ if(bPaintIt && !rPrimitive.getDoubleSided())
+ {
+ // get plane normal of polygon in view coordinates (with ZBuffer values),
+ // left-handed coordinate system
+ const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
+
+ if(aPlaneNormal.getZ() > 0.0)
+ {
+ bPaintIt = false;
+ }
+ }
+
+ if(bPaintIt)
+ {
+ ::com::sun::star::drawing::ShadeMode aShadeMode(mrSdrSceneAttribute.getShadeMode());
+ basegfx::B3DHomMatrix aNormalTransform(maWorldToEye);
+
+ if(mrSdrSceneAttribute.getTwoSidedLighting())
+ {
+ // get plane normal of polygon in view coordinates (with ZBuffer values),
+ // left-handed coordinate system
+ const basegfx::B3DVector aPlaneNormal(aFill.getB3DPolygon(0L).getNormal());
+
+ if(aPlaneNormal.getZ() > 0.0)
+ {
+ // mirror normals
+ aNormalTransform.scale(-1.0, -1.0, -1.0);
+ }
+ }
+
+ if(::com::sun::star::drawing::ShadeMode_PHONG == aShadeMode)
+ {
+ // phong shading
+ if(aFill.areNormalsUsed())
+ {
+ // transform normals to eye coor
+ aFill.transformNormals(aNormalTransform);
+ }
+ else
+ {
+ // fallback to gouraud when no normals available
+ aShadeMode = ::com::sun::star::drawing::ShadeMode_SMOOTH;
+ }
+ }
+
+ if(::com::sun::star::drawing::ShadeMode_SMOOTH == aShadeMode)
+ {
+ // gouraud shading
+ if(aFill.areNormalsUsed())
+ {
+ // transform normals to eye coor
+ aFill.transformNormals(aNormalTransform);
+
+ // prepare color model parameters, evtl. use blend color
+ const basegfx::BColor aColor(mbModulate ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
+ const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
+ const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
+ const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
+
+ // solve color model for each normal vector, set colors at points. Clear normals.
+ for(sal_uInt32 a(0L); a < aFill.count(); a++)
+ {
+ basegfx::B3DPolygon aPartFill(aFill.getB3DPolygon(a));
+
+ for(sal_uInt32 b(0L); b < aPartFill.count(); b++)
+ {
+ // solve color model. Transform normal to eye coor
+ const basegfx::B3DVector aNormal(aPartFill.getNormal(b));
+ const basegfx::BColor aSolvedColor(mrSdrLightingAttribute.solveColorModel(aNormal, aColor, rSpecular, rEmission, nSpecularIntensity));
+ aPartFill.setBColor(b, aSolvedColor);
+ }
+
+ // clear normals on this part polygon and write it back
+ aPartFill.clearNormals();
+ aFill.setB3DPolygon(a, aPartFill);
+ }
+ }
+ else
+ {
+ // fallback to flat when no normals available
+ aShadeMode = ::com::sun::star::drawing::ShadeMode_FLAT;
+ }
+ }
+
+ if(::com::sun::star::drawing::ShadeMode_FLAT == aShadeMode)
+ {
+ // flat shading. Clear normals and colors
+ aFill.clearNormals();
+ aFill.clearBColors();
+
+ // get plane vector in eye coordinates
+ const basegfx::B3DVector aPlaneEyeNormal(aNormalTransform * rPrimitive.getB3DPolyPolygon().getB3DPolygon(0L).getNormal());
+
+ // prepare color model parameters, evtl. use blend color
+ const basegfx::BColor aColor(mbModulate ? basegfx::BColor(1.0, 1.0, 1.0) : rPrimitive.getMaterial().getColor());
+ const basegfx::BColor& rSpecular(rPrimitive.getMaterial().getSpecular());
+ const basegfx::BColor& rEmission(rPrimitive.getMaterial().getEmission());
+ const sal_uInt16 nSpecularIntensity(rPrimitive.getMaterial().getSpecularIntensity());
+
+ // solve color model for plane vector and use that color for whole plane
+ aObjectColor = mrSdrLightingAttribute.solveColorModel(aPlaneEyeNormal, aColor, rSpecular, rEmission, nSpecularIntensity);
+ }
+
+ if(::com::sun::star::drawing::ShadeMode_DRAFT == aShadeMode)
+ {
+ // draft, just use object color which is already set. Delete all other infos
+ aFill.clearNormals();
+ aFill.clearBColors();
+ }
+ }
+
+ if(bPaintIt)
+ {
+ // draw it to ZBuffer
+ const attribute::materialAttribute3D aMaterial(
+ aObjectColor, rPrimitive.getMaterial().getSpecular(),
+ rPrimitive.getMaterial().getEmission(),
+ rPrimitive.getMaterial().getSpecularIntensity());
+ BZPolyRaCon aNewRaCon(true, *mpBZPixelRaster, aMaterial, *this);
+
+ for(sal_uInt32 a(0L); a < aFill.count(); a++)
+ {
+ aNewRaCon.addPolygon(aFill.getB3DPolygon(a), maInvEyeToView);
+ }
+
+ aNewRaCon.rasterconvert(0L, mpBZPixelRaster->getHeight());
+ }
+ }
+
+ void defaultProcessor3D::impRender_TRN3(const primitive3d::transformPrimitive3D& rTransformCandidate)
+ {
+ // remember current transformations
+ basegfx::B3DHomMatrix aLastWorldToView(maWorldToView);
+ basegfx::B3DHomMatrix aLastWorldToEye(maWorldToEye);
+ basegfx::B3DHomMatrix aLastInvWorldToView(maInvWorldToView);
+
+ // create new transformations
+ maWorldToView = maWorldToView * rTransformCandidate.getTransformation();
+ maWorldToEye = maWorldToEye * rTransformCandidate.getTransformation();
+ maInvWorldToView = maWorldToView;
+ maInvWorldToView.invert();
+
+ // let break down
+ process(rTransformCandidate.getPrimitives());
+
+ // restore transformations
+ maWorldToView = aLastWorldToView;
+ maWorldToEye = aLastWorldToEye;
+ maInvWorldToView = aLastInvWorldToView;
+ }
+
+ void defaultProcessor3D::process(const primitive3d::primitiveVector3D& rSource)
+ {
+ for(sal_uInt32 a(0L); a < rSource.size(); a++)
+ {
+ const primitive3d::referencedPrimitive3D& rCandidate = rSource[a];
+
+ switch(rCandidate.getID())
+ {
+ case CreatePrimitiveID('G', 'R', 'X', '3'):
+ {
+ // gradientTexturePrimitive3D
+ const primitive3d::gradientTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::gradientTexturePrimitive3D& >(rCandidate.getBasePrimitive());
+ impRender_GRX3(rPrimitive, false);
+ break;
+ }
+
+ case CreatePrimitiveID('H', 'A', 'X', '3'):
+ {
+ static bool bDoHatchDecomposition(true);
+
+ if(bDoHatchDecomposition)
+ {
+ // let break down
+ process(rCandidate.getBasePrimitive().getDecomposition());
+ }
+ else
+ {
+ // hatchTexturePrimitive3D
+ const primitive3d::hatchTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::hatchTexturePrimitive3D& >(rCandidate.getBasePrimitive());
+ impRender_HAX3(rPrimitive);
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('B', 'M', 'X', '3'):
+ {
+ // bitmapTexturePrimitive3D
+ const primitive3d::bitmapTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::bitmapTexturePrimitive3D& >(rCandidate.getBasePrimitive());
+ impRender_BMX3(rPrimitive);
+ break;
+ }
+
+ case CreatePrimitiveID('T', 'R', 'X', '3'):
+ {
+ // transparenceTexturePrimitive3D
+ const primitive3d::transparenceTexturePrimitive3D& rPrimitive = static_cast< const primitive3d::transparenceTexturePrimitive3D& >(rCandidate.getBasePrimitive());
+
+ if(mbProcessTransparent)
+ {
+ impRender_GRX3(rPrimitive, true);
+ }
+ else
+ {
+ mbContainsTransparent = true;
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('M', 'C', 'L', '3'):
+ {
+ // modified color group. Force output to unified color.
+ const primitive3d::modifiedColorPrimitive3D& rPrimitive = static_cast< const primitive3d::modifiedColorPrimitive3D& >(rCandidate.getBasePrimitive());
+ impRender_MCOL(rPrimitive);
+ break;
+ }
+
+ case CreatePrimitiveID('P', 'O', 'H', '3'):
+ {
+ // directdraw of polygonHairlinePrimitive3D
+ const primitive3d::polygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::polygonHairlinePrimitive3D& >(rCandidate.getBasePrimitive());
+
+ if(mbProcessTransparent == (0L != mpTransparenceGeoTexSvx))
+ {
+ impRender_POH3(rPrimitive);
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('P', 'O', 'M', '3'):
+ {
+ // directdraw of polyPolygonMaterialPrimitive3D
+ const primitive3d::polyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::polyPolygonMaterialPrimitive3D& >(rCandidate.getBasePrimitive());
+
+ if(mbProcessTransparent == (0L != mpTransparenceGeoTexSvx))
+ {
+ impRender_POM3(rPrimitive);
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('T', 'R', 'N', '3'):
+ {
+ // transform group.
+ impRender_TRN3(static_cast< const primitive3d::transformPrimitive3D& >(rCandidate.getBasePrimitive()));
+ break;
+ }
+
+ case CreatePrimitiveID('L', 'A', 'B', '3'):
+ {
+ // sdrLabelPrimitive3D. Accept, but ignore. Is handled by the scenePrimitive decompose
+ // method which creates 2d text objects at the 3d-projection-dependent positions.
+ break;
+ }
+
+ default:
+ {
+ // let break down
+ process(rCandidate.getBasePrimitive().getDecomposition());
+ break;
+ }
+ }
+ }
+ }
+
+ void defaultProcessor3D::processNonTransparent(const primitive3d::primitiveVector3D& rSource)
+ {
+ mbProcessTransparent = false;
+ mbContainsTransparent = false;
+ process(rSource);
+ }
+
+ void defaultProcessor3D::processTransparent(const primitive3d::primitiveVector3D& rSource)
+ {
+ if(mbContainsTransparent)
+ {
+ mbProcessTransparent = true;
+ process(rSource);
+ }
+ }
+
+ defaultProcessor3D::defaultProcessor3D(
+ const geometry::viewInformation& rViewInformation,
+ const geometry::transformation3D& rTransformation3D,
+ const attribute::sdrSceneAttribute& rSdrSceneAttribute,
+ const attribute::sdrLightingAttribute& rsdrLightingAttribute,
+ double fSizeX,
+ double fSizeY,
+ const basegfx::B2DRange& rVisiblePart)
+ : baseProcessor3D(rViewInformation, rTransformation3D),
+ mrSdrSceneAttribute(rSdrSceneAttribute),
+ mrSdrLightingAttribute(rsdrLightingAttribute),
+ mpGeoTexSvx(0L),
+ mpTransparenceGeoTexSvx(0L),
+ mbModulate(false),
+ mbFilter(false),
+ mbProcessTransparent(false),
+ mbContainsTransparent(false)
+ {
+ // generate ViewSizes
+ const double fFullViewSizeX((getViewInformation().getViewTransformation() * basegfx::B2DVector(fSizeX, 0.0)).getLength());
+ const double fFullViewSizeY((getViewInformation().getViewTransformation() * basegfx::B2DVector(0.0, fSizeY)).getLength());
+ const double fViewSizeX(fFullViewSizeX * rVisiblePart.getWidth());
+ const double fViewSizeY(fFullViewSizeY * rVisiblePart.getHeight());
+ const sal_uInt32 nViewSizeX((sal_uInt32)floor(fViewSizeX));
+ const sal_uInt32 nViewSizeY((sal_uInt32)floor(fViewSizeY));
+
+ if(nViewSizeX && nViewSizeY)
+ {
+ // create view unit buffer
+ mpBZPixelRaster = new basegfx::BZPixelRaster(nViewSizeX + 1L, nViewSizeY + 1L);
+ OSL_ENSURE(mpBZPixelRaster, "defaultProcessor3D: Could not allocate basegfx::BZPixelRaster (!)");
+
+ // create DeviceToView
+ // outcome is [-1.0 .. 1.0] in X,Y and Z.
+
+ {
+ // step one:
+ //
+ // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also
+ // necessary to
+ // - flip Y due to screen orientation
+ // - flip Z due to Z-Buffer orientation from back to front
+
+ maDeviceToView.scale(0.5, -0.5, -0.5);
+ maDeviceToView.translate(0.5, 0.5, 0.5);
+ }
+
+ {
+ // step two:
+ //
+ // bring from [0.0 .. 1.0] in X,Y and Z to view cordinates. also:
+ // - scale Z to [0.0 .. fMaxZDepth]
+ const double fMaxZDepth(double(0x0000ff00));
+ maDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0);
+ maDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth);
+ }
+
+ // create world to eye transformation
+ maWorldToEye = getTransformation3D().getOrientation() * getTransformation3D().getTransformation();
+
+ // create EyeToView transformation
+ maWorldToView = maDeviceToView * getTransformation3D().getProjection() * maWorldToEye;
+
+ // create inverse EyeToView transformation
+ maInvEyeToView = maDeviceToView * getTransformation3D().getProjection();
+ maInvEyeToView.invert();
+
+ // create inverse WorldToView transformation
+ maInvWorldToView = maWorldToView;
+ maInvWorldToView.invert();
+
+ // prepare maRasterRange
+ maRasterRange.expand(basegfx::B2DPoint(0.0, 0.0));
+ maRasterRange.expand(basegfx::B2DPoint(mpBZPixelRaster->getWidth(), mpBZPixelRaster->getHeight()));
+ }
+ }
+
+ defaultProcessor3D::~defaultProcessor3D()
+ {
+ if(mpBZPixelRaster)
+ {
+ delete mpBZPixelRaster;
+ }
+ }
+
+ BitmapEx defaultProcessor3D::getBitmapEx() const
+ {
+ if(mpBZPixelRaster)
+ {
+ return basegfx::getBitmapEx(*mpBZPixelRaster);
+ }
+
+ return BitmapEx();
+ }
+ } // end of namespace processor3d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/processor3d/makefile.mk b/drawinglayer/source/processor3d/makefile.mk
new file mode 100644
index 000000000000..c05046d27daa
--- /dev/null
+++ b/drawinglayer/source/processor3d/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: aw $ $Date: 2006-08-09 16:57:48 $
+#
+# 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
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=drawinglayer
+TARGET=processor3d
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/baseprocessor3d.obj \
+ $(SLO)$/defaultprocessor3d.obj \
+ $(SLO)$/shadow3dextractor.obj \
+ $(SLO)$/label3dextractor.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
diff --git a/drawinglayer/source/processor3d/shadow3dextractor.cxx b/drawinglayer/source/processor3d/shadow3dextractor.cxx
new file mode 100644
index 000000000000..c9a0d854061d
--- /dev/null
+++ b/drawinglayer/source/processor3d/shadow3dextractor.cxx
@@ -0,0 +1,345 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shadow3dextractor.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: aw $ $Date: 2006-08-09 16:57:48 $
+ *
+ * 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 _DRAWINGLAYER_PROCESSOR3D_SHADOW3DEXTRACTOR_HXX
+#include <drawinglayer/processor3d/shadow3dextractor.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_SHADOWPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/shadowprimitive3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE_SHADOWPRIMITIVE_HXX
+#include <drawinglayer/primitive/shadowprimitive.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_TRANSFORMPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/transformprimitive3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_POLYGONPRIMITIVE3D_HXX
+#include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
+#endif
+
+#ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE3D_POLYPOLYGONPRIMITIVE_HXX
+#include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
+#endif
+
+#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_GEOMETRY_TRANSFORMATION3D_HXX
+#include <drawinglayer/geometry/transformation3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_ATTRIBUTE_SDRATTRIBUTE3D_HXX
+#include <drawinglayer/attribute/sdrattribute3d.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE_SIMPLETRANSPARENCEPRIMITIVE_HXX
+#include <drawinglayer/primitive/simpletransparenceprimitive.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE_POLYGONPRIMITIVE_HXX
+#include <drawinglayer/primitive/polygonprimitive.hxx>
+#endif
+
+#ifndef _DRAWINGLAYER_PRIMITIVE_POLYPOLYGONPRIMITIVE_HXX
+#include <drawinglayer/primitive/polypolygonprimitive.hxx>
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace processor3d
+ {
+ shadow3DExtractingProcessor::shadow3DExtractingProcessor(
+ const geometry::viewInformation& rViewInformation,
+ const geometry::transformation3D& rTransformation3D,
+ const attribute::sdrLightingAttribute& rSdrLightingAttribute,
+ const primitive3d::primitiveVector3D& rPrimitiveVector,
+ double fShadowSlant)
+ : baseProcessor3D(rViewInformation, rTransformation3D),
+ mpTargetVector(&maPrimitiveVector),
+ mbShadowProjectionIsValid(false),
+ mbConvert(false),
+ mbUseProjection(false)
+ {
+ // create deviceToView projection for shadow geometry
+ // outcome is [-1.0 .. 1.0] in X,Y and Z. bring to [0.0 .. 1.0]. Also
+ // necessary to flip Y due to screen orientation
+ // Z is not needed, but will also be brought to [0.0 .. 1.0]
+ basegfx::B3DHomMatrix aDeviceToView;
+ aDeviceToView.scale(0.5, -0.5, 0.5);
+ aDeviceToView.translate(0.5, 0.5, 0.5);
+
+ // create complete 3d transformation set for shadow stuff
+ maWorldToEye = getTransformation3D().getOrientation() * getTransformation3D().getTransformation();
+ maEyeToView = getTransformation3D().getDeviceToView() * getTransformation3D().getProjection();
+ maWorldToView = maEyeToView * maWorldToEye;
+
+ // calculate shadow projection stuff
+ if(rSdrLightingAttribute.getLightVector().size())
+ {
+ // get light normal, plane normal and sclalar from it
+ maLightNormal = rSdrLightingAttribute.getLightVector()[0L].getDirection();
+ maLightNormal.normalize();
+ maShadowPlaneNormal = basegfx::B3DVector(0.0, sin(fShadowSlant), cos(fShadowSlant));
+ maShadowPlaneNormal.normalize();
+ mfLightPlaneScalar = maLightNormal.scalar(maShadowPlaneNormal);
+
+ if(basegfx::fTools::more(mfLightPlaneScalar, 0.0))
+ {
+ // use only when scalar is > 0.0, so the light is in front of the object
+ basegfx::B3DRange aContained3DRange(get3DRangeFromVector(rPrimitiveVector));
+ aContained3DRange.transform(maWorldToEye);
+ maPlanePoint.setX(maShadowPlaneNormal.getX() < 0.0 ? aContained3DRange.getMinX() : aContained3DRange.getMaxX());
+ maPlanePoint.setY(maShadowPlaneNormal.getY() > 0.0 ? aContained3DRange.getMinY() : aContained3DRange.getMaxY());
+ maPlanePoint.setZ(aContained3DRange.getMinZ() - (aContained3DRange.getDepth() / 8.0));
+
+ // set flag that shadow projection is prepared and allowed
+ mbShadowProjectionIsValid = true;
+ }
+ }
+ }
+
+ shadow3DExtractingProcessor::~shadow3DExtractingProcessor()
+ {
+ }
+
+ void shadow3DExtractingProcessor::process(const primitive3d::primitiveVector3D& rSource)
+ {
+ for(sal_uInt32 a(0L); a < rSource.size(); a++)
+ {
+ // get reference
+ const primitive3d::referencedPrimitive3D& rCandidate = rSource[a];
+
+ switch(rCandidate.getID())
+ {
+ case CreatePrimitiveID('S', 'H', 'D', '3'):
+ {
+ // shadow3d object. Call recursive with content and start conversion
+ const primitive3d::shadowPrimitive3D& rPrimitive = static_cast< const primitive3d::shadowPrimitive3D& >(rCandidate.getBasePrimitive());
+
+ // set new target
+ primitive::primitiveVector aNewSubList;
+ primitive::primitiveVector* pLastTargetVector = mpTargetVector;
+ mpTargetVector = &aNewSubList;
+
+ // activate convert
+ const bool bLastConvert(mbConvert);
+ mbConvert = true;
+
+ // set projection flag
+ const bool bLastUseProjection(mbUseProjection);
+ mbUseProjection = rPrimitive.getShadow3D();
+
+ // process content
+ process(rPrimitive.getPrimitives());
+
+ // restore values
+ mbUseProjection = bLastUseProjection;
+ mbConvert = bLastConvert;
+ mpTargetVector = pLastTargetVector;
+
+ // create 2d shadow primitive with result
+ primitive::shadowPrimitive* pNew = new primitive::shadowPrimitive(rPrimitive.getShadowTransform(), rPrimitive.getShadowColor(), aNewSubList);
+
+ if(basegfx::fTools::more(rPrimitive.getShadowTransparence(), 0.0))
+ {
+ // create simpleTransparencePrimitive, add created primitives
+ primitive::primitiveVector aNewTransPrimitiveVector;
+ aNewTransPrimitiveVector.push_back(primitive::referencedPrimitive(*pNew));
+ primitive::simpleTransparencePrimitive* pNewTrans = new primitive::simpleTransparencePrimitive(rPrimitive.getShadowTransparence(), aNewTransPrimitiveVector);
+ mpTargetVector->push_back(primitive::referencedPrimitive(*pNewTrans));
+ }
+ else
+ {
+ // add directly
+ mpTargetVector->push_back(primitive::referencedPrimitive(*pNew));
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('T', 'R', 'N', '3'):
+ {
+ // transform group. Remember current transformations
+ const primitive3d::transformPrimitive3D& rPrimitive = static_cast< const primitive3d::transformPrimitive3D& >(rCandidate.getBasePrimitive());
+ basegfx::B3DHomMatrix aLastWorldToView(maWorldToView);
+ basegfx::B3DHomMatrix aLastWorldToEye(maWorldToEye);
+
+ // create new transformations
+ maWorldToView = maWorldToView * rPrimitive.getTransformation();
+ maWorldToEye = maWorldToEye * rPrimitive.getTransformation();
+
+ // let break down
+ process(rPrimitive.getPrimitives());
+
+ // restore transformations
+ maWorldToView = aLastWorldToView;
+ maWorldToEye = aLastWorldToEye;
+ break;
+ }
+
+ case CreatePrimitiveID('P', 'O', 'H', '3'):
+ {
+ // polygonHairlinePrimitive3D
+ if(mbConvert)
+ {
+ const primitive3d::polygonHairlinePrimitive3D& rPrimitive = static_cast< const primitive3d::polygonHairlinePrimitive3D& >(rCandidate.getBasePrimitive());
+ basegfx::B2DPolygon a2DHairline;
+
+ if(mbUseProjection)
+ {
+ if(mbShadowProjectionIsValid)
+ {
+ a2DHairline = impDoShadowProjection(rPrimitive.getB3DPolygon());
+ }
+ }
+ else
+ {
+ a2DHairline = basegfx::tools::createB2DPolygonFromB3DPolygon(rPrimitive.getB3DPolygon(), maWorldToView);
+ }
+
+ if(a2DHairline.count())
+ {
+ a2DHairline.transform(getTransformation3D().getObjectTransformation());
+ primitive::polygonHairlinePrimitive* pNew = new primitive::polygonHairlinePrimitive(a2DHairline, maPrimitiveColor);
+ mpTargetVector->push_back(primitive::referencedPrimitive(*pNew));
+ }
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('P', 'O', 'M', '3'):
+ {
+ // polyPolygonMaterialPrimitive3D
+ if(mbConvert)
+ {
+ const primitive3d::polyPolygonMaterialPrimitive3D& rPrimitive = static_cast< const primitive3d::polyPolygonMaterialPrimitive3D& >(rCandidate.getBasePrimitive());
+ basegfx::B2DPolyPolygon a2DFill;
+
+ if(mbUseProjection)
+ {
+ if(mbShadowProjectionIsValid)
+ {
+ a2DFill = impDoShadowProjection(rPrimitive.getB3DPolyPolygon());
+ }
+ }
+ else
+ {
+ a2DFill = basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(rPrimitive.getB3DPolyPolygon(), maWorldToView);
+ }
+
+ if(a2DFill.count())
+ {
+ a2DFill.transform(getTransformation3D().getObjectTransformation());
+ primitive::polyPolygonColorPrimitive* pNew = new primitive::polyPolygonColorPrimitive(a2DFill, maPrimitiveColor);
+ mpTargetVector->push_back(primitive::referencedPrimitive(*pNew));
+ }
+ }
+
+ break;
+ }
+
+ case CreatePrimitiveID('L', 'A', 'B', '3'):
+ {
+ // has no 3d shadow, accept and ignore
+ break;
+ }
+
+ default:
+ {
+ // let break down
+ process(rCandidate.getBasePrimitive().getDecomposition());
+ break;
+ }
+ }
+ }
+ }
+
+ basegfx::B2DPolygon shadow3DExtractingProcessor::impDoShadowProjection(const basegfx::B3DPolygon& rSource)
+ {
+ basegfx::B2DPolygon aRetval;
+
+ for(sal_uInt32 a(0L); a < rSource.count(); a++)
+ {
+ // get point, transform to eye coordinate system
+ basegfx::B3DPoint aCandidate(rSource.getB3DPoint(a));
+ aCandidate *= maWorldToEye;
+
+ // we are in eye coordinates
+ // ray is (aCandidate + fCut * maLightNormal)
+ // plane is (maPlanePoint, maShadowPlaneNormal)
+ // maLightNormal.scalar(maShadowPlaneNormal) is already in mfLightPlaneScalar and > 0.0
+ // get cut point of ray with shadow plane
+ const double fCut(basegfx::B3DVector(maPlanePoint - aCandidate).scalar(maShadowPlaneNormal) / mfLightPlaneScalar);
+ aCandidate += maLightNormal * fCut;
+
+ // transform to view, use 2d coordinates
+ aCandidate *= maEyeToView;
+ aRetval.append(basegfx::B2DPoint(aCandidate.getX(), aCandidate.getY()));
+ }
+
+ // copy closed flag
+ aRetval.setClosed(rSource.isClosed());
+
+ return aRetval;
+ }
+
+ basegfx::B2DPolyPolygon shadow3DExtractingProcessor::impDoShadowProjection(const basegfx::B3DPolyPolygon& rSource)
+ {
+ basegfx::B2DPolyPolygon aRetval;
+
+ for(sal_uInt32 a(0L); a < rSource.count(); a++)
+ {
+ aRetval.append(impDoShadowProjection(rSource.getB3DPolygon(a)));
+ }
+
+ return aRetval;
+ }
+ } // end of namespace processor3d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/texture/makefile.mk b/drawinglayer/source/texture/makefile.mk
new file mode 100644
index 000000000000..877a929a8f1e
--- /dev/null
+++ b/drawinglayer/source/texture/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: aw $ $Date: 2006-08-09 16:58:20 $
+#
+# 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
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=drawinglayer
+TARGET=texture
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/texture.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx
new file mode 100644
index 000000000000..afc6e63071ce
--- /dev/null
+++ b/drawinglayer/source/texture/texture.cxx
@@ -0,0 +1,1090 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: texture.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: aw $ $Date: 2006-08-09 16:58:20 $
+ *
+ * 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 _DRAWINGLAYER_TEXTURE_TEXTURE_HXX
+#include <drawinglayer/texture/texture.hxx>
+#endif
+
+#ifndef _BGFX_NUMERIC_FTOOLS_HXX
+#include <basegfx/numeric/ftools.hxx>
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvx::geoTexSvx()
+ {
+ }
+
+ geoTexSvx::~geoTexSvx()
+ {
+ }
+
+ bool geoTexSvx::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ // default implementation says yes (no data -> no difference)
+ return true;
+ }
+
+ void geoTexSvx::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ // default implementation does nothing
+ }
+
+ void geoTexSvx::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ // base implementation creates random color (for testing only, may also be pure virtual)
+ rBColor.setRed((rand() & 0x7fff) / 32767.0);
+ rBColor.setGreen((rand() & 0x7fff) / 32767.0);
+ rBColor.setBlue((rand() & 0x7fff) / 32767.0);
+ }
+
+ void geoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ {
+ // base implementation uses inverse of luminance of solved color
+ basegfx::BColor aBaseColor;
+ modifyBColor(rUV, aBaseColor, rfOpacity);
+ rfOpacity = 1.0 - aBaseColor.luminance();
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ void geoTexSvxGradient::impAppendMatrix(::std::vector< basegfx::B2DHomMatrix >& rMatrices, const basegfx::B2DRange& rRange)
+ {
+ basegfx::B2DHomMatrix aNew;
+ aNew.set(0, 0, rRange.getWidth());
+ aNew.set(1, 1, rRange.getHeight());
+ aNew.set(0, 2, rRange.getMinX());
+ aNew.set(1, 2, rRange.getMinY());
+ rMatrices.push_back(maTextureTransform * aNew);
+ }
+
+ void geoTexSvxGradient::impAppendColorsRadial(::std::vector< basegfx::BColor >& rColors)
+ {
+ if(mnSteps)
+ {
+ rColors.push_back(maStart);
+
+ for(sal_uInt32 a(1L); a < mnSteps - 1L; a++)
+ {
+ rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)mnSteps));
+ }
+
+ rColors.push_back(maEnd);
+ }
+ }
+
+ geoTexSvxGradient::geoTexSvxGradient(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder)
+ : maTargetRange(rTargetRange),
+ maStart(rStart),
+ maEnd(rEnd),
+ mnSteps(nSteps),
+ mfAspect(1.0),
+ mfBorder(fBorder)
+ {
+ }
+
+ geoTexSvxGradient::~geoTexSvxGradient()
+ {
+ }
+
+ bool geoTexSvxGradient::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxGradient* pCompare = dynamic_cast< const geoTexSvxGradient* >(&rGeoTexSvx);
+ return (pCompare
+ && maTextureTransform == pCompare->maTextureTransform
+ && maTargetRange == pCompare->maTargetRange
+ && mnSteps == pCompare->mnSteps
+ && mfAspect == pCompare->mfAspect
+ && mfBorder == pCompare->mfBorder);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientLinear::geoTexSvxGradientLinear(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(0.0, -mfBorder);
+ const double fSizeWithoutBorder(1.0 - mfBorder);
+
+ if(!basegfx::fTools::equal(fSizeWithoutBorder, 0.0))
+ {
+ maBackTextureTransform.scale(1.0, 1.0 / fSizeWithoutBorder);
+ }
+ }
+
+ geoTexSvxGradientLinear::~geoTexSvxGradientLinear()
+ {
+ }
+
+ void geoTexSvxGradientLinear::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fTop(mfBorder);
+ const double fStripeWidth((1.0 - fTop) / mnSteps);
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ const double fOffsetUpper(fStripeWidth * (double)a);
+
+ // create matrix
+ const basegfx::B2DRange aRect(0.0, fTop + fOffsetUpper, 1.0, 1.0);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientLinear::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ if(mnSteps)
+ {
+ rColors.push_back(maStart);
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)(mnSteps + 1L)));
+ }
+ }
+ }
+
+ void geoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+
+ if(basegfx::fTools::lessOrEqual(aCoor.getY(), 0.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ if(basegfx::fTools::moreOrEqual(aCoor.getY(), 1.0))
+ {
+ rBColor = maEnd;
+ return;
+ }
+
+ double fScaler(aCoor.getY());
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps + 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientAxial::geoTexSvxGradientAxial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(0.0, -0.5);
+ const double fSizeWithoutBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fSizeWithoutBorder, 0.0))
+ {
+ maBackTextureTransform.scale(1.0, 1.0 / fSizeWithoutBorder);
+ }
+
+ // fill internal steps for getBColor implementation
+ mfInternalSteps = (double)((mnSteps * 2L) - 1L);
+ }
+
+ geoTexSvxGradientAxial::~geoTexSvxGradientAxial()
+ {
+ }
+
+ void geoTexSvxGradientAxial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder(mfBorder * 0.5);
+ double fTop(fHalfBorder);
+ double fBottom(1.0 - fHalfBorder);
+ const double fStripeWidth((fBottom - fTop) / ((mnSteps * 2L) - 1L));
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ const double fOffset(fStripeWidth * (double)a);
+
+ // create matrix
+ const basegfx::B2DRange aRect(0.0, fTop + fOffset, 1.0, fBottom - fOffset);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientAxial::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ if(mnSteps)
+ {
+ rColors.push_back(maEnd);
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ rColors.push_back(interpolate(maEnd, maStart, (double)a / (double)mnSteps));
+ }
+ }
+ }
+
+ void geoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(basegfx::fTools::moreOrEqual(fAbsY, 1.0))
+ {
+ rBColor = maEnd;
+ return;
+ }
+
+ double fScaler(fAbsY);
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(((fScaler * mfInternalSteps) + 1.0) / 2.0) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientRadial::geoTexSvxGradientRadial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
+ fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
+ fTargetSizeX = fOriginalDiag;
+ fTargetSizeY = fOriginalDiag;
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use original target size
+ fTargetOffsetX += (fOffsetX - 0.5) * maTargetRange.getWidth();
+ fTargetOffsetY += (fOffsetY - 0.5) * maTargetRange.getHeight();
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientRadial::~geoTexSvxGradientRadial()
+ {
+ }
+
+ void geoTexSvxGradientRadial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ fIncrementY = (fBottom - fTop) / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+ else
+ {
+ fIncrementX = (fRight - fLeft) / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientRadial::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fDist(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY());
+
+ if(basegfx::fTools::moreOrEqual(fDist, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - sqrt(fDist));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientElliptical::geoTexSvxGradientElliptical(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX;
+ fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY;
+ fTargetSizeX = 1.4142 * fTargetSizeX;
+ fTargetSizeY = 1.4142 * fTargetSizeY;
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use original target size
+ fTargetOffsetX += (fOffsetX - 0.5) * maTargetRange.getWidth();
+ fTargetOffsetY += (fOffsetY - 0.5) * maTargetRange.getHeight();
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientElliptical::~geoTexSvxGradientElliptical()
+ {
+ }
+
+ void geoTexSvxGradientElliptical::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ fIncrementY = (fBottom - fTop) / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+ else
+ {
+ fIncrementX = (fRight - fLeft) / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientElliptical::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fDist(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY());
+
+ if(basegfx::fTools::moreOrEqual(fDist, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - sqrt(fDist));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientSquare::geoTexSvxGradientSquare(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use scaled target size
+ fTargetOffsetX += (fOffsetX - 0.5) * fTargetSizeX;
+ fTargetOffsetY += (fOffsetY - 0.5) * fTargetSizeY;
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientSquare::~geoTexSvxGradientSquare()
+ {
+ }
+
+ void geoTexSvxGradientSquare::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ const double fWidth(fRight - fLeft);
+ const double fHalfAspectExpansion(((mfAspect - 1.0) * 0.5) * fWidth);
+ fTop -= fHalfAspectExpansion;
+ fBottom += fHalfAspectExpansion;
+ fIncrementX = fWidth / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+ else
+ {
+ const double fHeight(fBottom - fTop);
+ const double fHalfAspectExpansion((((1.0 / mfAspect) - 1.0) * 0.5) * fHeight);
+ fLeft -= fHalfAspectExpansion;
+ fRight += fHalfAspectExpansion;
+ fIncrementY = fHeight / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientSquare::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fAbsX(fabs(aCoor.getX()));
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(basegfx::fTools::moreOrEqual(fAbsX, 1.0) || basegfx::fTools::moreOrEqual(fAbsY, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientRect::geoTexSvxGradientRect(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use scaled target size
+ fTargetOffsetX += (fOffsetX - 0.5) * fTargetSizeX;
+ fTargetOffsetY += (fOffsetY - 0.5) * fTargetSizeY;
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientRect::~geoTexSvxGradientRect()
+ {
+ }
+
+ void geoTexSvxGradientRect::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ fIncrementY = (fBottom - fTop) / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+ else
+ {
+ fIncrementX = (fRight - fLeft) / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientRect::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fAbsX(fabs(aCoor.getX()));
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(basegfx::fTools::moreOrEqual(fAbsX, 1.0) || basegfx::fTools::moreOrEqual(fAbsY, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxHatch::geoTexSvxHatch(const basegfx::B2DRange& rTargetRange, double fDistance, double fAngle)
+ : mfDistance(0.1),
+ mfAngle(fAngle),
+ mnSteps(10L)
+ {
+ double fTargetSizeX(rTargetRange.getWidth());
+ double fTargetSizeY(rTargetRange.getHeight());
+ double fTargetOffsetX(rTargetRange.getMinX());
+ double fTargetOffsetY(rTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare height for texture
+ const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
+ mnSteps = basegfx::fround(fSteps + 0.5);
+ mfDistance = 1.0 / fSteps;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ }
+
+ geoTexSvxHatch::~geoTexSvxHatch()
+ {
+ }
+
+ bool geoTexSvxHatch::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxHatch* pCompare = dynamic_cast< const geoTexSvxHatch* >(&rGeoTexSvx);
+ return (pCompare
+ && maTextureTransform == pCompare->maTextureTransform
+ && mfDistance == pCompare->mfDistance
+ && mfAngle == pCompare->mfAngle
+ && mnSteps == pCompare->mnSteps);
+ }
+
+ void geoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // create matrix
+ const double fOffset(mfDistance * (double)a);
+ basegfx::B2DHomMatrix aNew;
+ aNew.set(1, 2, fOffset);
+ rMatrices.push_back(maTextureTransform * aNew);
+ }
+ }
+
+ double geoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ return fmod(aCoor.getY(), mfDistance);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxTiled::geoTexSvxTiled(const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
+ : maTopLeft(rTopLeft),
+ maSize(rSize)
+ {
+ if(basegfx::fTools::lessOrEqual(maSize.getX(), 0.0))
+ {
+ maSize.setX(1.0);
+ }
+
+ if(basegfx::fTools::lessOrEqual(maSize.getY(), 0.0))
+ {
+ maSize.setY(1.0);
+ }
+ }
+
+ geoTexSvxTiled::~geoTexSvxTiled()
+ {
+ }
+
+ bool geoTexSvxTiled::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxTiled* pCompare = dynamic_cast< const geoTexSvxTiled* >(&rGeoTexSvx);
+ return (pCompare
+ && maTopLeft == pCompare->maTopLeft
+ && maSize == pCompare->maSize);
+ }
+
+ void geoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ double fStartX(maTopLeft.getX());
+ double fStartY(maTopLeft.getY());
+
+ if(basegfx::fTools::more(fStartX, 0.0))
+ {
+ fStartX -= (floor(fStartX / maSize.getX()) + 1.0) * maSize.getX();
+ }
+
+ if(basegfx::fTools::less(fStartX + maSize.getX(), 0.0))
+ {
+ fStartX += floor(-fStartX / maSize.getX()) * maSize.getX();
+ }
+
+ if(basegfx::fTools::more(fStartY, 0.0))
+ {
+ fStartY -= (floor(fStartY / maSize.getY()) + 1.0) * maSize.getY();
+ }
+
+ if(basegfx::fTools::less(fStartY + maSize.getY(), 0.0))
+ {
+ fStartY += floor(-fStartY / maSize.getY()) * maSize.getY();
+ }
+
+ for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += maSize.getY())
+ {
+ for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += maSize.getX())
+ {
+ basegfx::B2DHomMatrix aNew;
+
+ aNew.set(0, 0, maSize.getX());
+ aNew.set(1, 1, maSize.getY());
+ aNew.set(0, 2, fPosX);
+ aNew.set(1, 2, fPosY);
+
+ rMatrices.push_back(aNew);
+ }
+ }
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/util/makefile.mk b/drawinglayer/util/makefile.mk
index b2c089facf64..307ffd92b078 100644
--- a/drawinglayer/util/makefile.mk
+++ b/drawinglayer/util/makefile.mk
@@ -4,9 +4,9 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.4 $
+# $Revision: 1.5 $
#
-# last change: $Author: aw $ $Date: 2006-06-02 13:58:03 $
+# last change: $Author: aw $ $Date: 2006-08-09 16:58:53 $
#
# The Contents of this file are made available subject to
# the terms of GNU Lesser General Public License Version 2.1.
@@ -50,7 +50,10 @@ LIB1FILES=\
$(SLB)$/primitive3d.lib \
$(SLB)$/geometry.lib \
$(SLB)$/processor.lib \
- $(SLB)$/animation.lib
+ $(SLB)$/processor3d.lib \
+ $(SLB)$/attribute.lib \
+ $(SLB)$/animation.lib \
+ $(SLB)$/texture.lib
SHL1TARGET= drawinglayer$(UPD)$(DLLPOSTFIX)
SHL1IMPLIB= idrawinglayer