summaryrefslogtreecommitdiff
path: root/drawinglayer/source/primitive2d
diff options
context:
space:
mode:
Diffstat (limited to 'drawinglayer/source/primitive2d')
-rw-r--r--drawinglayer/source/primitive2d/alphaprimitive2d.cxx78
-rw-r--r--drawinglayer/source/primitive2d/animatedprimitive2d.cxx293
-rw-r--r--drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx124
-rw-r--r--drawinglayer/source/primitive2d/baseprimitive2d.cxx264
-rw-r--r--drawinglayer/source/primitive2d/bitmapprimitive2d.cxx89
-rw-r--r--drawinglayer/source/primitive2d/borderlineprimitive2d.cxx243
-rw-r--r--drawinglayer/source/primitive2d/chartprimitive2d.cxx90
-rw-r--r--drawinglayer/source/primitive2d/controlprimitive2d.cxx394
-rw-r--r--drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx176
-rw-r--r--drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx142
-rw-r--r--drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx202
-rw-r--r--drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx162
-rw-r--r--drawinglayer/source/primitive2d/graphicprimitive2d.cxx458
-rw-r--r--drawinglayer/source/primitive2d/gridprimitive2d.cxx329
-rw-r--r--drawinglayer/source/primitive2d/groupprimitive2d.cxx87
-rw-r--r--drawinglayer/source/primitive2d/helplineprimitive2d.cxx230
-rw-r--r--drawinglayer/source/primitive2d/hittestprimitive2d.cxx76
-rw-r--r--drawinglayer/source/primitive2d/invertprimitive2d.cxx65
-rw-r--r--drawinglayer/source/primitive2d/makefile.mk90
-rw-r--r--drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx165
-rw-r--r--drawinglayer/source/primitive2d/maskprimitive2d.cxx79
-rw-r--r--drawinglayer/source/primitive2d/mediaprimitive2d.cxx164
-rw-r--r--drawinglayer/source/primitive2d/metafileprimitive2d.cxx89
-rw-r--r--drawinglayer/source/primitive2d/modifiedcolorprimitive2d.cxx79
-rw-r--r--drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx185
-rw-r--r--drawinglayer/source/primitive2d/pointarrayprimitive2d.cxx101
-rw-r--r--drawinglayer/source/primitive2d/polygonprimitive2d.cxx633
-rw-r--r--drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx548
-rw-r--r--drawinglayer/source/primitive2d/primitivetools2d.cxx106
-rw-r--r--drawinglayer/source/primitive2d/sceneprimitive2d.cxx484
-rw-r--r--drawinglayer/source/primitive2d/shadowprimitive2d.cxx114
-rw-r--r--drawinglayer/source/primitive2d/structuretagprimitive2d.cxx67
-rw-r--r--drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx888
-rw-r--r--drawinglayer/source/primitive2d/texteffectprimitive2d.cxx245
-rw-r--r--drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx166
-rw-r--r--drawinglayer/source/primitive2d/textlayoutdevice.cxx430
-rw-r--r--drawinglayer/source/primitive2d/textprimitive2d.cxx374
-rw-r--r--drawinglayer/source/primitive2d/transformprimitive2d.cxx87
-rw-r--r--drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx129
-rw-r--r--drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx130
40 files changed, 8855 insertions, 0 deletions
diff --git a/drawinglayer/source/primitive2d/alphaprimitive2d.cxx b/drawinglayer/source/primitive2d/alphaprimitive2d.cxx
new file mode 100644
index 000000000000..a503c2979c41
--- /dev/null
+++ b/drawinglayer/source/primitive2d/alphaprimitive2d.cxx
@@ -0,0 +1,78 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: alphaprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/alphaprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ AlphaPrimitive2D::AlphaPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ const Primitive2DSequence& rAlpha)
+ : GroupPrimitive2D(rChildren),
+ maAlpha(rAlpha)
+ {
+ }
+
+ bool AlphaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const AlphaPrimitive2D& rCompare = (AlphaPrimitive2D&)rPrimitive;
+
+ return (getAlpha() == rCompare.getAlpha());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(AlphaPrimitive2D, PRIMITIVE2D_ID_ALPHAPRIMITIVE2D)
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/animatedprimitive2d.cxx b/drawinglayer/source/primitive2d/animatedprimitive2d.cxx
new file mode 100644
index 000000000000..13f1f699f1ab
--- /dev/null
+++ b/drawinglayer/source/primitive2d/animatedprimitive2d.cxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: animatedprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
+#include <drawinglayer/animation/animationtiming.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence AnimatedSwitchPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ if(getChildren().hasElements())
+ {
+ const double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime()));
+ const sal_uInt32 nLen(getChildren().getLength());
+ sal_uInt32 nIndex(basegfx::fround(fState * (double)nLen));
+
+ if(nIndex >= nLen)
+ {
+ nIndex = nLen - 1L;
+ }
+
+ const Primitive2DReference xRef(getChildren()[nIndex], uno::UNO_QUERY_THROW);
+ return Primitive2DSequence(&xRef, 1L);
+ }
+
+ return Primitive2DSequence();
+ }
+
+ AnimatedSwitchPrimitive2D::AnimatedSwitchPrimitive2D(
+ const animation::AnimationEntry& rAnimationEntry,
+ const Primitive2DSequence& rChildren,
+ bool bIsTextAnimation)
+ : GroupPrimitive2D(rChildren),
+ mpAnimationEntry(0),
+ mfDecomposeViewTime(0.0),
+ mbIsTextAnimation(bIsTextAnimation)
+ {
+ // clone given animation description
+ mpAnimationEntry = rAnimationEntry.clone();
+ }
+
+ AnimatedSwitchPrimitive2D::~AnimatedSwitchPrimitive2D()
+ {
+ // delete cloned animation description
+ delete mpAnimationEntry;
+ }
+
+ bool AnimatedSwitchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const AnimatedSwitchPrimitive2D& rCompare = static_cast< const AnimatedSwitchPrimitive2D& >(rPrimitive);
+
+ return (getAnimationEntry() == rCompare.getAnimationEntry());
+ }
+
+ return false;
+ }
+
+ Primitive2DSequence AnimatedSwitchPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if(getLocalDecomposition().hasElements() && mfDecomposeViewTime != rViewInformation.getViewTime())
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< AnimatedSwitchPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember time
+ const_cast< AnimatedSwitchPrimitive2D* >(this)->mfDecomposeViewTime = rViewInformation.getViewTime();
+ }
+
+ // use parent implementation
+ return GroupPrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ basegfx::B2DRange AnimatedSwitchPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // to get range from decomposition and not from group content, call implementation from
+ // BasePrimitive2D here
+ return BasePrimitive2D::getB2DRange(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(AnimatedSwitchPrimitive2D, PRIMITIVE2D_ID_ANIMATEDSWITCHPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence AnimatedBlinkPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ if(getChildren().hasElements())
+ {
+ const double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime()));
+
+ if(fState < 0.5)
+ {
+ return getChildren();
+ }
+ }
+
+ return Primitive2DSequence();
+ }
+
+ AnimatedBlinkPrimitive2D::AnimatedBlinkPrimitive2D(
+ const animation::AnimationEntry& rAnimationEntry,
+ const Primitive2DSequence& rChildren,
+ bool bIsTextAnimation)
+ : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, bIsTextAnimation)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(AnimatedBlinkPrimitive2D, PRIMITIVE2D_ID_ANIMATEDBLINKPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// helper class for AnimatedInterpolatePrimitive2D
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ BufferedMatrixDecompose::BufferedMatrixDecompose(const basegfx::B2DHomMatrix& rMatrix)
+ : maB2DHomMatrix(rMatrix),
+ maScale(0.0, 0.0),
+ maTranslate(0.0, 0.0),
+ mfRotate(0.0),
+ mfShearX(0.0),
+ mbDecomposed(false)
+ {
+ }
+
+ void BufferedMatrixDecompose::ensureDecompose() const
+ {
+ if(!mbDecomposed)
+ {
+ BufferedMatrixDecompose* pThis = const_cast< BufferedMatrixDecompose* >(this);
+ maB2DHomMatrix.decompose(pThis->maScale, pThis->maTranslate, pThis->mfRotate, pThis->mfShearX);
+ pThis->mbDecomposed = true;
+ }
+ }
+ } // end of anonymous namespace
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence AnimatedInterpolatePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ const sal_uInt32 nSize(maMatrixStack.size());
+
+ if(nSize)
+ {
+ double fState(getAnimationEntry().getStateAtTime(rViewInformation.getViewTime()));
+
+ if(fState < 0.0)
+ {
+ fState = 0.0;
+ }
+ else if(fState > 1.0)
+ {
+ fState = 1.0;
+ }
+
+ const double fIndex(fState * (double)(nSize - 1L));
+ const sal_uInt32 nIndA(sal_uInt32(floor(fIndex)));
+ const double fOffset(fIndex - (double)nIndA);
+ basegfx::B2DHomMatrix aTargetTransform;
+
+ if(basegfx::fTools::equalZero(fOffset))
+ {
+ // use matrix from nIndA directly
+ aTargetTransform = maMatrixStack[nIndA].getB2DHomMatrix();
+ }
+ else
+ {
+ // interpolate. Get involved matrices and ensure they are decomposed
+ const sal_uInt32 nIndB((nIndA + 1L) % nSize);
+ std::vector< BufferedMatrixDecompose >::const_iterator aMatA(maMatrixStack.begin() + nIndA);
+ std::vector< BufferedMatrixDecompose >::const_iterator aMatB(maMatrixStack.begin() + nIndB);
+
+ aMatA->ensureDecompose();
+ aMatB->ensureDecompose();
+
+ // interpolate for fOffset [0.0 .. 1.0[
+ const basegfx::B2DVector aScale(basegfx::interpolate(aMatA->getScale(), aMatB->getScale(), fOffset));
+ const basegfx::B2DVector aTranslate(basegfx::interpolate(aMatA->getTranslate(), aMatB->getTranslate(), fOffset));
+ const double fRotate(((aMatB->getRotate() - aMatA->getRotate()) * fOffset) + aMatA->getRotate());
+ const double fShearX(((aMatB->getShearX() - aMatA->getShearX()) * fOffset) + aMatA->getShearX());
+
+ // build matrix for state
+ aTargetTransform.scale(aScale.getX(), aScale.getY());
+ aTargetTransform.shearX(fShearX);
+ aTargetTransform.rotate(fRotate);
+ aTargetTransform.translate(aTranslate.getX(), aTranslate.getY());
+ }
+
+ // create new transform primitive reference, return new sequence
+ const Primitive2DReference xRef(new TransformPrimitive2D(aTargetTransform, getChildren()));
+ return Primitive2DSequence(&xRef, 1L);
+ }
+ else
+ {
+ return getChildren();
+ }
+ }
+
+ AnimatedInterpolatePrimitive2D::AnimatedInterpolatePrimitive2D(
+ const std::vector< basegfx::B2DHomMatrix >& rmMatrixStack,
+ const animation::AnimationEntry& rAnimationEntry,
+ const Primitive2DSequence& rChildren,
+ bool bIsTextAnimation)
+ : AnimatedSwitchPrimitive2D(rAnimationEntry, rChildren, bIsTextAnimation),
+ maMatrixStack()
+ {
+ // copy matrices
+ const sal_uInt32 nCount(rmMatrixStack.size());
+
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ maMatrixStack.push_back(BufferedMatrixDecompose(rmMatrixStack[a]));
+ }
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(AnimatedInterpolatePrimitive2D, PRIMITIVE2D_ID_ANIMATEDINTERPOLATEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
new file mode 100644
index 000000000000..cff797451954
--- /dev/null
+++ b/drawinglayer/source/primitive2d/backgroundcolorprimitive2d.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: backgroundcolorprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence BackgroundColorPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ if(!rViewInformation.getViewport().isEmpty())
+ {
+ const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(rViewInformation.getViewport()));
+ const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), getBColor()));
+ return Primitive2DSequence(&xRef, 1L);
+ }
+ else
+ {
+ return Primitive2DSequence();
+ }
+ }
+
+ BackgroundColorPrimitive2D::BackgroundColorPrimitive2D(
+ const basegfx::BColor& rBColor)
+ : BasePrimitive2D(),
+ maBColor(rBColor),
+ maLastViewport()
+ {
+ }
+
+ bool BackgroundColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const BackgroundColorPrimitive2D& rCompare = (BackgroundColorPrimitive2D&)rPrimitive;
+
+ return (getBColor() == rCompare.getBColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange BackgroundColorPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // always as big as the view
+ return rViewInformation.getViewport();
+ }
+
+ Primitive2DSequence BackgroundColorPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if(getLocalDecomposition().hasElements() && (maLastViewport != rViewInformation.getViewport()))
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< BackgroundColorPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember ViewRange
+ const_cast< BackgroundColorPrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport();
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(BackgroundColorPrimitive2D, PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/baseprimitive2d.cxx b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
new file mode 100644
index 000000000000..63941512bfb0
--- /dev/null
+++ b/drawinglayer/source/primitive2d/baseprimitive2d.cxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: baseprimitive2d.cxx,v $
+ *
+ * $Revision: 1.6 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence BasePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ return Primitive2DSequence();
+ }
+
+ BasePrimitive2D::BasePrimitive2D()
+ : BasePrimitive2DImplBase(m_aMutex),
+ maLocalDecomposition()
+ {
+ }
+
+ bool BasePrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
+ {
+ return (getPrimitiveID() == rPrimitive.getPrimitiveID());
+ }
+
+ basegfx::B2DRange BasePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ return getB2DRangeFromPrimitive2DSequence(get2DDecomposition(rViewInformation), rViewInformation);
+ }
+
+ Primitive2DSequence BasePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ const Primitive2DSequence aNewSequence(createLocalDecomposition(rViewInformation));
+ const_cast< BasePrimitive2D* >(this)->setLocalDecomposition(aNewSequence);
+ }
+
+ return getLocalDecomposition();
+ }
+
+ Primitive2DSequence SAL_CALL BasePrimitive2D::getDecomposition( const uno::Sequence< beans::PropertyValue >& rViewParameters ) throw ( uno::RuntimeException )
+ {
+ const geometry::ViewInformation2D aViewInformation(rViewParameters);
+ return get2DDecomposition(aViewInformation);
+ }
+
+ com::sun::star::geometry::RealRectangle2D SAL_CALL BasePrimitive2D::getRange( const uno::Sequence< beans::PropertyValue >& rViewParameters ) throw ( uno::RuntimeException )
+ {
+ const geometry::ViewInformation2D aViewInformation(rViewParameters);
+ return basegfx::unotools::rectangle2DFromB2DRectangle(getB2DRange(aViewInformation));
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// tooling
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ // get B2DRange from a given Primitive2DReference
+ basegfx::B2DRange getB2DRangeFromPrimitive2DReference(const Primitive2DReference& rCandidate, const geometry::ViewInformation2D& aViewInformation)
+ {
+ basegfx::B2DRange aRetval;
+
+ if(rCandidate.is())
+ {
+ // try to get C++ implementation base
+ const BasePrimitive2D* pCandidate(dynamic_cast< BasePrimitive2D* >(rCandidate.get()));
+
+ if(pCandidate)
+ {
+ // use it if possible
+ aRetval.expand(pCandidate->getB2DRange(aViewInformation));
+ }
+ else
+ {
+ // use UNO API call instead
+ const uno::Sequence< beans::PropertyValue >& rViewParameters(aViewInformation.getViewInformationSequence());
+ aRetval.expand(basegfx::unotools::b2DRectangleFromRealRectangle2D(rCandidate->getRange(rViewParameters)));
+ }
+ }
+
+ return aRetval;
+ }
+
+ // get B2DRange from a given Primitive2DSequence
+ basegfx::B2DRange getB2DRangeFromPrimitive2DSequence(const Primitive2DSequence& rCandidate, const geometry::ViewInformation2D& aViewInformation)
+ {
+ basegfx::B2DRange aRetval;
+
+ if(rCandidate.hasElements())
+ {
+ const sal_Int32 nCount(rCandidate.getLength());
+
+ for(sal_Int32 a(0L); a < nCount; a++)
+ {
+ aRetval.expand(getB2DRangeFromPrimitive2DReference(rCandidate[a], aViewInformation));
+ }
+ }
+
+ return aRetval;
+ }
+
+ bool arePrimitive2DReferencesEqual(const Primitive2DReference& rxA, const Primitive2DReference& rxB)
+ {
+ const sal_Bool bAIs(rxA.is());
+
+ if(bAIs != rxB.is())
+ {
+ return false;
+ }
+
+ if(!bAIs)
+ {
+ return true;
+ }
+
+ const BasePrimitive2D* pA(dynamic_cast< const BasePrimitive2D* >(rxA.get()));
+ const BasePrimitive2D* pB(dynamic_cast< const BasePrimitive2D* >(rxB.get()));
+ const bool bAEqualZero(pA == 0L);
+
+ if(bAEqualZero != (pB == 0L))
+ {
+ return false;
+ }
+
+ if(bAEqualZero)
+ {
+ return false;
+ }
+
+ return (pA->operator==(*pB));
+ }
+
+ bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const Primitive2DSequence& rB)
+ {
+ const sal_Bool bAHasElements(rA.hasElements());
+
+ if(bAHasElements != rB.hasElements())
+ {
+ return false;
+ }
+
+ if(!bAHasElements)
+ {
+ return true;
+ }
+
+ const sal_Int32 nCount(rA.getLength());
+
+ if(nCount != rB.getLength())
+ {
+ return false;
+ }
+
+ for(sal_Int32 a(0L); a < nCount; a++)
+ {
+ if(!arePrimitive2DReferencesEqual(rA[a], rB[a]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // concatenate sequence
+ void appendPrimitive2DSequenceToPrimitive2DSequence(Primitive2DSequence& rDest, const Primitive2DSequence& rSource)
+ {
+ if(rSource.hasElements())
+ {
+ if(rDest.hasElements())
+ {
+ const sal_Int32 nSourceCount(rSource.getLength());
+ const sal_Int32 nDestCount(rDest.getLength());
+ const sal_Int32 nTargetCount(nSourceCount + nDestCount);
+ sal_Int32 nInsertPos(nDestCount);
+
+ rDest.realloc(nTargetCount);
+
+ for(sal_Int32 a(0L); a < nSourceCount; a++)
+ {
+ if(rSource[a].is())
+ {
+ rDest[nInsertPos++] = rSource[a];
+ }
+ }
+
+ if(nInsertPos != nTargetCount)
+ {
+ rDest.realloc(nInsertPos);
+ }
+ }
+ else
+ {
+ rDest = rSource;
+ }
+ }
+ }
+
+ // concatenate single Primitive2D
+ void appendPrimitive2DReferenceToPrimitive2DSequence(Primitive2DSequence& rDest, const Primitive2DReference& rSource)
+ {
+ if(rSource.is())
+ {
+ const sal_Int32 nDestCount(rDest.getLength());
+ rDest.realloc(nDestCount + 1L);
+ rDest[nDestCount] = rSource;
+ }
+ }
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx
new file mode 100644
index 000000000000..5900900bcf06
--- /dev/null
+++ b/drawinglayer/source/primitive2d/bitmapprimitive2d.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bitmapprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ BitmapPrimitive2D::BitmapPrimitive2D(
+ const BitmapEx& rBitmapEx,
+ const basegfx::B2DHomMatrix& rTransform)
+ : BasePrimitive2D(),
+ maBitmapEx(rBitmapEx),
+ maTransform(rTransform)
+ {
+ }
+
+ bool BitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const BitmapPrimitive2D& rCompare = (BitmapPrimitive2D&)rPrimitive;
+
+ return (maBitmapEx == rCompare.maBitmapEx
+ && maTransform == rCompare.maTransform);
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange BitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(maTransform);
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(BitmapPrimitive2D, PRIMITIVE2D_ID_BITMAPPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
new file mode 100644
index 000000000000..ba73f920cb08
--- /dev/null
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: borderlineprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <numeric>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence BorderLinePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence xRetval;
+
+ if(!getStart().equal(getEnd()) && (getCreateInside() || getCreateOutside()))
+ {
+ if(isInsideUsed())
+ {
+ // get data and vectors
+ const double fWidth(getWidth());
+ basegfx::B2DVector aVector(getEnd() - getStart());
+ aVector.normalize();
+ const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
+
+ if(isOutsideUsed())
+ {
+ // both used, double line definition. Create left and right offset
+ xRetval.realloc(getCreateInside() && getCreateOutside() ? 2 : 1);
+ sal_uInt32 nInsert(0);
+
+ if(getCreateInside())
+ {
+ // create geometry for left
+ const basegfx::B2DVector aLeftOff(aPerpendicular * (0.5 * (getCorrectedLeftWidth() - fWidth)));
+ const basegfx::B2DPoint aTmpStart(getStart() + aLeftOff - (getExtendInnerStart() * aVector));
+ const basegfx::B2DPoint aTmpEnd(getEnd() + aLeftOff + (getExtendInnerEnd() * aVector));
+ basegfx::B2DPolygon aLeft;
+
+ if(leftIsHairline())
+ {
+ // create hairline primitive
+ aLeft.append(aTmpStart);
+ aLeft.append(aTmpEnd);
+
+ xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D(
+ aLeft,
+ getRGBColor()));
+ }
+ else
+ {
+ // create filled polygon primitive. Already tried to create thick lines
+ // with the correct LineWidth, but this leads to problems when no AA
+ // is available and fat line special case reductions between 0.5 < x < 2.5 line widths
+ // are executed due to the FilledPolygon-do-not-paint-their-bottom-and-right-lines.
+ const basegfx::B2DVector aLineWidthOffset((getCorrectedLeftWidth() * 0.5) * aPerpendicular);
+
+ aLeft.append(aTmpStart + aLineWidthOffset);
+ aLeft.append(aTmpEnd + aLineWidthOffset);
+ aLeft.append(aTmpEnd - aLineWidthOffset);
+ aLeft.append(aTmpStart - aLineWidthOffset);
+ aLeft.setClosed(true);
+
+ xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aLeft), getRGBColor()));
+ }
+ }
+
+ if(getCreateOutside())
+ {
+ // create geometry for right
+ const basegfx::B2DVector aRightOff(aPerpendicular * (0.5 * (fWidth - getCorrectedRightWidth())));
+ const basegfx::B2DPoint aTmpStart(getStart() + aRightOff - (getExtendOuterStart() * aVector));
+ const basegfx::B2DPoint aTmpEnd(getEnd() + aRightOff + (getExtendOuterEnd() * aVector));
+ basegfx::B2DPolygon aRight;
+
+ if(rightIsHairline())
+ {
+ // create hairline primitive
+ aRight.append(aTmpStart);
+ aRight.append(aTmpEnd);
+
+ xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D(
+ aRight,
+ getRGBColor()));
+ }
+ else
+ {
+ // create filled polygon primitive
+ const basegfx::B2DVector aLineWidthOffset((getCorrectedRightWidth() * 0.5) * aPerpendicular);
+
+ aRight.append(aTmpStart + aLineWidthOffset);
+ aRight.append(aTmpEnd + aLineWidthOffset);
+ aRight.append(aTmpEnd - aLineWidthOffset);
+ aRight.append(aTmpStart - aLineWidthOffset);
+ aRight.setClosed(true);
+
+ xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aRight), getRGBColor()));
+ }
+ }
+ }
+ else
+ {
+ // single line, create geometry
+ basegfx::B2DPolygon aPolygon;
+ const double fMaxExtStart(::std::max(getExtendInnerStart(), getExtendOuterStart()));
+ const double fMaxExtEnd(::std::max(getExtendInnerEnd(), getExtendOuterEnd()));
+ const basegfx::B2DPoint aTmpStart(getStart() - (fMaxExtStart * aVector));
+ const basegfx::B2DPoint aTmpEnd(getEnd() + (fMaxExtEnd * aVector));
+ xRetval.realloc(1);
+
+ if(leftIsHairline())
+ {
+ // create hairline primitive
+ aPolygon.append(aTmpStart);
+ aPolygon.append(aTmpEnd);
+
+ xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D(
+ aPolygon,
+ getRGBColor()));
+ }
+ else
+ {
+ // create filled polygon primitive
+ const basegfx::B2DVector aLineWidthOffset((getCorrectedLeftWidth() * 0.5) * aPerpendicular);
+
+ aPolygon.append(aTmpStart + aLineWidthOffset);
+ aPolygon.append(aTmpEnd + aLineWidthOffset);
+ aPolygon.append(aTmpEnd - aLineWidthOffset);
+ aPolygon.append(aTmpStart - aLineWidthOffset);
+ aPolygon.setClosed(true);
+
+ xRetval[0] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon), getRGBColor()));
+ }
+ }
+ }
+ }
+
+ return xRetval;
+ }
+
+ BorderLinePrimitive2D::BorderLinePrimitive2D(
+ const basegfx::B2DPoint& rStart,
+ const basegfx::B2DPoint& rEnd,
+ double fLeftWidth,
+ double fDistance,
+ double fRightWidth,
+ double fExtendInnerStart,
+ double fExtendInnerEnd,
+ double fExtendOuterStart,
+ double fExtendOuterEnd,
+ bool bCreateInside,
+ bool bCreateOutside,
+ const basegfx::BColor& rRGBColor)
+ : BasePrimitive2D(),
+ maStart(rStart),
+ maEnd(rEnd),
+ mfLeftWidth(fLeftWidth),
+ mfDistance(fDistance),
+ mfRightWidth(fRightWidth),
+ mfExtendInnerStart(fExtendInnerStart),
+ mfExtendInnerEnd(fExtendInnerEnd),
+ mfExtendOuterStart(fExtendOuterStart),
+ mfExtendOuterEnd(fExtendOuterEnd),
+ maRGBColor(rRGBColor),
+ mbCreateInside(bCreateInside),
+ mbCreateOutside(bCreateOutside)
+ {
+ }
+
+ bool BorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const BorderLinePrimitive2D& rCompare = (BorderLinePrimitive2D&)rPrimitive;
+
+ return (getStart() == rCompare.getStart()
+ && getEnd() == rCompare.getEnd()
+ && getLeftWidth() == rCompare.getLeftWidth()
+ && getDistance() == rCompare.getDistance()
+ && getRightWidth() == rCompare.getRightWidth()
+ && getExtendInnerStart() == rCompare.getExtendInnerStart()
+ && getExtendInnerEnd() == rCompare.getExtendInnerEnd()
+ && getExtendOuterStart() == rCompare.getExtendOuterStart()
+ && getExtendOuterEnd() == rCompare.getExtendOuterEnd()
+ && getCreateInside() == rCompare.getCreateInside()
+ && getCreateOutside() == rCompare.getCreateOutside()
+ && getRGBColor() == rCompare.getRGBColor());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/chartprimitive2d.cxx b/drawinglayer/source/primitive2d/chartprimitive2d.cxx
new file mode 100644
index 000000000000..3df6464f8aeb
--- /dev/null
+++ b/drawinglayer/source/primitive2d/chartprimitive2d.cxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: chartprimitive2d.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/chartprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ ChartPrimitive2D::ChartPrimitive2D(
+ const uno::Reference< frame::XModel >& rxChartModel,
+ const basegfx::B2DHomMatrix& rTransformation,
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren),
+ mxChartModel(rxChartModel),
+ maTransformation(rTransformation)
+ {
+ }
+
+ bool ChartPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const ChartPrimitive2D& rCompare = static_cast< const ChartPrimitive2D& >(rPrimitive);
+
+ return (getChartModel() == rCompare.getChartModel()
+ && getTransformation() == rCompare.getTransformation());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(ChartPrimitive2D, PRIMITIVE2D_ID_CHARTPRIMITIVE2D)
+
+ basegfx::B2DRange ChartPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(getTransformation());
+ return aRetval;
+ }
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/controlprimitive2d.cxx b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
new file mode 100644
index 000000000000..6241eeb2fa73
--- /dev/null
+++ b/drawinglayer/source/primitive2d/controlprimitive2d.cxx
@@ -0,0 +1,394 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: controlprimitive2d.cxx,v $
+ *
+ * $Revision: 1.6 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/controlprimitive2d.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/awt/XWindow2.hpp>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <vcl/bitmapex.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <tools/diagnose_ex.h>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <vcl/window.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ void ControlPrimitive2D::createXControl()
+ {
+ if(!mxXControl.is() && getControlModel().is())
+ {
+ uno::Reference< beans::XPropertySet > xSet(getControlModel(), uno::UNO_QUERY);
+
+ if(xSet.is())
+ {
+ uno::Any aValue(xSet->getPropertyValue(rtl::OUString::createFromAscii("DefaultControl")));
+ rtl::OUString aUnoControlTypeName;
+
+ if(aValue >>= aUnoControlTypeName)
+ {
+ if(aUnoControlTypeName.getLength())
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( comphelper::getProcessServiceFactory() );
+
+ if(xFactory.is())
+ {
+ uno::Reference< awt::XControl > xXControl(xFactory->createInstance(aUnoControlTypeName), uno::UNO_QUERY);
+
+ if(xXControl.is())
+ {
+ xXControl->setModel(getControlModel());
+
+ // remember XControl
+ mxXControl = xXControl;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Primitive2DReference ControlPrimitive2D::createBitmapDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DReference xRetval;
+ const uno::Reference< awt::XControl >& rXControl(getXControl());
+
+ if(rXControl.is())
+ {
+ uno::Reference< awt::XWindow > xControlWindow(rXControl, uno::UNO_QUERY);
+
+ if(xControlWindow.is())
+ {
+ // get decomposition to get size
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // get absolute discrete size (no mirror or rotate here)
+ aScale = basegfx::absolute(aScale);
+ basegfx::B2DVector aDiscreteSize(rViewInformation.getObjectToViewTransformation() * aScale);
+
+ // limit to a maximum square size, e.g. 300x150 pixels (45000)
+ const SvtOptionsDrawinglayer aDrawinglayerOpt;
+ const double fDiscreteMax(aDrawinglayerOpt.GetQuadraticFormControlRenderLimit());
+ const double fDiscreteQuadratic(aDiscreteSize.getX() * aDiscreteSize.getY());
+ const bool bScaleUsed(fDiscreteQuadratic > fDiscreteMax);
+ double fFactor(1.0);
+
+ if(bScaleUsed)
+ {
+ // get factor and adapt to scaled size
+ fFactor = sqrt(fDiscreteMax / fDiscreteQuadratic);
+ aDiscreteSize *= fFactor;
+ }
+
+ // go to integer
+ const sal_Int32 nSizeX(basegfx::fround(aDiscreteSize.getX()));
+ const sal_Int32 nSizeY(basegfx::fround(aDiscreteSize.getY()));
+
+ if(nSizeX > 0 && nSizeY > 0)
+ {
+ // prepare VirtualDevice
+ VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
+ const Size aSizePixel(nSizeX, nSizeY);
+ aVirtualDevice.SetOutputSizePixel(aSizePixel);
+
+ // set size at control
+ xControlWindow->setPosSize(0, 0, nSizeX, nSizeY, awt::PosSize::POSSIZE);
+
+ // get graphics and view
+ uno::Reference< awt::XGraphics > xGraphics(aVirtualDevice.CreateUnoGraphics());
+ uno::Reference< awt::XView > xControlView(rXControl, uno::UNO_QUERY);
+
+ if(xGraphics.is() && xControlView.is())
+ {
+ // link graphics and view
+ xControlView->setGraphics(xGraphics);
+
+ { // #i93162# For painting the control setting a Zoom (using setZoom() at the xControlView)
+ // is needed to define the font size. Normally this is done in
+ // ViewObjectContactOfUnoControl::createPrimitive2DSequence by using positionControlForPaint().
+ // For some reason the difference between MAP_TWIPS and MAP_100TH_MM still plays
+ // a role there so that for Draw/Impress/Calc (the MAP_100TH_MM users) i need to set a zoom
+ // here, too. The factor includes the needed scale, but is calculated by pure comparisons. It
+ // is somehow related to the twips/100thmm relationship.
+ bool bUserIs100thmm(false);
+ const uno::Reference< awt::XControl > xControl(xControlView, uno::UNO_QUERY);
+
+ if(xControl.is())
+ {
+ uno::Reference< awt::XWindowPeer > xWindowPeer(xControl->getPeer());
+
+ if(xWindowPeer.is())
+ {
+ VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation(xWindowPeer);
+
+ if(pVCLXWindow)
+ {
+ Window* pWindow = pVCLXWindow->GetWindow();
+
+ if(pWindow)
+ {
+ pWindow = pWindow->GetParent();
+
+ if(pWindow)
+ {
+ if(MAP_100TH_MM == pWindow->GetMapMode().GetMapUnit())
+ {
+ bUserIs100thmm = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(bUserIs100thmm)
+ {
+ // calc screen zoom for text display. fFactor is already added indirectly in aDiscreteSize
+ basegfx::B2DVector aScreenZoom(
+ basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : aDiscreteSize.getX() / aScale.getX(),
+ basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : aDiscreteSize.getY() / aScale.getY());
+ static double fZoomScale(28.0); // do not ask for this constant factor, but it gets the zoom right
+ aScreenZoom *= fZoomScale;
+
+ // set zoom at control view for text scaling
+ xControlView->setZoom((float)aScreenZoom.getX(), (float)aScreenZoom.getY());
+ }
+ }
+
+ try
+ {
+ // try to paint it to VirtualDevice
+ xControlView->draw(0, 0);
+
+ // get bitmap
+ const Bitmap aContent(aVirtualDevice.GetBitmap(Point(), aSizePixel));
+
+ // to avoid scaling, use the Bitmap pixel size as primitive size
+ const Size aBitmapSize(aContent.GetSizePixel());
+ basegfx::B2DVector aBitmapSizeLogic(
+ rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(aBitmapSize.getWidth() - 1, aBitmapSize.getHeight() - 1));
+
+ if(bScaleUsed)
+ {
+ // if scaled adapt to scaled size
+ aBitmapSizeLogic /= fFactor;
+ }
+
+ // short form for scale and translate transformation
+ basegfx::B2DHomMatrix aBitmapTransform;
+
+ aBitmapTransform.set(0L, 0L, aBitmapSizeLogic.getX());
+ aBitmapTransform.set(1L, 1L, aBitmapSizeLogic.getY());
+ aBitmapTransform.set(0L, 2L, aTranslate.getX());
+ aBitmapTransform.set(1L, 2L, aTranslate.getY());
+
+ // create primitive
+ xRetval = new BitmapPrimitive2D(BitmapEx(aContent), aBitmapTransform);
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+ }
+ }
+
+ return xRetval;
+ }
+
+ Primitive2DReference ControlPrimitive2D::createPlaceholderDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // create a gray placeholder hairline polygon in object size
+ basegfx::B2DRange aObjectRange(0.0, 0.0, 1.0, 1.0);
+ aObjectRange.transform(getTransform());
+ const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aObjectRange));
+ const basegfx::BColor aGrayTone(0xc0 / 255.0, 0xc0 / 255.0, 0xc0 / 255.0);
+
+ // The replacement object may also get a text like 'empty group' here later
+ Primitive2DReference xRetval(new PolygonHairlinePrimitive2D(aOutline, aGrayTone));
+
+ return xRetval;
+ }
+
+ Primitive2DSequence ControlPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // try to create a bitmap decomposition. If that fails for some reason,
+ // at least create a replacement decomposition.
+ Primitive2DReference xReference(createBitmapDecomposition(rViewInformation));
+
+ if(!xReference.is())
+ {
+ xReference = createPlaceholderDecomposition(rViewInformation);
+ }
+
+ return Primitive2DSequence(&xReference, 1L);
+ }
+
+ ControlPrimitive2D::ControlPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const uno::Reference< awt::XControlModel >& rxControlModel)
+ : BasePrimitive2D(),
+ maTransform(rTransform),
+ mxControlModel(rxControlModel),
+ mxXControl(),
+ maLastViewScaling()
+ {
+ }
+
+ ControlPrimitive2D::ControlPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const uno::Reference< awt::XControlModel >& rxControlModel,
+ const uno::Reference< awt::XControl >& rxXControl)
+ : BasePrimitive2D(),
+ maTransform(rTransform),
+ mxControlModel(rxControlModel),
+ mxXControl(rxXControl),
+ maLastViewScaling()
+ {
+ }
+
+ const uno::Reference< awt::XControl >& ControlPrimitive2D::getXControl() const
+ {
+ if(!mxXControl.is())
+ {
+ const_cast< ControlPrimitive2D* >(this)->createXControl();
+ }
+
+ return mxXControl;
+ }
+
+ bool ControlPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ // use base class compare operator
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const ControlPrimitive2D& rCompare = (ControlPrimitive2D&)rPrimitive;
+
+ if(getTransform() == rCompare.getTransform())
+ {
+ // check if ControlModel references both are/are not
+ bool bRetval(getControlModel().is() == rCompare.getControlModel().is());
+
+ if(bRetval && getControlModel().is())
+ {
+ // both exist, check for equality
+ bRetval = (getControlModel() == rCompare.getControlModel());
+ }
+
+ if(bRetval)
+ {
+ // check if XControl references both are/are not
+ bRetval = (getXControl().is() == rCompare.getXControl().is());
+ }
+
+ if(bRetval && getXControl().is())
+ {
+ // both exist, check for equality
+ bRetval = (getXControl() == rCompare.getXControl());
+ }
+
+ return bRetval;
+ }
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange ControlPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // simply derivate from unit range
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(getTransform());
+ return aRetval;
+ }
+
+ Primitive2DSequence ControlPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // this primitive is view-dependent related to the scaling. If scaling has changed,
+ // destroy existing decomposition. To detect change, use size of unit size in view coordinates
+ ::osl::MutexGuard aGuard( m_aMutex );
+ const basegfx::B2DVector aNewScaling(rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(1.0, 1.0));
+
+ if(getLocalDecomposition().hasElements())
+ {
+ if(!maLastViewScaling.equal(aNewScaling))
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< ControlPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember ViewTransformation
+ const_cast< ControlPrimitive2D* >(this)->maLastViewScaling = aNewScaling;
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(ControlPrimitive2D, PRIMITIVE2D_ID_CONTROLPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
new file mode 100644
index 000000000000..5805c02a61ed
--- /dev/null
+++ b/drawinglayer/source/primitive2d/embedded3dprimitive2d.cxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: embedded3dprimitive2d.cxx,v $
+ *
+ * $Revision: 1.8 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/geometry/viewinformation3d.hxx>
+#include <drawinglayer/processor3d/shadow3dextractor.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ bool Embedded3DPrimitive2D::impGetShadow3D(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ osl::MutexGuard aGuard( m_aMutex );
+
+ // create on demand
+ if(!mbShadow3DChecked && getChildren3D().hasElements())
+ {
+ // create shadow extraction processor
+ processor3d::Shadow3DExtractingProcessor aShadowProcessor(
+ getViewInformation3D(),
+ getObjectTransformation(),
+ getLightNormal(),
+ getShadowSlant(),
+ getScene3DRange());
+
+ // process local primitives
+ aShadowProcessor.process(getChildren3D());
+
+ // fetch result and set checked flag
+ const_cast< Embedded3DPrimitive2D* >(this)->maShadowPrimitives = aShadowProcessor.getPrimitive2DSequence();
+ const_cast< Embedded3DPrimitive2D* >(this)->mbShadow3DChecked = true;
+ }
+
+ // return if there are shadow primitives
+ return maShadowPrimitives.hasElements();
+ }
+
+ Primitive2DSequence Embedded3DPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // use info to create a yellow 2d rectangle, similar to empty 3d scenes and/or groups
+ const basegfx::B2DRange aLocal2DRange(getB2DRange(rViewInformation));
+ const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aLocal2DRange));
+ const basegfx::BColor aYellow(1.0, 1.0, 0.0);
+ const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(aOutline, aYellow));
+
+ return Primitive2DSequence(&xRef, 1L);
+ }
+
+ Embedded3DPrimitive2D::Embedded3DPrimitive2D(
+ const primitive3d::Primitive3DSequence& rxChildren3D,
+ const basegfx::B2DHomMatrix& rObjectTransformation,
+ const geometry::ViewInformation3D& rViewInformation3D,
+ const basegfx::B3DVector& rLightNormal,
+ double fShadowSlant,
+ const basegfx::B3DRange& rScene3DRange)
+ : BasePrimitive2D(),
+ mxChildren3D(rxChildren3D),
+ maObjectTransformation(rObjectTransformation),
+ maViewInformation3D(rViewInformation3D),
+ maLightNormal(rLightNormal),
+ mfShadowSlant(fShadowSlant),
+ maScene3DRange(rScene3DRange),
+ maShadowPrimitives(),
+ maB2DRange(),
+ mbShadow3DChecked(false)
+ {
+ maLightNormal.normalize();
+ }
+
+ bool Embedded3DPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const Embedded3DPrimitive2D& rCompare = static_cast< const Embedded3DPrimitive2D& >(rPrimitive);
+
+ return (primitive3d::arePrimitive3DSequencesEqual(getChildren3D(), rCompare.getChildren3D())
+ && getObjectTransformation() == rCompare.getObjectTransformation()
+ && getViewInformation3D() == rCompare.getViewInformation3D()
+ && getLightNormal() == rCompare.getLightNormal()
+ && getShadowSlant() == rCompare.getShadowSlant()
+ && getScene3DRange() == rCompare.getScene3DRange());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange Embedded3DPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ if(maB2DRange.isEmpty())
+ {
+ // use the 3d transformation stack to create a projection of the 3D range
+ basegfx::B3DRange a3DRange(primitive3d::getB3DRangeFromPrimitive3DSequence(getChildren3D(), getViewInformation3D()));
+ a3DRange.transform(getViewInformation3D().getObjectToView());
+
+ // create 2d range from projected 3d and transform with scene's object transformation
+ basegfx::B2DRange aNewRange;
+ aNewRange.expand(basegfx::B2DPoint(a3DRange.getMinX(), a3DRange.getMinY()));
+ aNewRange.expand(basegfx::B2DPoint(a3DRange.getMaxX(), a3DRange.getMaxY()));
+ aNewRange.transform(getObjectTransformation());
+
+ // cehck for 3D shadows and their 2D projections. If those exist, they need to be
+ // taken into account
+ if(impGetShadow3D(rViewInformation))
+ {
+ const basegfx::B2DRange aShadow2DRange(getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
+
+ if(!aShadow2DRange.isEmpty())
+ {
+ aNewRange.expand(aShadow2DRange);
+ }
+ }
+
+ // assign to buffered value
+ const_cast< Embedded3DPrimitive2D* >(this)->maB2DRange = aNewRange;
+ }
+
+ return maB2DRange;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(Embedded3DPrimitive2D, PRIMITIVE2D_ID_EMBEDDED3DPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx b/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx
new file mode 100644
index 000000000000..125c2cb42193
--- /dev/null
+++ b/drawinglayer/source/primitive2d/fillbitmapprimitive2d.cxx
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fillbitmapprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/texture/texture.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence FillBitmapPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ const Size aTileSizePixel(getFillBitmap().getBitmap().GetSizePixel());
+ Primitive2DSequence aRetval;
+
+ // is there a tile with some size at all?
+ if(aTileSizePixel.getWidth() && aTileSizePixel.getHeight())
+ {
+ if(getFillBitmap().getTiling())
+ {
+ // get object range and create tiling matrices
+ ::std::vector< basegfx::B2DHomMatrix > aMatrices;
+ texture::GeoTexSvxTiled aTiling(getFillBitmap().getTopLeft(), getFillBitmap().getSize());
+ aTiling.appendTransformations(aMatrices);
+
+ // resize result
+ aRetval.realloc(aMatrices.size());
+
+ // create one primitive for each matrix
+ for(sal_uInt32 a(0L); a < aMatrices.size(); a++)
+ {
+ basegfx::B2DHomMatrix aNewMatrix = aMatrices[a];
+ aNewMatrix *= getTransformation();
+
+ // create bitmap primitive and add to result
+ const Primitive2DReference xRef(new BitmapPrimitive2D(BitmapEx(getFillBitmap().getBitmap()), aNewMatrix));
+ aRetval[a] = xRef;
+ }
+ }
+ else
+ {
+ // create new object transform
+ basegfx::B2DHomMatrix aObjectTransform;
+ aObjectTransform.set(0L, 0L, getFillBitmap().getSize().getX());
+ aObjectTransform.set(1L, 1L, getFillBitmap().getSize().getY());
+ aObjectTransform.set(0L, 2L, getFillBitmap().getTopLeft().getX());
+ aObjectTransform.set(1L, 2L, getFillBitmap().getTopLeft().getY());
+ aObjectTransform *= getTransformation();
+
+ // create bitmap primitive and add exclusive to decomposition (hand over ownership)
+ const Primitive2DReference xRef(new BitmapPrimitive2D(BitmapEx(getFillBitmap().getBitmap()), aObjectTransform));
+ aRetval = Primitive2DSequence(&xRef, 1L);
+ }
+ }
+
+ return aRetval;
+ }
+
+ FillBitmapPrimitive2D::FillBitmapPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransformation,
+ const attribute::FillBitmapAttribute& rFillBitmap)
+ : BasePrimitive2D(),
+ maTransformation(rTransformation),
+ maFillBitmap(rFillBitmap)
+ {
+ }
+
+ bool FillBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const FillBitmapPrimitive2D& rCompare = static_cast< const FillBitmapPrimitive2D& >(rPrimitive);
+
+ return (getTransformation() == rCompare.getTransformation()
+ && getFillBitmap() == rCompare.getFillBitmap());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange FillBitmapPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return range of it
+ basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aPolygon.transform(getTransformation());
+ return basegfx::tools::getRange(aPolygon);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(FillBitmapPrimitive2D, PRIMITIVE2D_ID_FILLBITMAPPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
new file mode 100644
index 000000000000..ff0c031b38a1
--- /dev/null
+++ b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
@@ -0,0 +1,202 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fillgradientprimitive2d.cxx,v $
+ *
+ * $Revision: 1.6 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/texture/texture.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence FillGradientPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ const attribute::GradientStyle aGradientStyle(maFillGradient.getStyle());
+ ::std::vector< basegfx::B2DHomMatrix > aMatrices;
+ ::std::vector< basegfx::BColor > aColors;
+ basegfx::B2DPolygon aUnitPolygon;
+ sal_uInt32 nSteps(maFillGradient.getSteps());
+
+ if(attribute::GRADIENTSTYLE_RADIAL == aGradientStyle || attribute::GRADIENTSTYLE_ELLIPTICAL == aGradientStyle)
+ {
+ const basegfx::B2DPoint aCircleCenter(0.5, 0.5);
+ aUnitPolygon = basegfx::tools::createPolygonFromEllipse(aCircleCenter, 0.5, 0.5);
+ }
+ else
+ {
+ aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0));
+ }
+
+ // make sure steps is not too high/low
+ const basegfx::BColor aStart(maFillGradient.getStartColor());
+ const basegfx::BColor aEnd(maFillGradient.getEndColor());
+ const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
+
+ if(nSteps == 0L)
+ {
+ nSteps = nMaxSteps;
+ }
+
+ if(nSteps < 2L)
+ {
+ nSteps = 2L;
+ }
+
+ if(nSteps > nMaxSteps)
+ {
+ nSteps = nMaxSteps;
+ }
+
+ switch(aGradientStyle)
+ {
+ case attribute::GRADIENTSTYLE_LINEAR:
+ {
+ texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), -maFillGradient.getAngle());
+ aGradient.appendTransformations(aMatrices);
+ aGradient.appendColors(aColors);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_AXIAL:
+ {
+ texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), -maFillGradient.getAngle());
+ aGradient.appendTransformations(aMatrices);
+ aGradient.appendColors(aColors);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_RADIAL:
+ {
+ texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY());
+ aGradient.appendTransformations(aMatrices);
+ aGradient.appendColors(aColors);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_ELLIPTICAL:
+ {
+ texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY(), -maFillGradient.getAngle());
+ aGradient.appendTransformations(aMatrices);
+ aGradient.appendColors(aColors);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_SQUARE:
+ {
+ texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY(), -maFillGradient.getAngle());
+ aGradient.appendTransformations(aMatrices);
+ aGradient.appendColors(aColors);
+ break;
+ }
+ case attribute::GRADIENTSTYLE_RECT:
+ {
+ texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, maFillGradient.getBorder(), maFillGradient.getOffsetX(), maFillGradient.getOffsetY(), -maFillGradient.getAngle());
+ aGradient.appendTransformations(aMatrices);
+ aGradient.appendColors(aColors);
+ break;
+ }
+ }
+
+ // prepare return value
+ Primitive2DSequence aRetval(aColors.size() ? aMatrices.size() + 1L : aMatrices.size());
+
+ // create solid fill with start color
+ if(aColors.size())
+ {
+ // create primitive
+ const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())), aColors[0L]));
+ aRetval[0L] = xRef;
+ }
+
+ // create solid fill steps
+ for(sal_uInt32 a(0L); a < aMatrices.size(); a++)
+ {
+ // create part polygon
+ basegfx::B2DPolygon aNewPoly(aUnitPolygon);
+ aNewPoly.transform(aMatrices[a]);
+
+ // create solid fill
+ const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aNewPoly), aColors[a + 1L]));
+ aRetval[a + 1L] = xRef;
+ }
+
+ return aRetval;
+ }
+
+ FillGradientPrimitive2D::FillGradientPrimitive2D(
+ const basegfx::B2DRange& rObjectRange,
+ const attribute::FillGradientAttribute& rFillGradient)
+ : BasePrimitive2D(),
+ maObjectRange(rObjectRange),
+ maFillGradient(rFillGradient)
+ {
+ }
+
+ bool FillGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const FillGradientPrimitive2D& rCompare = (FillGradientPrimitive2D&)rPrimitive;
+
+ return (getObjectRange() == rCompare.getObjectRange()
+ && maFillGradient == rCompare.maFillGradient);
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange FillGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return ObjectRange
+ return getObjectRange();
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(FillGradientPrimitive2D, PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
new file mode 100644
index 000000000000..06d04111686d
--- /dev/null
+++ b/drawinglayer/source/primitive2d/fillhatchprimitive2d.cxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: fillhatchprimitive2d.cxx,v $
+ *
+ * $Revision: 1.6 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
+#include <drawinglayer/texture/texture.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence FillHatchPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // create hatch
+ const basegfx::BColor aHatchColor(maFillHatch.getColor());
+ const double fAngle(-maFillHatch.getAngle());
+ ::std::vector< basegfx::B2DHomMatrix > aMatrices;
+
+ // get hatch transformations
+ switch(maFillHatch.getStyle())
+ {
+ case attribute::HATCHSTYLE_TRIPLE:
+ {
+ // rotated 45 degrees
+ texture::GeoTexSvxHatch aHatch(getObjectRange(), maFillHatch.getDistance(), fAngle + F_PI4);
+ aHatch.appendTransformations(aMatrices);
+
+ // fall-through by purpose
+ }
+ case attribute::HATCHSTYLE_DOUBLE:
+ {
+ // rotated 90 degrees
+ texture::GeoTexSvxHatch aHatch(getObjectRange(), maFillHatch.getDistance(), fAngle + F_PI2);
+ aHatch.appendTransformations(aMatrices);
+
+ // fall-through by purpose
+ }
+ case attribute::HATCHSTYLE_SINGLE:
+ {
+ // angle as given
+ texture::GeoTexSvxHatch aHatch(getObjectRange(), maFillHatch.getDistance(), fAngle);
+ aHatch.appendTransformations(aMatrices);
+ }
+ }
+
+ // prepare return value
+ const bool bFillBackground(maFillHatch.isFillBackground());
+ Primitive2DSequence aRetval(bFillBackground ? aMatrices.size() + 1L : aMatrices.size());
+
+ // evtl. create filled background
+ if(bFillBackground)
+ {
+ // create primitive for background
+ const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())), maBColor));
+ aRetval[0L] = xRef;
+ }
+
+ // create primitives
+ const basegfx::B2DPoint aStart(0.0, 0.0);
+ const basegfx::B2DPoint aEnd(1.0, 0.0);
+
+ for(sal_uInt32 a(0L); a < aMatrices.size(); a++)
+ {
+ const basegfx::B2DHomMatrix& rMatrix = aMatrices[a];
+ basegfx::B2DPolygon aNewLine;
+
+ aNewLine.append(rMatrix * aStart);
+ aNewLine.append(rMatrix * aEnd);
+
+ // create hairline
+ const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(aNewLine, aHatchColor));
+ aRetval[bFillBackground ? (a + 1L) : a] = xRef;
+ }
+
+ return aRetval;
+ }
+
+ FillHatchPrimitive2D::FillHatchPrimitive2D(
+ const basegfx::B2DRange& rObjectRange,
+ const basegfx::BColor& rBColor,
+ const attribute::FillHatchAttribute& rFillHatch)
+ : BasePrimitive2D(),
+ maObjectRange(rObjectRange),
+ maFillHatch(rFillHatch),
+ maBColor(rBColor)
+ {
+ }
+
+ bool FillHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const FillHatchPrimitive2D& rCompare = (FillHatchPrimitive2D&)rPrimitive;
+
+ return (getObjectRange() == rCompare.getObjectRange()
+ && maFillHatch == rCompare.maFillHatch
+ && maBColor == rCompare.maBColor);
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange FillHatchPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return ObjectRange
+ return getObjectRange();
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(FillHatchPrimitive2D, PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/graphicprimitive2d.cxx b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
new file mode 100644
index 000000000000..1ed826dab562
--- /dev/null
+++ b/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
@@ -0,0 +1,458 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: graphicprimitive2d.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
+#include <drawinglayer/animation/animationtiming.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
+#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// helper class for animated graphics
+
+#include <vcl/animate.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ struct animationStep
+ {
+ BitmapEx maBitmapEx;
+ sal_uInt32 mnTime;
+ };
+
+ class animatedBitmapExPreparator
+ {
+ ::Animation maAnimation;
+ ::std::vector< animationStep > maSteps;
+
+ sal_uInt32 generateStepTime(sal_uInt32 nIndex) const;
+
+ public:
+ animatedBitmapExPreparator(const Graphic& rGraphic);
+
+ sal_uInt32 count() const { return maSteps.size(); }
+ sal_uInt32 loopCount() const { return (sal_uInt32)maAnimation.GetLoopCount(); }
+ sal_uInt32 stepTime(sal_uInt32 a) const { return maSteps[a].mnTime; }
+ const BitmapEx& stepBitmapEx(sal_uInt32 a) const { return maSteps[a].maBitmapEx; }
+ };
+
+ sal_uInt32 animatedBitmapExPreparator::generateStepTime(sal_uInt32 nIndex) const
+ {
+ const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(nIndex));
+ sal_uInt32 nWaitTime(rAnimBitmap.nWait * 10);
+
+ // #115934#
+ // Take care of special value for MultiPage TIFFs. ATM these shall just
+ // show their first page. Later we will offer some switching when object
+ // is selected.
+ if(ANIMATION_TIMEOUT_ON_CLICK == rAnimBitmap.nWait)
+ {
+ // ATM the huge value would block the timer, so
+ // use a long time to show first page (whole day)
+ nWaitTime = 100 * 60 * 60 * 24;
+ }
+
+ // Bad trap: There are animated gifs with no set WaitTime (!).
+ // In that case use a default value.
+ if(0L == nWaitTime)
+ {
+ nWaitTime = 100L;
+ }
+
+ return nWaitTime;
+ }
+
+ animatedBitmapExPreparator::animatedBitmapExPreparator(const Graphic& rGraphic)
+ : maAnimation(rGraphic.GetAnimation())
+ {
+ OSL_ENSURE(GRAPHIC_BITMAP == rGraphic.GetType() && rGraphic.IsAnimated(), "animatedBitmapExPreparator: graphic is not animated (!)");
+
+ // #128539# secure access to Animation, looks like there exist animated GIFs out there
+ // with a step count of zero
+ if(maAnimation.Count())
+ {
+ VirtualDevice aVirtualDevice(*Application::GetDefaultDevice());
+ VirtualDevice aVirtualDeviceMask(*Application::GetDefaultDevice(), 1L);
+
+ // Prepare VirtualDevices and their states
+ aVirtualDevice.EnableMapMode(sal_False);
+ aVirtualDeviceMask.EnableMapMode(sal_False);
+ aVirtualDevice.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
+ aVirtualDeviceMask.SetOutputSizePixel(maAnimation.GetDisplaySizePixel());
+ aVirtualDevice.Erase();
+ aVirtualDeviceMask.Erase();
+
+ for(sal_uInt16 a(0L); a < maAnimation.Count(); a++)
+ {
+ animationStep aNextStep;
+ aNextStep.mnTime = generateStepTime(a);
+
+ // prepare step
+ const AnimationBitmap& rAnimBitmap = maAnimation.Get(sal_uInt16(a));
+
+ switch(rAnimBitmap.eDisposal)
+ {
+ case DISPOSE_NOT:
+ {
+ aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
+ Bitmap aMask = rAnimBitmap.aBmpEx.GetMask();
+
+ if(aMask.IsEmpty())
+ {
+ const Point aEmpty;
+ const Rectangle aRect(aEmpty, aVirtualDeviceMask.GetOutputSizePixel());
+ const Wallpaper aWallpaper(COL_BLACK);
+ aVirtualDeviceMask.DrawWallpaper(aRect, aWallpaper);
+ }
+ else
+ {
+ BitmapEx aExpandVisibilityMask = BitmapEx(aMask, aMask);
+ aVirtualDeviceMask.DrawBitmapEx(rAnimBitmap.aPosPix, aExpandVisibilityMask);
+ }
+
+ break;
+ }
+ case DISPOSE_BACK:
+ {
+ // #i70772# react on no mask, for primitives, too.
+ const Bitmap aMask(rAnimBitmap.aBmpEx.GetMask());
+ const Bitmap aContent(rAnimBitmap.aBmpEx.GetBitmap());
+
+ aVirtualDeviceMask.Erase();
+ aVirtualDevice.DrawBitmap(rAnimBitmap.aPosPix, aContent);
+
+ if(aMask.IsEmpty())
+ {
+ const Rectangle aRect(rAnimBitmap.aPosPix, aContent.GetSizePixel());
+ aVirtualDeviceMask.SetFillColor(COL_BLACK);
+ aVirtualDeviceMask.SetLineColor();
+ aVirtualDeviceMask.DrawRect(aRect);
+ }
+ else
+ {
+ aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, aMask);
+ }
+
+ break;
+ }
+ case DISPOSE_FULL:
+ {
+ aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
+ break;
+ }
+ case DISPOSE_PREVIOUS :
+ {
+ aVirtualDevice.DrawBitmapEx(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx);
+ aVirtualDeviceMask.DrawBitmap(rAnimBitmap.aPosPix, rAnimBitmap.aBmpEx.GetMask());
+ break;
+ }
+ }
+
+ // create BitmapEx
+ Bitmap aMainBitmap = aVirtualDevice.GetBitmap(Point(), aVirtualDevice.GetOutputSizePixel());
+ Bitmap aMaskBitmap = aVirtualDeviceMask.GetBitmap(Point(), aVirtualDeviceMask.GetOutputSizePixel());
+ aNextStep.maBitmapEx = BitmapEx(aMainBitmap, aMaskBitmap);
+
+ // add to vector
+ maSteps.push_back(aNextStep);
+ }
+ }
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence GraphicPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence aRetval;
+
+ if(255L != getGraphicAttr().GetTransparency())
+ {
+ // get transformed graphic. Suppress rotation and cropping, only filtering is needed
+ // here (and may be replaced later on). Cropping is handled below as mask primitive (if set)
+ GraphicAttr aSuppressGraphicAttr(getGraphicAttr());
+ aSuppressGraphicAttr.SetCrop(0L, 0L, 0L, 0L);
+ aSuppressGraphicAttr.SetRotation(0);
+ Graphic aTransformedGraphic(getGraphicObject().GetTransformedGraphic(&aSuppressGraphicAttr));
+ Primitive2DReference xPrimitive;
+
+ switch(aTransformedGraphic.GetType())
+ {
+ case GRAPHIC_BITMAP :
+ {
+ if(aTransformedGraphic.IsAnimated())
+ {
+ // prepare animation data
+ animatedBitmapExPreparator aData(aTransformedGraphic);
+
+ if(aData.count())
+ {
+ // create sub-primitives for animated bitmap and the needed animation loop
+ animation::AnimationEntryLoop aAnimationLoop(aData.loopCount() ? aData.loopCount() : 0xffff);
+ Primitive2DSequence aBitmapPrimitives(aData.count());
+
+ for(sal_uInt32 a(0L); a < aData.count(); a++)
+ {
+ animation::AnimationEntryFixed aTime((double)aData.stepTime(a), (double)a / (double)aData.count());
+ aAnimationLoop.append(aTime);
+ const Primitive2DReference xRef(new BitmapPrimitive2D(aData.stepBitmapEx(a), getTransform()));
+ aBitmapPrimitives[a] = xRef;
+ }
+
+ // prepare animation list
+ animation::AnimationEntryList aAnimationList;
+ aAnimationList.append(aAnimationLoop);
+
+ // create and add animated switch primitive
+ xPrimitive = Primitive2DReference(new AnimatedSwitchPrimitive2D(aAnimationList, aBitmapPrimitives, false));
+ }
+ }
+ else
+ {
+ xPrimitive = Primitive2DReference(new BitmapPrimitive2D(aTransformedGraphic.GetBitmapEx(), getTransform()));
+ }
+
+ break;
+ }
+
+ case GRAPHIC_GDIMETAFILE :
+ {
+ // create MetafilePrimitive2D
+ const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile();
+
+ xPrimitive = Primitive2DReference(
+ new MetafilePrimitive2D(
+ getTransform(),
+ rMetafile));
+
+ // #i100357# find out if clipping is needed for this primitive. Unfortunately,
+ // there exist Metafiles who's content is bigger than the proposed PrefSize set
+ // at them. This is an error, but we need to work around this
+ const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
+ const Size aMetaFileRealSize(
+ const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
+ *Application::GetDefaultDevice()).GetSize());
+
+ if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
+ || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
+ {
+ // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
+ const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
+ basegfx::B2DPolygon aMaskPolygon(
+ basegfx::tools::createPolygonFromRect(
+ basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aMaskPolygon.transform(getTransform());
+
+ xPrimitive = Primitive2DReference(
+ new MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(aMaskPolygon),
+ aChildContent));
+ }
+
+ break;
+ }
+
+ default:
+ {
+ // nothing to create
+ break;
+ }
+ }
+
+ if(xPrimitive.is())
+ {
+ // check for cropping
+ if(getGraphicAttr().IsCropped())
+ {
+ // decompose to get current pos and size
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // create ranges. The current object range is just scale and translate
+ const basegfx::B2DRange aCurrent(aTranslate.getX(), aTranslate.getY(), aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
+
+ // calculate scalings between real image size and logic object size. This
+ // is necessary since the crop values are relative to original bitmap size
+ double fFactorX(1.0);
+ double fFactorY(1.0);
+
+ {
+ const MapMode aMapMode100thmm(MAP_100TH_MM);
+ Size aBitmapSize(getGraphicObject().GetPrefSize());
+
+ // #i95968# better support PrefMapMode; special for MAP_PIXEL was missing
+ if(MAP_PIXEL == getGraphicObject().GetPrefMapMode().GetMapUnit())
+ {
+ aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
+ }
+ else
+ {
+ aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, getGraphicObject().GetPrefMapMode(), aMapMode100thmm);
+ }
+
+ const double fDivX(aBitmapSize.Width() - getGraphicAttr().GetLeftCrop() - getGraphicAttr().GetRightCrop());
+ const double fDivY(aBitmapSize.Height() - getGraphicAttr().GetTopCrop() - getGraphicAttr().GetBottomCrop());
+
+ if(!basegfx::fTools::equalZero(fDivX))
+ {
+ fFactorX = aScale.getX() / fDivX;
+ }
+
+ if(!basegfx::fTools::equalZero(fDivY))
+ {
+ fFactorY = aScale.getY() / fDivY;
+ }
+ }
+
+ // Create cropped range, describes the bounds of the original graphic
+ basegfx::B2DRange aCropped;
+ aCropped.expand(aCurrent.getMinimum() - basegfx::B2DPoint(getGraphicAttr().GetLeftCrop() * fFactorX, getGraphicAttr().GetTopCrop() * fFactorY));
+ aCropped.expand(aCurrent.getMaximum() + basegfx::B2DPoint(getGraphicAttr().GetRightCrop() * fFactorX, getGraphicAttr().GetBottomCrop() * fFactorY));
+
+ if(aCropped.isEmpty())
+ {
+ // nothing to add since cropped bitmap is completely empty
+ // xPrimitive will not be used
+ }
+ else
+ {
+ // build new object transformation for transform primitive which contains xPrimitive
+ basegfx::B2DHomMatrix aNewObjectTransform(getTransform());
+ aNewObjectTransform.invert();
+ aNewObjectTransform.scale(aCropped.getWidth(), aCropped.getHeight());
+ aNewObjectTransform.translate(aCropped.getMinX() - aCurrent.getMinX(), aCropped.getMinY() - aCurrent.getMinY());
+ aNewObjectTransform.shearX(fShearX);
+ aNewObjectTransform.rotate(fRotate);
+ aNewObjectTransform.translate(aTranslate.getX(), aTranslate.getY());
+
+ // prepare TransformPrimitive2D with xPrimitive
+ const Primitive2DReference xTransformPrimitive(new TransformPrimitive2D(aNewObjectTransform, Primitive2DSequence(&xPrimitive, 1L)));
+
+ if(aCurrent.isInside(aCropped))
+ {
+ // cropped just got smaller, no need to really use a mask. Add to destination directly
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xTransformPrimitive);
+ }
+ else
+ {
+ // cropped got bigger, mask it with original object's bounds
+ basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aMaskPolyPolygon.transform(getTransform());
+
+ // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
+ const Primitive2DReference xRefB(new MaskPrimitive2D(aMaskPolyPolygon, Primitive2DSequence(&xTransformPrimitive, 1L)));
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRefB);
+ }
+ }
+ }
+ else
+ {
+ // add to decomposition
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xPrimitive);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ GraphicPrimitive2D::GraphicPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const GraphicObject& rGraphicObject,
+ const GraphicAttr& rGraphicAttr)
+ : BasePrimitive2D(),
+ maTransform(rTransform),
+ maGraphicObject(rGraphicObject),
+ maGraphicAttr(rGraphicAttr)
+ {
+ }
+
+ GraphicPrimitive2D::GraphicPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const GraphicObject& rGraphicObject)
+ : BasePrimitive2D(),
+ maTransform(rTransform),
+ maGraphicObject(rGraphicObject),
+ maGraphicAttr()
+ {
+ }
+
+ bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive;
+
+ return (getTransform() == rCompare.getTransform()
+ && getGraphicObject() == rCompare.getGraphicObject()
+ && getGraphicAttr() == rCompare.getGraphicAttr());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(getTransform());
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
new file mode 100644
index 000000000000..df4171309389
--- /dev/null
+++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
@@ -0,0 +1,329 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: gridprimitive2d.cxx,v $
+ *
+ * $Revision: 1.10 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/gridprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
+#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence GridPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+
+ if(!rViewInformation.getViewport().isEmpty() && getWidth() > 0.0 && getHeight() > 0.0)
+ {
+ // decompose grid matrix to get logic size
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // create grid matrix which transforms from scaled logic to view
+ basegfx::B2DHomMatrix aRST;
+ aRST.shearX(fShearX);
+ aRST.rotate(fRotate);
+ aRST.translate(aTranslate.getX(), aTranslate.getY());
+ aRST *= rViewInformation.getObjectToViewTransformation();
+
+ // get step widths
+ double fStepX(getWidth());
+ double fStepY(getHeight());
+ const double fMinimalStep(10.0);
+
+ // guarantee a step width of 10.0
+ if(basegfx::fTools::less(fStepX, fMinimalStep))
+ {
+ fStepX = fMinimalStep;
+ }
+
+ if(basegfx::fTools::less(fStepY, fMinimalStep))
+ {
+ fStepY = fMinimalStep;
+ }
+
+ // get relative distances in view coordinates
+ double fViewStepX((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(fStepX, 0.0)).getLength());
+ double fViewStepY((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fStepY)).getLength());
+ double fSmallStepX(1.0), fViewSmallStepX(1.0), fSmallStepY(1.0), fViewSmallStepY(1.0);
+ sal_uInt32 nSmallStepsX(0L), nSmallStepsY(0L);
+
+ // setup subdivisions
+ if(getSubdivisionsX())
+ {
+ fSmallStepX = fStepX / getSubdivisionsX();
+ fViewSmallStepX = fViewStepX / getSubdivisionsX();
+ }
+
+ if(getSubdivisionsY())
+ {
+ fSmallStepY = fStepY / getSubdivisionsY();
+ fViewSmallStepY = fViewStepY / getSubdivisionsY();
+ }
+
+ // correct step width
+ while(fViewStepX < getSmallestViewDistance())
+ {
+ fViewStepX *= 2.0;
+ fStepX *= 2.0;
+ }
+
+ while(fViewStepY < getSmallestViewDistance())
+ {
+ fViewStepY *= 2.0;
+ fStepY *= 2.0;
+ }
+
+ // correct small step width
+ if(getSubdivisionsX())
+ {
+ while(fViewSmallStepX < getSmallestSubdivisionViewDistance())
+ {
+ fViewSmallStepX *= 2.0;
+ fSmallStepX *= 2.0;
+ }
+
+ nSmallStepsX = (sal_uInt32)(fStepX / fSmallStepX);
+ }
+
+ if(getSubdivisionsY())
+ {
+ while(fViewSmallStepY < getSmallestSubdivisionViewDistance())
+ {
+ fViewSmallStepY *= 2.0;
+ fSmallStepY *= 2.0;
+ }
+
+ nSmallStepsY = (sal_uInt32)(fStepY / fSmallStepY);
+ }
+
+ // prepare point vectors for point and cross markers
+ std::vector< basegfx::B2DPoint > aPositionsPoint;
+ std::vector< basegfx::B2DPoint > aPositionsCross;
+
+ for(double fX(0.0); fX < aScale.getX(); fX += fStepX)
+ {
+ const bool bXZero(basegfx::fTools::equalZero(fX));
+
+ for(double fY(0.0); fY < aScale.getY(); fY += fStepY)
+ {
+ const bool bYZero(basegfx::fTools::equalZero(fY));
+
+ if(!bXZero && !bYZero)
+ {
+ // get discrete position and test against 3x3 area surrounding it
+ // since it's a cross
+ const double fHalfCrossSize(3.0 * 0.5);
+ const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fY));
+ const basegfx::B2DRange aDiscreteRangeCross(
+ aViewPos.getX() - fHalfCrossSize, aViewPos.getY() - fHalfCrossSize,
+ aViewPos.getX() + fHalfCrossSize, aViewPos.getY() + fHalfCrossSize);
+
+ if(rViewInformation.getDiscreteViewport().overlaps(aDiscreteRangeCross))
+ {
+ const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
+ aPositionsCross.push_back(aLogicPos);
+ }
+ }
+
+ if(getSubdivisionsX() && !bYZero)
+ {
+ double fF(fX + fSmallStepX);
+
+ for(sal_uInt32 a(1L); a < nSmallStepsX && fF < aScale.getX(); a++, fF += fSmallStepX)
+ {
+ const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fF, fY));
+
+ if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
+ {
+ const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
+ aPositionsPoint.push_back(aLogicPos);
+ }
+ }
+ }
+
+ if(getSubdivisionsY() && !bXZero)
+ {
+ double fF(fY + fSmallStepY);
+
+ for(sal_uInt32 a(1L); a < nSmallStepsY && fF < aScale.getY(); a++, fF += fSmallStepY)
+ {
+ const basegfx::B2DPoint aViewPos(aRST * basegfx::B2DPoint(fX, fF));
+
+ if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
+ {
+ const basegfx::B2DPoint aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
+ aPositionsPoint.push_back(aLogicPos);
+ }
+ }
+ }
+ }
+ }
+
+ // prepare return value
+ const sal_uInt32 nCountPoint(aPositionsPoint.size());
+ const sal_uInt32 nCountCross(aPositionsCross.size());
+ const sal_uInt32 nRetvalCount((nCountPoint ? 1 : 0) + (nCountCross ? 1 : 0));
+ sal_uInt32 nInsertCounter(0);
+
+ aRetval.realloc(nRetvalCount);
+
+ // add PointArrayPrimitive2D if point markers were added
+ if(nCountPoint)
+ {
+ aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsPoint, getBColor()));
+ }
+
+ // add MarkerArrayPrimitive2D if cross markers were added
+ if(nCountCross)
+ {
+ if(!getSubdivisionsX() && !getSubdivisionsY())
+ {
+ // no subdivisions, so fall back to points at grid positions, no need to
+ // visualize a difference between divisions and sub-divisions
+ aRetval[nInsertCounter++] = Primitive2DReference(new PointArrayPrimitive2D(aPositionsCross, getBColor()));
+ }
+ else
+ {
+ aRetval[nInsertCounter++] = Primitive2DReference(new MarkerArrayPrimitive2D(aPositionsCross, getCrossMarker()));
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ GridPrimitive2D::GridPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ double fWidth,
+ double fHeight,
+ double fSmallestViewDistance,
+ double fSmallestSubdivisionViewDistance,
+ sal_uInt32 nSubdivisionsX,
+ sal_uInt32 nSubdivisionsY,
+ const basegfx::BColor& rBColor,
+ const BitmapEx& rCrossMarker)
+ : BasePrimitive2D(),
+ maTransform(rTransform),
+ mfWidth(fWidth),
+ mfHeight(fHeight),
+ mfSmallestViewDistance(fSmallestViewDistance),
+ mfSmallestSubdivisionViewDistance(fSmallestSubdivisionViewDistance),
+ mnSubdivisionsX(nSubdivisionsX),
+ mnSubdivisionsY(nSubdivisionsY),
+ maBColor(rBColor),
+ maCrossMarker(rCrossMarker),
+ maLastObjectToViewTransformation(),
+ maLastViewport()
+ {
+ }
+
+ bool GridPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const GridPrimitive2D& rCompare = (GridPrimitive2D&)rPrimitive;
+
+ return (getTransform() == rCompare.getTransform()
+ && getWidth() == rCompare.getWidth()
+ && getHeight() == rCompare.getHeight()
+ && getSmallestViewDistance() == rCompare.getSmallestViewDistance()
+ && getSmallestSubdivisionViewDistance() == rCompare.getSmallestSubdivisionViewDistance()
+ && getSubdivisionsX() == rCompare.getSubdivisionsX()
+ && getSubdivisionsY() == rCompare.getSubdivisionsY()
+ && getBColor() == rCompare.getBColor()
+ && getCrossMarker() == rCompare.getCrossMarker());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange GridPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // get object's range
+ basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+ aUnitRange.transform(getTransform());
+
+ // intersect with visible part
+ aUnitRange.intersect(rViewInformation.getViewport());
+
+ return aUnitRange;
+ }
+
+ Primitive2DSequence GridPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if(getLocalDecomposition().hasElements())
+ {
+ if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< GridPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember ViewRange and ViewTransformation
+ const_cast< GridPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
+ const_cast< GridPrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport();
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(GridPrimitive2D, PRIMITIVE2D_ID_GRIDPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/groupprimitive2d.cxx b/drawinglayer/source/primitive2d/groupprimitive2d.cxx
new file mode 100644
index 000000000000..ae899af6e84d
--- /dev/null
+++ b/drawinglayer/source/primitive2d/groupprimitive2d.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: groupprimitive2d.cxx,v $
+ *
+ * $Revision: 1.7 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ /// default: just return children, so all renderers not supporting group will use it's content
+ Primitive2DSequence GroupPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ return getChildren();
+ }
+
+ GroupPrimitive2D::GroupPrimitive2D( const Primitive2DSequence& rChildren )
+ : BasePrimitive2D(),
+ maChildren(rChildren)
+ {
+ }
+
+ /** The compare opertator uses the Sequence::==operator, so only checking if
+ the rererences are equal. All non-equal references are interpreted as
+ non-equal.
+ */
+ bool GroupPrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const GroupPrimitive2D& rCompare = static_cast< const GroupPrimitive2D& >(rPrimitive);
+
+ return (arePrimitive2DSequencesEqual(getChildren(), rCompare.getChildren()));
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(GroupPrimitive2D, PRIMITIVE2D_ID_GROUPPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/helplineprimitive2d.cxx b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
new file mode 100644
index 000000000000..3232e635b561
--- /dev/null
+++ b/drawinglayer/source/primitive2d/helplineprimitive2d.cxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: helplineprimitive2d.cxx,v $
+ *
+ * $Revision: 1.7 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/helplineprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence HelplinePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ std::vector< BasePrimitive2D* > aTempPrimitiveTarget;
+
+ if(!rViewInformation.getViewport().isEmpty() && !getDirection().equalZero())
+ {
+ // position to view coordinates, DashLen and DashLen in logic
+ const basegfx::B2DPoint aViewPosition(rViewInformation.getObjectToViewTransformation() * getPosition());
+
+ switch(getStyle())
+ {
+ default : // HELPLINESTYLE2D_POINT
+ {
+ const double fViewFixValue(15.0);
+ basegfx::B2DVector aNormalizedDirection(getDirection());
+ aNormalizedDirection.normalize();
+ aNormalizedDirection *= fViewFixValue;
+ const basegfx::B2DPoint aStartA(aViewPosition - aNormalizedDirection);
+ const basegfx::B2DPoint aEndA(aViewPosition + aNormalizedDirection);
+ basegfx::B2DPolygon aLineA;
+ aLineA.append(aStartA);
+ aLineA.append(aEndA);
+ aLineA.transform(rViewInformation.getInverseObjectToViewTransformation());
+ PolygonMarkerPrimitive2D* pNewA = new PolygonMarkerPrimitive2D(aLineA, getRGBColA(), getRGBColB(), getDiscreteDashLength());
+ aTempPrimitiveTarget.push_back(pNewA);
+
+ const basegfx::B2DVector aPerpendicularNormalizedDirection(basegfx::getPerpendicular(aNormalizedDirection));
+ const basegfx::B2DPoint aStartB(aViewPosition - aPerpendicularNormalizedDirection);
+ const basegfx::B2DPoint aEndB(aViewPosition + aPerpendicularNormalizedDirection);
+ basegfx::B2DPolygon aLineB;
+ aLineB.append(aStartB);
+ aLineB.append(aEndB);
+ aLineB.transform(rViewInformation.getInverseObjectToViewTransformation());
+ PolygonMarkerPrimitive2D* pNewB = new PolygonMarkerPrimitive2D(aLineB, getRGBColA(), getRGBColB(), getDiscreteDashLength());
+ aTempPrimitiveTarget.push_back(pNewB);
+
+ break;
+ }
+ case HELPLINESTYLE2D_LINE :
+ {
+ basegfx::B2DPolygon aLine;
+
+ if(basegfx::areParallel(getDirection(), basegfx::B2DVector(1.0, 0.0)))
+ {
+ // parallel to X-Axis, get cuts with Y-Axes
+ const double fCutA((rViewInformation.getDiscreteViewport().getMinX() - aViewPosition.getX()) / getDirection().getX());
+ const double fCutB((rViewInformation.getDiscreteViewport().getMaxX() - aViewPosition.getX()) / getDirection().getX());
+ const basegfx::B2DPoint aPosA(aViewPosition + (fCutA * getDirection()));
+ const basegfx::B2DPoint aPosB(aViewPosition + (fCutB * getDirection()));
+ const bool bBothLeft(aPosA.getX() < rViewInformation.getDiscreteViewport().getMinX() && aPosB.getX() < rViewInformation.getDiscreteViewport().getMinX());
+ const bool bBothRight(aPosA.getX() > rViewInformation.getDiscreteViewport().getMaxX() && aPosB.getX() < rViewInformation.getDiscreteViewport().getMaxX());
+
+ if(!bBothLeft && !bBothRight)
+ {
+ aLine.append(aPosA);
+ aLine.append(aPosB);
+ }
+ }
+ else
+ {
+ // get cuts with X-Axes
+ const double fCutA((rViewInformation.getDiscreteViewport().getMinY() - aViewPosition.getY()) / getDirection().getY());
+ const double fCutB((rViewInformation.getDiscreteViewport().getMaxY() - aViewPosition.getY()) / getDirection().getY());
+ const basegfx::B2DPoint aPosA(aViewPosition + (fCutA * getDirection()));
+ const basegfx::B2DPoint aPosB(aViewPosition + (fCutB * getDirection()));
+ const bool bBothAbove(aPosA.getY() < rViewInformation.getDiscreteViewport().getMinY() && aPosB.getY() < rViewInformation.getDiscreteViewport().getMinY());
+ const bool bBothBelow(aPosA.getY() > rViewInformation.getDiscreteViewport().getMaxY() && aPosB.getY() < rViewInformation.getDiscreteViewport().getMaxY());
+
+ if(!bBothAbove && !bBothBelow)
+ {
+ aLine.append(aPosA);
+ aLine.append(aPosB);
+ }
+ }
+
+ if(aLine.count())
+ {
+ // clip against visible area
+ const basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolygonOnRange(aLine, rViewInformation.getDiscreteViewport(), true, true));
+
+ for(sal_uInt32 a(0L); a < aResult.count(); a++)
+ {
+ basegfx::B2DPolygon aPart(aResult.getB2DPolygon(a));
+ aPart.transform(rViewInformation.getInverseObjectToViewTransformation());
+ PolygonMarkerPrimitive2D* pNew = new PolygonMarkerPrimitive2D(aPart, getRGBColA(), getRGBColB(), getDiscreteDashLength());
+ aTempPrimitiveTarget.push_back(pNew);
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ // prepare return value
+ Primitive2DSequence aRetval(aTempPrimitiveTarget.size());
+
+ for(sal_uInt32 a(0L); a < aTempPrimitiveTarget.size(); a++)
+ {
+ const Primitive2DReference xRef(aTempPrimitiveTarget[a]);
+ aRetval[a] = xRef;
+ }
+
+ return aRetval;
+ }
+
+ HelplinePrimitive2D::HelplinePrimitive2D(
+ const basegfx::B2DPoint& rPosition,
+ const basegfx::B2DVector& rDirection,
+ HelplineStyle2D eStyle,
+ const basegfx::BColor& rRGBColA,
+ const basegfx::BColor& rRGBColB,
+ double fDiscreteDashLength)
+ : BasePrimitive2D(),
+ maPosition(rPosition),
+ maDirection(rDirection),
+ meStyle(eStyle),
+ maRGBColA(rRGBColA),
+ maRGBColB(rRGBColB),
+ mfDiscreteDashLength(fDiscreteDashLength),
+ maLastObjectToViewTransformation(),
+ maLastViewport()
+ {
+ }
+
+ bool HelplinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const HelplinePrimitive2D& rCompare = (HelplinePrimitive2D&)rPrimitive;
+
+ return (getPosition() == rCompare.getPosition()
+ && getDirection() == rCompare.getDirection()
+ && getStyle() == rCompare.getStyle()
+ && getRGBColA() == rCompare.getRGBColA()
+ && getRGBColB() == rCompare.getRGBColB()
+ && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
+ }
+
+ return false;
+ }
+
+ Primitive2DSequence HelplinePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if(getLocalDecomposition().hasElements())
+ {
+ if(maLastViewport != rViewInformation.getViewport() || maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< HelplinePrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember ViewRange and ViewTransformation
+ const_cast< HelplinePrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
+ const_cast< HelplinePrimitive2D* >(this)->maLastViewport = rViewInformation.getViewport();
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(HelplinePrimitive2D, PRIMITIVE2D_ID_HELPLINEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/hittestprimitive2d.cxx b/drawinglayer/source/primitive2d/hittestprimitive2d.cxx
new file mode 100644
index 000000000000..daf65abd81d4
--- /dev/null
+++ b/drawinglayer/source/primitive2d/hittestprimitive2d.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: hittestprimitive3d.cxx,v $
+ *
+ * $Revision: 1.1.2.1 $
+ *
+ * last change: $Author: aw $ $Date: 2008/09/25 17:12:14 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/hittestprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence HitTestPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return empty sequence
+ return Primitive2DSequence();
+ }
+
+ HitTestPrimitive2D::HitTestPrimitive2D(
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ basegfx::B2DRange HitTestPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ return getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(HitTestPrimitive2D, PRIMITIVE2D_ID_HITTESTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/invertprimitive2d.cxx b/drawinglayer/source/primitive2d/invertprimitive2d.cxx
new file mode 100644
index 000000000000..374ec578113d
--- /dev/null
+++ b/drawinglayer/source/primitive2d/invertprimitive2d.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unifiedalphaprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/invertprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ InvertPrimitive2D::InvertPrimitive2D(
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(InvertPrimitive2D, PRIMITIVE2D_ID_INVERTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/makefile.mk b/drawinglayer/source/primitive2d/makefile.mk
new file mode 100644
index 000000000000..e10d1ddbcc71
--- /dev/null
+++ b/drawinglayer/source/primitive2d/makefile.mk
@@ -0,0 +1,90 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.13 $
+#
+# last change: $Author: aw $ $Date: 2008-04-04 06:00:23 $
+#
+# 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=primitive2d
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/alphaprimitive2d.obj \
+ $(SLO)$/animatedprimitive2d.obj \
+ $(SLO)$/baseprimitive2d.obj \
+ $(SLO)$/backgroundcolorprimitive2d.obj \
+ $(SLO)$/bitmapprimitive2d.obj \
+ $(SLO)$/borderlineprimitive2d.obj \
+ $(SLO)$/chartprimitive2d.obj \
+ $(SLO)$/controlprimitive2d.obj \
+ $(SLO)$/embedded3dprimitive2d.obj \
+ $(SLO)$/fillbitmapprimitive2d.obj \
+ $(SLO)$/fillgradientprimitive2d.obj \
+ $(SLO)$/fillhatchprimitive2d.obj \
+ $(SLO)$/graphicprimitive2d.obj \
+ $(SLO)$/gridprimitive2d.obj \
+ $(SLO)$/groupprimitive2d.obj \
+ $(SLO)$/helplineprimitive2d.obj \
+ $(SLO)$/hittestprimitive2d.obj \
+ $(SLO)$/invertprimitive2d.obj \
+ $(SLO)$/markerarrayprimitive2d.obj \
+ $(SLO)$/pointarrayprimitive2d.obj \
+ $(SLO)$/maskprimitive2d.obj \
+ $(SLO)$/mediaprimitive2d.obj \
+ $(SLO)$/metafileprimitive2d.obj \
+ $(SLO)$/modifiedcolorprimitive2d.obj \
+ $(SLO)$/pagepreviewprimitive2d.obj \
+ $(SLO)$/polypolygonprimitive2d.obj \
+ $(SLO)$/polygonprimitive2d.obj \
+ $(SLO)$/primitivetools2d.obj \
+ $(SLO)$/sceneprimitive2d.obj \
+ $(SLO)$/shadowprimitive2d.obj \
+ $(SLO)$/structuretagprimitive2d.obj \
+ $(SLO)$/texteffectprimitive2d.obj \
+ $(SLO)$/textlayoutdevice.obj \
+ $(SLO)$/textprimitive2d.obj \
+ $(SLO)$/textdecoratedprimitive2d.obj \
+ $(SLO)$/texthierarchyprimitive2d.obj \
+ $(SLO)$/transformprimitive2d.obj \
+ $(SLO)$/unifiedalphaprimitive2d.obj \
+ $(SLO)$/wrongspellprimitive2d.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
diff --git a/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx b/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx
new file mode 100644
index 000000000000..5737b9ef6cec
--- /dev/null
+++ b/drawinglayer/source/primitive2d/markerarrayprimitive2d.cxx
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: markerarrayprimitive2d.cxx,v $
+ *
+ * $Revision: 1.7 $
+ *
+ * last change: $Author: aw $ $Date: 2008-07-21 17:41:18 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence MarkerArrayPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence xRetval;
+ const std::vector< basegfx::B2DPoint >& rPositions = getPositions();
+ const sal_uInt32 nMarkerCount(rPositions.size());
+
+ if(nMarkerCount && !getMarker().IsEmpty())
+ {
+ // get pixel size
+ Size aBitmapSize(getMarker().GetSizePixel());
+
+ if(aBitmapSize.Width() && aBitmapSize.Height())
+ {
+ // get logic half pixel size
+ basegfx::B2DVector aLogicHalfSize(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(aBitmapSize.getWidth() - 1.0, aBitmapSize.getHeight() - 1.0));
+
+ // use half size for expand
+ aLogicHalfSize *= 0.5;
+
+ // number of primitives is known; realloc accordingly
+ xRetval.realloc(nMarkerCount);
+
+ for(sal_uInt32 a(0); a < nMarkerCount; a++)
+ {
+ const basegfx::B2DPoint& rPosition(rPositions[a]);
+ const basegfx::B2DRange aRange(rPosition - aLogicHalfSize, rPosition + aLogicHalfSize);
+ basegfx::B2DHomMatrix aTransform;
+
+ aTransform.set(0, 0, aRange.getWidth());
+ aTransform.set(1, 1, aRange.getHeight());
+ aTransform.set(0, 2, aRange.getMinX());
+ aTransform.set(1, 2, aRange.getMinY());
+
+ xRetval[a] = Primitive2DReference(new BitmapPrimitive2D(getMarker(), aTransform));
+ }
+ }
+ }
+
+ return xRetval;
+ }
+
+ MarkerArrayPrimitive2D::MarkerArrayPrimitive2D(
+ const std::vector< basegfx::B2DPoint >& rPositions,
+ const BitmapEx& rMarker)
+ : BasePrimitive2D(),
+ maPositions(rPositions),
+ maMarker(rMarker)
+ {
+ }
+
+ bool MarkerArrayPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const MarkerArrayPrimitive2D& rCompare = (MarkerArrayPrimitive2D&)rPrimitive;
+
+ return (getPositions() == rCompare.getPositions()
+ && getMarker() == rCompare.getMarker());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange MarkerArrayPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval;
+
+ if(getPositions().size())
+ {
+ // get the basic range from the position vector
+ for(std::vector< basegfx::B2DPoint >::const_iterator aIter(getPositions().begin()); aIter != getPositions().end(); aIter++)
+ {
+ aRetval.expand(*aIter);
+ }
+
+ if(!getMarker().IsEmpty())
+ {
+ // get pixel size
+ const Size aBitmapSize(getMarker().GetSizePixel());
+
+ if(aBitmapSize.Width() && aBitmapSize.Height())
+ {
+ // get logic half size
+ basegfx::B2DVector aLogicHalfSize(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(aBitmapSize.getWidth(), aBitmapSize.getHeight()));
+
+ // use half size for expand
+ aLogicHalfSize *= 0.5;
+
+ // apply aLogicHalfSize
+ aRetval.expand(aRetval.getMinimum() - aLogicHalfSize);
+ aRetval.expand(aRetval.getMaximum() + aLogicHalfSize);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(MarkerArrayPrimitive2D, PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/maskprimitive2d.cxx b/drawinglayer/source/primitive2d/maskprimitive2d.cxx
new file mode 100644
index 000000000000..20a4c98db67d
--- /dev/null
+++ b/drawinglayer/source/primitive2d/maskprimitive2d.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: maskprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ MaskPrimitive2D::MaskPrimitive2D(
+ const basegfx::B2DPolyPolygon& rMask,
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren),
+ maMask(rMask)
+ {
+ }
+
+ bool MaskPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const MaskPrimitive2D& rCompare = static_cast< const MaskPrimitive2D& >(rPrimitive);
+
+ return (getMask() == rCompare.getMask());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(MaskPrimitive2D, PRIMITIVE2D_ID_MASKPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/mediaprimitive2d.cxx b/drawinglayer/source/primitive2d/mediaprimitive2d.cxx
new file mode 100644
index 000000000000..7799b8e66d0e
--- /dev/null
+++ b/drawinglayer/source/primitive2d/mediaprimitive2d.cxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: mediaprimitive2d.cxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/mediaprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <avmedia/mediawindow.hxx>
+#include <goodies/grfmgr.hxx>
+#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence MediaPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence xRetval(1);
+
+ // create background object
+ basegfx::B2DPolygon aBackgroundPolygon(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aBackgroundPolygon.transform(getTransform());
+ const Primitive2DReference xRefBackground(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aBackgroundPolygon), getBackgroundColor()));
+ xRetval[0] = xRefBackground;
+
+ // try to get graphic snapshot
+ const Graphic aGraphic(avmedia::MediaWindow::grabFrame(getURL(), true));
+
+ if(GRAPHIC_BITMAP == aGraphic.GetType() || GRAPHIC_GDIMETAFILE == aGraphic.GetType())
+ {
+ const GraphicObject aGraphicObject(aGraphic);
+ const GraphicAttr aGraphicAttr;
+ xRetval.realloc(2);
+ xRetval[0] = xRefBackground;
+ xRetval[1] = Primitive2DReference(new GraphicPrimitive2D(getTransform(), aGraphicObject, aGraphicAttr));
+ }
+
+ if(getDiscreteBorder())
+ {
+ const basegfx::B2DVector aDiscreteInLogic(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector((double)getDiscreteBorder(), (double)getDiscreteBorder()));
+ const double fDiscreteSize(aDiscreteInLogic.getX() + aDiscreteInLogic.getY());
+
+ basegfx::B2DRange aSourceRange(0.0, 0.0, 1.0, 1.0);
+ aSourceRange.transform(getTransform());
+
+ basegfx::B2DRange aDestRange(aSourceRange);
+ aDestRange.grow(-0.5 * fDiscreteSize);
+
+ if(::basegfx::fTools::equalZero(aDestRange.getWidth()) || ::basegfx::fTools::equalZero(aDestRange.getHeight()))
+ {
+ // shrunk primitive has no content (zero size in X or Y), nothing to display, nothing to return
+ xRetval = Primitive2DSequence();
+ }
+ else
+ {
+ // create transformation matrix from original range to shrunk range
+ basegfx::B2DHomMatrix aTransform;
+ aTransform.translate(-aSourceRange.getMinX(), -aSourceRange.getMinY());
+ aTransform.scale(aDestRange.getWidth() / aSourceRange.getWidth(), aDestRange.getHeight() / aSourceRange.getHeight());
+ aTransform.translate(aDestRange.getMinX(), aDestRange.getMinY());
+
+ // add transform primitive
+ const Primitive2DReference aScaled(new TransformPrimitive2D(aTransform, xRetval));
+ xRetval = Primitive2DSequence(&aScaled, 1L);
+ }
+ }
+
+ return xRetval;
+ }
+
+ MediaPrimitive2D::MediaPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransform,
+ const rtl::OUString& rURL,
+ const basegfx::BColor& rBackgroundColor,
+ sal_uInt32 nDiscreteBorder)
+ : BasePrimitive2D(),
+ maTransform(rTransform),
+ maURL(rURL),
+ maBackgroundColor(rBackgroundColor),
+ mnDiscreteBorder(nDiscreteBorder)
+ {
+ }
+
+ bool MediaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const MediaPrimitive2D& rCompare = (MediaPrimitive2D&)rPrimitive;
+
+ return (getTransform() == rCompare.getTransform()
+ && getURL() == rCompare.getURL()
+ && getBackgroundColor() == rCompare.getBackgroundColor()
+ && getDiscreteBorder() == rCompare.getDiscreteBorder());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange MediaPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(getTransform());
+
+ if(getDiscreteBorder())
+ {
+ const basegfx::B2DVector aDiscreteInLogic(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector((double)getDiscreteBorder(), (double)getDiscreteBorder()));
+ const double fDiscreteSize(aDiscreteInLogic.getX() + aDiscreteInLogic.getY());
+
+ aRetval.grow(-0.5 * fDiscreteSize);
+ }
+
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(MediaPrimitive2D, PRIMITIVE2D_ID_MEDIAPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
new file mode 100644
index 000000000000..2d1c0428a6a3
--- /dev/null
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: metafileprimitive2d.cxx,v $
+ *
+ * $Revision: 1.6 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ MetafilePrimitive2D::MetafilePrimitive2D(
+ const basegfx::B2DHomMatrix& rMetaFileTransform,
+ const GDIMetaFile& rMetaFile)
+ : BasePrimitive2D(),
+ maMetaFileTransform(rMetaFileTransform),
+ maMetaFile(rMetaFile)
+ {
+ }
+
+ bool MetafilePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const MetafilePrimitive2D& rCompare = (MetafilePrimitive2D&)rPrimitive;
+
+ return (getTransform() == rCompare.getTransform()
+ && getMetaFile() == rCompare.getMetaFile());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange MetafilePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(getTransform());
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(MetafilePrimitive2D, PRIMITIVE2D_ID_METAFILEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/modifiedcolorprimitive2d.cxx b/drawinglayer/source/primitive2d/modifiedcolorprimitive2d.cxx
new file mode 100644
index 000000000000..184cf2535911
--- /dev/null
+++ b/drawinglayer/source/primitive2d/modifiedcolorprimitive2d.cxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: modifiedcolorprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ ModifiedColorPrimitive2D::ModifiedColorPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ const basegfx::BColorModifier& rColorModifier)
+ : GroupPrimitive2D(rChildren),
+ maColorModifier(rColorModifier)
+ {
+ }
+
+ bool ModifiedColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const ModifiedColorPrimitive2D& rCompare = (ModifiedColorPrimitive2D&)rPrimitive;
+
+ return (getColorModifier() == rCompare.getColorModifier());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(ModifiedColorPrimitive2D, PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx
new file mode 100644
index 000000000000..01a82299682d
--- /dev/null
+++ b/drawinglayer/source/primitive2d/pagepreviewprimitive2d.cxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pagepreviewprimitive2d.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PagePreviewPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence xRetval;
+ Primitive2DSequence aContent(getChildren());
+
+ if(aContent.hasElements()
+ && basegfx::fTools::more(getContentWidth(), 0.0)
+ && basegfx::fTools::more(getContentHeight(), 0.0))
+ {
+ // the decomposed matrix will be needed
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ getTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ if(basegfx::fTools::more(aScale.getX(), 0.0) && basegfx::fTools::more(aScale.getY(), 0.0))
+ {
+ // check if content overlaps with tageted size and needs to be embedded with a
+ // clipping primitive
+ const basegfx::B2DRange aRealContentRange(getB2DRangeFromPrimitive2DSequence(aContent, rViewInformation));
+ const basegfx::B2DRange aAllowedContentRange(0.0, 0.0, getContentWidth(), getContentHeight());
+
+ if(!aAllowedContentRange.isInside(aRealContentRange))
+ {
+ const Primitive2DReference xReferenceA(new MaskPrimitive2D(basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aAllowedContentRange)), aContent));
+ aContent = Primitive2DSequence(&xReferenceA, 1);
+ }
+
+ // create a mapping from content to object.
+ basegfx::B2DHomMatrix aPageTrans;
+
+ if(getKeepAspectRatio())
+ {
+ // #i101075# when keeping the aspect ratio is wanted, it is necessary to calculate
+ // an equidistant scaling in X and Y and a corresponding translation to
+ // center the output. Calculate needed scale factors
+ const double fScaleX(aScale.getX() / getContentWidth());
+ const double fScaleY(aScale.getY() / getContentHeight());
+
+ // to keep the aspect, use the smaller scale and adapt missing size by translation
+ if(fScaleX < fScaleY)
+ {
+ // height needs to be adapted
+ const double fNeededHeight(aScale.getY() / fScaleX);
+ const double fSpaceToAdd(fNeededHeight - getContentHeight());
+
+ aPageTrans.translate(0.0, fSpaceToAdd * 0.5);
+ aPageTrans.scale(fScaleX, aScale.getY() / fNeededHeight);
+ }
+ else
+ {
+ // width needs to be adapted
+ const double fNeededWidth(aScale.getX() / fScaleY);
+ const double fSpaceToAdd(fNeededWidth - getContentWidth());
+
+ aPageTrans.translate(fSpaceToAdd * 0.5, 0.0);
+ aPageTrans.scale(aScale.getX() / fNeededWidth, fScaleY);
+ }
+
+ // add the missing object transformation aspects
+ aPageTrans.shearX(fShearX);
+ aPageTrans.rotate(fRotate);
+ aPageTrans.translate(aTranslate.getX(), aTranslate.getY());
+ }
+ else
+ {
+ // completely scale to PageObject size. Scale to unit size.
+ aPageTrans.scale(1.0/ getContentWidth(), 1.0 / getContentHeight());
+
+ // apply object matrix
+ aPageTrans *= getTransform();
+ }
+
+ // embed in necessary transformation to map from SdrPage to SdrPageObject
+ const Primitive2DReference xReferenceB(new TransformPrimitive2D(aPageTrans, aContent));
+ xRetval = Primitive2DSequence(&xReferenceB, 1);
+ }
+ }
+
+ return xRetval;
+ }
+
+ PagePreviewPrimitive2D::PagePreviewPrimitive2D(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxDrawPage,
+ const basegfx::B2DHomMatrix& rTransform,
+ double fContentWidth,
+ double fContentHeight,
+ const Primitive2DSequence& rChildren,
+ bool bKeepAspectRatio)
+ : GroupPrimitive2D(rChildren),
+ mxDrawPage(rxDrawPage),
+ maTransform(rTransform),
+ mfContentWidth(fContentWidth),
+ mfContentHeight(fContentHeight),
+ mbKeepAspectRatio(bKeepAspectRatio)
+ {
+ }
+
+ bool PagePreviewPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const PagePreviewPrimitive2D& rCompare = static_cast< const PagePreviewPrimitive2D& >(rPrimitive);
+
+ return (getXDrawPage() == rCompare.getXDrawPage()
+ && getTransform() == rCompare.getTransform()
+ && getContentWidth() == rCompare.getContentWidth()
+ && getContentHeight() == rCompare.getContentHeight()
+ && getKeepAspectRatio() == rCompare.getKeepAspectRatio());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PagePreviewPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation`*/) const
+ {
+ // nothing is allowed to stick out of a PagePreviewPrimitive, thus we
+ // can quickly deliver our range here
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(getTransform());
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PagePreviewPrimitive2D, PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/pointarrayprimitive2d.cxx b/drawinglayer/source/primitive2d/pointarrayprimitive2d.cxx
new file mode 100644
index 000000000000..d144fd7030e6
--- /dev/null
+++ b/drawinglayer/source/primitive2d/pointarrayprimitive2d.cxx
@@ -0,0 +1,101 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pointarrayprimitive2d.cxx,v $
+ *
+ * $Revision: 1.3 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ PointArrayPrimitive2D::PointArrayPrimitive2D(
+ const std::vector< basegfx::B2DPoint >& rPositions,
+ const basegfx::BColor& rRGBColor)
+ : BasePrimitive2D(),
+ maPositions(rPositions),
+ maRGBColor(rRGBColor),
+ maB2DRange()
+ {
+ }
+
+ bool PointArrayPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PointArrayPrimitive2D& rCompare = (PointArrayPrimitive2D&)rPrimitive;
+
+ return (getPositions() == rCompare.getPositions()
+ && getRGBColor() == rCompare.getRGBColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PointArrayPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ if(maB2DRange.isEmpty())
+ {
+ basegfx::B2DRange aNewRange;
+
+ // get the basic range from the position vector
+ for(std::vector< basegfx::B2DPoint >::const_iterator aIter(getPositions().begin()); aIter != getPositions().end(); aIter++)
+ {
+ aNewRange.expand(*aIter);
+ }
+
+ // assign to buffered value
+ const_cast< PointArrayPrimitive2D* >(this)->maB2DRange = aNewRange;
+ }
+
+ return maB2DRange;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PointArrayPrimitive2D, PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
new file mode 100644
index 000000000000..b5212da54688
--- /dev/null
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -0,0 +1,633 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: polygonprimitive2d.cxx,v $
+ *
+ * $Revision: 1.12 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ PolygonHairlinePrimitive2D::PolygonHairlinePrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const basegfx::BColor& rBColor)
+ : BasePrimitive2D(),
+ maPolygon(rPolygon),
+ maBColor(rBColor)
+ {
+ }
+
+ bool PolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolygonHairlinePrimitive2D& rCompare = (PolygonHairlinePrimitive2D&)rPrimitive;
+
+ return (getB2DPolygon() == rCompare.getB2DPolygon()
+ && getBColor() == rCompare.getBColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // this is a hairline, thus the line width is view-dependent. Get range of polygon
+ // as base size
+ basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange());
+
+ if(!aRetval.isEmpty())
+ {
+ // Calculate view-dependent hairline width
+ const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0));
+ const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5);
+
+ if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0))
+ {
+ aRetval.grow(fDiscreteHalfLineWidth);
+ }
+ }
+
+ // return range
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolygonMarkerPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // calculate logic DashLength
+ const basegfx::B2DVector aDashVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(getDiscreteDashLength(), 0.0));
+ const double fLogicDashLength(aDashVector.getX());
+
+ if(fLogicDashLength > 0.0 && !getRGBColorA().equal(getRGBColorB()))
+ {
+ // apply dashing; get line and gap snippets
+ ::std::vector< double > aDash;
+ basegfx::B2DPolyPolygon aDashedPolyPolyA;
+ basegfx::B2DPolyPolygon aDashedPolyPolyB;
+
+ aDash.push_back(fLogicDashLength);
+ aDash.push_back(fLogicDashLength);
+ basegfx::tools::applyLineDashing(getB2DPolygon(), aDash, &aDashedPolyPolyA, &aDashedPolyPolyB, 2.0 * fLogicDashLength);
+
+ // prepare return value
+ Primitive2DSequence aRetval(2);
+
+ aRetval[0] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyA, getRGBColorA()));
+ aRetval[1] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyB, getRGBColorB()));
+
+ return aRetval;
+ }
+ else
+ {
+ const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(getB2DPolygon(), getRGBColorA()));
+ return Primitive2DSequence(&xRef, 1L);
+ }
+ }
+
+ PolygonMarkerPrimitive2D::PolygonMarkerPrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const basegfx::BColor& rRGBColorA,
+ const basegfx::BColor& rRGBColorB,
+ double fDiscreteDashLength)
+ : BasePrimitive2D(),
+ maPolygon(rPolygon),
+ maRGBColorA(rRGBColorA),
+ maRGBColorB(rRGBColorB),
+ mfDiscreteDashLength(fDiscreteDashLength),
+ maLastInverseObjectToViewTransformation()
+ {
+ }
+
+ bool PolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolygonMarkerPrimitive2D& rCompare = (PolygonMarkerPrimitive2D&)rPrimitive;
+
+ return (getB2DPolygon() == rCompare.getB2DPolygon()
+ && getRGBColorA() == rCompare.getRGBColorA()
+ && getRGBColorB() == rCompare.getRGBColorB()
+ && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // this is a hairline, thus the line width is view-dependent. Get range of polygon
+ // as base size
+ basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange());
+
+ if(!aRetval.isEmpty())
+ {
+ // Calculate view-dependent hairline width
+ const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0));
+ const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5);
+
+ if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0))
+ {
+ aRetval.grow(fDiscreteHalfLineWidth);
+ }
+ }
+
+ // return range
+ return aRetval;
+ }
+
+ Primitive2DSequence PolygonMarkerPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bool bNeedNewDecomposition(false);
+
+ if(getLocalDecomposition().hasElements())
+ {
+ if(rViewInformation.getInverseObjectToViewTransformation() != maLastInverseObjectToViewTransformation)
+ {
+ bNeedNewDecomposition = true;
+ }
+ }
+
+ if(bNeedNewDecomposition)
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< PolygonMarkerPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember last used InverseObjectToViewTransformation
+ PolygonMarkerPrimitive2D* pThat = const_cast< PolygonMarkerPrimitive2D* >(this);
+ pThat->maLastInverseObjectToViewTransformation = rViewInformation.getInverseObjectToViewTransformation();
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYGONMARKERPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolygonStrokePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ if(getB2DPolygon().count())
+ {
+ // #i102241# try to simplify before usage
+ const basegfx::B2DPolygon aB2DPolygon(basegfx::tools::simplifyCurveSegments(getB2DPolygon()));
+ basegfx::B2DPolyPolygon aHairLinePolyPolygon;
+
+ if(0.0 == getStrokeAttribute().getFullDotDashLen())
+ {
+ // no line dashing, just copy
+ aHairLinePolyPolygon.append(aB2DPolygon);
+ }
+ else
+ {
+ // apply LineStyle
+ basegfx::tools::applyLineDashing(aB2DPolygon, getStrokeAttribute().getDotDashArray(), &aHairLinePolyPolygon, 0, getStrokeAttribute().getFullDotDashLen());
+ }
+
+ const sal_uInt32 nCount(aHairLinePolyPolygon.count());
+
+ if(getLineAttribute().getWidth())
+ {
+ // create fat line data
+ const double fHalfLineWidth(getLineAttribute().getWidth() / 2.0);
+ const basegfx::B2DLineJoin aLineJoin(getLineAttribute().getLineJoin());
+ basegfx::B2DPolyPolygon aAreaPolyPolygon;
+
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ // New version of createAreaGeometry; now creates bezier polygons
+ aAreaPolyPolygon.append(basegfx::tools::createAreaGeometry(
+ aHairLinePolyPolygon.getB2DPolygon(a), fHalfLineWidth, aLineJoin));
+ }
+
+ // prepare return value
+ Primitive2DSequence aRetval(aAreaPolyPolygon.count());
+
+ // create primitive
+ for(sal_uInt32 b(0L); b < aAreaPolyPolygon.count(); b++)
+ {
+ // put into single polyPolygon primitives to make clear that this is NOT meant
+ // to be painted as a single PolyPolygon (XORed as fill rule). Alternatively, a
+ // melting process may be used here one day.
+ const basegfx::B2DPolyPolygon aNewPolyPolygon(aAreaPolyPolygon.getB2DPolygon(b));
+ static bool bTestByUsingRandomColor(false);
+ const basegfx::BColor aColor(bTestByUsingRandomColor
+ ? basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)
+ : getLineAttribute().getColor());
+ const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(aNewPolyPolygon, aColor));
+ aRetval[b] = xRef;
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ // prepare return value
+ const Primitive2DReference xRef(new PolyPolygonHairlinePrimitive2D(aHairLinePolyPolygon, getLineAttribute().getColor()));
+ return Primitive2DSequence(&xRef, 1);
+ }
+ }
+ else
+ {
+ return Primitive2DSequence();
+ }
+ }
+
+ PolygonStrokePrimitive2D::PolygonStrokePrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::StrokeAttribute& rStrokeAttribute)
+ : BasePrimitive2D(),
+ maPolygon(rPolygon),
+ maLineAttribute(rLineAttribute),
+ maStrokeAttribute(rStrokeAttribute)
+ {
+ }
+
+ PolygonStrokePrimitive2D::PolygonStrokePrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const attribute::LineAttribute& rLineAttribute)
+ : BasePrimitive2D(),
+ maPolygon(rPolygon),
+ maLineAttribute(rLineAttribute),
+ maStrokeAttribute()
+ {
+ }
+
+ bool PolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolygonStrokePrimitive2D& rCompare = (PolygonStrokePrimitive2D&)rPrimitive;
+
+ return (getB2DPolygon() == rCompare.getB2DPolygon()
+ && getLineAttribute() == rCompare.getLineAttribute()
+ && getStrokeAttribute() == rCompare.getStrokeAttribute());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval;
+
+ if(getLineAttribute().getWidth())
+ {
+ if(basegfx::B2DLINEJOIN_MITER == getLineAttribute().getLineJoin())
+ {
+ // if line is mitered, use parent call since mitered line
+ // geometry may use more space than the geometry grown by half line width
+ aRetval = BasePrimitive2D::getB2DRange(rViewInformation);
+ }
+ else
+ {
+ // for all other B2DLINEJOIN_* get the range from the base geometry
+ // and expand by half the line width
+ aRetval = getB2DPolygon().getB2DRange();
+ aRetval.grow(getLineAttribute().getWidth() * 0.5);
+ }
+ }
+ else
+ {
+ // this is a hairline, thus the line width is view-dependent. Get range of polygon
+ // as base size
+ aRetval = getB2DPolygon().getB2DRange();
+
+ if(!aRetval.isEmpty())
+ {
+ // Calculate view-dependent hairline width
+ const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0));
+ const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5);
+
+ if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0))
+ {
+ aRetval.grow(fDiscreteHalfLineWidth);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolygonWavePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence aRetval;
+
+ if(getB2DPolygon().count())
+ {
+ const bool bHasWidth(!basegfx::fTools::equalZero(getWaveWidth()));
+ const bool bHasHeight(!basegfx::fTools::equalZero(getWaveHeight()));
+
+ if(bHasWidth && bHasHeight)
+ {
+ // create waveline curve
+ const basegfx::B2DPolygon aWaveline(basegfx::tools::createWaveline(getB2DPolygon(), getWaveWidth(), getWaveHeight()));
+ const Primitive2DReference xRef(new PolygonStrokePrimitive2D(aWaveline, getLineAttribute(), getStrokeAttribute()));
+ aRetval = Primitive2DSequence(&xRef, 1);
+ }
+ else
+ {
+ // flat waveline, decompose to simple line primitive
+ const Primitive2DReference xRef(new PolygonStrokePrimitive2D(getB2DPolygon(), getLineAttribute(), getStrokeAttribute()));
+ aRetval = Primitive2DSequence(&xRef, 1);
+ }
+ }
+
+ return aRetval;
+ }
+
+ PolygonWavePrimitive2D::PolygonWavePrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::StrokeAttribute& rStrokeAttribute,
+ double fWaveWidth,
+ double fWaveHeight)
+ : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute),
+ mfWaveWidth(fWaveWidth),
+ mfWaveHeight(fWaveHeight)
+ {
+ if(mfWaveWidth < 0.0)
+ {
+ mfWaveWidth = 0.0;
+ }
+
+ if(mfWaveHeight < 0.0)
+ {
+ mfWaveHeight = 0.0;
+ }
+ }
+
+ PolygonWavePrimitive2D::PolygonWavePrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ double fWaveWidth,
+ double fWaveHeight)
+ : PolygonStrokePrimitive2D(rPolygon, rLineAttribute),
+ mfWaveWidth(fWaveWidth),
+ mfWaveHeight(fWaveHeight)
+ {
+ if(mfWaveWidth < 0.0)
+ {
+ mfWaveWidth = 0.0;
+ }
+
+ if(mfWaveHeight < 0.0)
+ {
+ mfWaveHeight = 0.0;
+ }
+ }
+
+ bool PolygonWavePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(PolygonStrokePrimitive2D::operator==(rPrimitive))
+ {
+ const PolygonWavePrimitive2D& rCompare = (PolygonWavePrimitive2D&)rPrimitive;
+
+ return (getWaveWidth() == rCompare.getWaveWidth()
+ && getWaveHeight() == rCompare.getWaveHeight());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolygonWavePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // get range of parent
+ basegfx::B2DRange aRetval(PolygonStrokePrimitive2D::getB2DRange(rViewInformation));
+
+ // if WaveHeight, grow by it
+ if(basegfx::fTools::more(getWaveHeight(), 0.0))
+ {
+ aRetval.grow(getWaveHeight());
+ }
+
+ // if line width, grow by it
+ if(basegfx::fTools::more(getLineAttribute().getWidth(), 0.0))
+ {
+ aRetval.grow(getLineAttribute().getWidth() * 0.5);
+ }
+
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolygonWavePrimitive2D, PRIMITIVE2D_ID_POLYGONWAVEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolygonStrokeArrowPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // copy local polygon, it may be changed
+ basegfx::B2DPolygon aLocalPolygon(getB2DPolygon());
+ basegfx::B2DPolyPolygon aArrowA;
+ basegfx::B2DPolyPolygon aArrowB;
+
+ if(!aLocalPolygon.isClosed())
+ {
+ // apply arrows
+ const double fPolyLength(basegfx::tools::getLength(aLocalPolygon));
+ double fStart(0.0);
+ double fEnd(0.0);
+
+ if(getStart().isActive())
+ {
+ // create start arrow primitive and consume
+ aArrowA = basegfx::tools::createAreaGeometryForLineStartEnd(
+ aLocalPolygon, getStart().getB2DPolyPolygon(), true, getStart().getWidth(),
+ fPolyLength, getStart().isCentered() ? 0.5 : 0.0, &fStart);
+
+ // create some overlapping
+ fStart *= 0.8;
+ }
+
+ if(getEnd().isActive())
+ {
+ // create end arrow primitive and consume
+ aArrowB = basegfx::tools::createAreaGeometryForLineStartEnd(
+ aLocalPolygon, getEnd().getB2DPolyPolygon(), false, getEnd().getWidth(),
+ fPolyLength, getEnd().isCentered() ? 0.5 : 0.0, &fEnd);
+
+ // create some overlapping
+ fEnd *= 0.8;
+ }
+
+ if(0.0 != fStart || 0.0 != fEnd)
+ {
+ // build new poly, consume something from old poly
+ aLocalPolygon = basegfx::tools::getSnippetAbsolute(aLocalPolygon, fStart, fPolyLength - fEnd, fPolyLength);
+ }
+ }
+
+ // prepare return value
+ Primitive2DSequence aRetval(1L + (aArrowA.count() ? 1L : 0L) + (aArrowB.count() ? 1L : 0L));
+ sal_uInt32 nInd(0L);
+
+ // add shaft
+ const Primitive2DReference xRefShaft(new PolygonStrokePrimitive2D(aLocalPolygon, getLineAttribute(), getStrokeAttribute()));
+ aRetval[nInd++] = xRefShaft;
+
+ if(aArrowA.count())
+ {
+ const Primitive2DReference xRefA(new PolyPolygonColorPrimitive2D(aArrowA, getLineAttribute().getColor()));
+ aRetval[nInd++] = xRefA;
+ }
+
+ if(aArrowB.count())
+ {
+ const Primitive2DReference xRefB(new PolyPolygonColorPrimitive2D(aArrowB, getLineAttribute().getColor()));
+ aRetval[nInd++] = xRefB;
+ }
+
+ return aRetval;
+ }
+
+ PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::StrokeAttribute& rStrokeAttribute,
+ const attribute::LineStartEndAttribute& rStart,
+ const attribute::LineStartEndAttribute& rEnd)
+ : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute),
+ maStart(rStart),
+ maEnd(rEnd)
+ {
+ }
+
+ PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D(
+ const basegfx::B2DPolygon& rPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::LineStartEndAttribute& rStart,
+ const attribute::LineStartEndAttribute& rEnd)
+ : PolygonStrokePrimitive2D(rPolygon, rLineAttribute),
+ maStart(rStart),
+ maEnd(rEnd)
+ {
+ }
+
+ bool PolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(PolygonStrokePrimitive2D::operator==(rPrimitive))
+ {
+ const PolygonStrokeArrowPrimitive2D& rCompare = (PolygonStrokeArrowPrimitive2D&)rPrimitive;
+
+ return (getStart() == rCompare.getStart()
+ && getEnd() == rCompare.getEnd());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval;
+
+ if(getStart().isActive() || getEnd().isActive())
+ {
+ // use decomposition when line start/end is used
+ return BasePrimitive2D::getB2DRange(rViewInformation);
+ }
+ else
+ {
+ // get range from parent
+ return PolygonStrokePrimitive2D::getB2DRange(rViewInformation);
+ }
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx
new file mode 100644
index 000000000000..9dd14aeb11e3
--- /dev/null
+++ b/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx
@@ -0,0 +1,548 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: polypolygonprimitive2d.cxx,v $
+ *
+ * $Revision: 1.8 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonHairlinePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ if(nCount)
+ {
+ Primitive2DSequence aRetval(nCount);
+
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ aRetval[a] = Primitive2DReference(new PolygonHairlinePrimitive2D(aPolyPolygon.getB2DPolygon(a), getBColor()));
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return Primitive2DSequence();
+ }
+ }
+
+ PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor)
+ : BasePrimitive2D(),
+ maPolyPolygon(rPolyPolygon),
+ maBColor(rBColor)
+ {
+ }
+
+ bool PolyPolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonHairlinePrimitive2D& rCompare = (PolyPolygonHairlinePrimitive2D&)rPrimitive;
+
+ return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
+ && getBColor() == rCompare.getBColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolyPolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return range
+ return basegfx::tools::getRange(getB2DPolyPolygon());
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonMarkerPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ if(nCount)
+ {
+ Primitive2DSequence aRetval(nCount);
+
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ aRetval[a] = Primitive2DReference(new PolygonMarkerPrimitive2D(aPolyPolygon.getB2DPolygon(a), getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return Primitive2DSequence();
+ }
+ }
+
+ PolyPolygonMarkerPrimitive2D::PolyPolygonMarkerPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rRGBColorA,
+ const basegfx::BColor& rRGBColorB,
+ double fDiscreteDashLength)
+ : BasePrimitive2D(),
+ maPolyPolygon(rPolyPolygon),
+ maRGBColorA(rRGBColorA),
+ maRGBColorB(rRGBColorB),
+ mfDiscreteDashLength(fDiscreteDashLength)
+ {
+ }
+
+ bool PolyPolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonMarkerPrimitive2D& rCompare = (PolyPolygonMarkerPrimitive2D&)rPrimitive;
+
+ return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
+ && getRGBColorA() == rCompare.getRGBColorA()
+ && getRGBColorB() == rCompare.getRGBColorB()
+ && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolyPolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return range
+ return basegfx::tools::getRange(getB2DPolyPolygon());
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONMARKERPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonStrokePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ if(nCount)
+ {
+ Primitive2DSequence aRetval(nCount);
+
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ aRetval[a] = Primitive2DReference(new PolygonStrokePrimitive2D(aPolyPolygon.getB2DPolygon(a), getLineAttribute(), getStrokeAttribute()));
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return Primitive2DSequence();
+ }
+ }
+
+ PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::StrokeAttribute& rStrokeAttribute)
+ : BasePrimitive2D(),
+ maPolyPolygon(rPolyPolygon),
+ maLineAttribute(rLineAttribute),
+ maStrokeAttribute(rStrokeAttribute)
+ {
+ }
+
+ PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const attribute::LineAttribute& rLineAttribute)
+ : BasePrimitive2D(),
+ maPolyPolygon(rPolyPolygon),
+ maLineAttribute(rLineAttribute),
+ maStrokeAttribute()
+ {
+ }
+
+ bool PolyPolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonStrokePrimitive2D& rCompare = (PolyPolygonStrokePrimitive2D&)rPrimitive;
+
+ return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
+ && getLineAttribute() == rCompare.getLineAttribute()
+ && getStrokeAttribute() == rCompare.getStrokeAttribute());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolyPolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // get range of it (subdivided)
+ basegfx::B2DRange aRetval(basegfx::tools::getRange(getB2DPolyPolygon()));
+
+ // if width, grow by line width
+ if(getLineAttribute().getWidth())
+ {
+ aRetval.grow(getLineAttribute().getWidth() / 2.0);
+ }
+
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonStrokeArrowPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ if(nCount)
+ {
+ Primitive2DSequence aRetval(nCount);
+
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(a));
+
+ if(aPolygon.isClosed())
+ {
+ // no need for PolygonStrokeArrowPrimitive2D when polygon is closed
+ aRetval[a] = Primitive2DReference(new PolygonStrokePrimitive2D(aPolygon, getLineAttribute(), getStrokeAttribute()));
+ }
+ else
+ {
+ aRetval[a] = Primitive2DReference(new PolygonStrokeArrowPrimitive2D(aPolygon, getLineAttribute(), getStrokeAttribute(), getStart(), getEnd()));
+ }
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return Primitive2DSequence();
+ }
+ }
+
+ PolyPolygonStrokeArrowPrimitive2D::PolyPolygonStrokeArrowPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::StrokeAttribute& rStrokeAttribute,
+ const attribute::LineStartEndAttribute& rStart,
+ const attribute::LineStartEndAttribute& rEnd)
+ : PolyPolygonStrokePrimitive2D(rPolyPolygon, rLineAttribute, rStrokeAttribute),
+ maStart(rStart),
+ maEnd(rEnd)
+ {
+ }
+
+ PolyPolygonStrokeArrowPrimitive2D::PolyPolygonStrokeArrowPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const attribute::LineAttribute& rLineAttribute,
+ const attribute::LineStartEndAttribute& rStart,
+ const attribute::LineStartEndAttribute& rEnd)
+ : PolyPolygonStrokePrimitive2D(rPolyPolygon, rLineAttribute),
+ maStart(rStart),
+ maEnd(rEnd)
+ {
+ }
+
+ bool PolyPolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(PolyPolygonStrokePrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonStrokeArrowPrimitive2D& rCompare = (PolyPolygonStrokeArrowPrimitive2D&)rPrimitive;
+
+ return (getStart() == rCompare.getStart()
+ && getEnd() == rCompare.getEnd());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolyPolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval;
+
+ if(getStart().isActive() || getEnd().isActive())
+ {
+ // use decomposition when line start/end is used
+ return BasePrimitive2D::getB2DRange(rViewInformation);
+ }
+ else
+ {
+ // get range from parent
+ return PolyPolygonStrokePrimitive2D::getB2DRange(rViewInformation);
+ }
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEARROWPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ PolyPolygonColorPrimitive2D::PolyPolygonColorPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rBColor)
+ : BasePrimitive2D(),
+ maPolyPolygon(rPolyPolygon),
+ maBColor(rBColor)
+ {
+ }
+
+ bool PolyPolygonColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonColorPrimitive2D& rCompare = (PolyPolygonColorPrimitive2D&)rPrimitive;
+
+ return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
+ && getBColor() == rCompare.getBColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange PolyPolygonColorPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // return range
+ return basegfx::tools::getRange(getB2DPolyPolygon());
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonColorPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonGradientPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // create SubSequence with FillGradientPrimitive2D
+ const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
+ FillGradientPrimitive2D* pNewGradient = new FillGradientPrimitive2D(aPolyPolygonRange, getFillGradient());
+ const Primitive2DReference xSubRef(pNewGradient);
+ const Primitive2DSequence aSubSequence(&xSubRef, 1L);
+
+ // create mask primitive
+ MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
+ const Primitive2DReference xRef(pNewMask);
+ return Primitive2DSequence(&xRef, 1L);
+ }
+
+ PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rBColor,
+ const attribute::FillGradientAttribute& rFillGradient)
+ : PolyPolygonColorPrimitive2D(rPolyPolygon, rBColor),
+ maFillGradient(rFillGradient)
+ {
+ }
+
+ bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(PolyPolygonColorPrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonGradientPrimitive2D& rCompare = (PolyPolygonGradientPrimitive2D&)rPrimitive;
+
+ return (getFillGradient() == rCompare.getFillGradient());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonGradientPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonHatchPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // create SubSequence with FillHatchPrimitive2D
+ const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
+ FillHatchPrimitive2D* pNewHatch = new FillHatchPrimitive2D(aPolyPolygonRange, getBColor(), getFillHatch());
+ const Primitive2DReference xSubRef(pNewHatch);
+ const Primitive2DSequence aSubSequence(&xSubRef, 1L);
+
+ // create mask primitive
+ MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
+ const Primitive2DReference xRef(pNewMask);
+ return Primitive2DSequence(&xRef, 1L);
+ }
+
+ PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rBColor,
+ const attribute::FillHatchAttribute& rFillHatch)
+ : PolyPolygonColorPrimitive2D(rPolyPolygon, rBColor),
+ maFillHatch(rFillHatch)
+ {
+ }
+
+ bool PolyPolygonHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(PolyPolygonColorPrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonHatchPrimitive2D& rCompare = (PolyPolygonHatchPrimitive2D&)rPrimitive;
+
+ return (getFillHatch() == rCompare.getFillHatch());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonHatchPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence PolyPolygonBitmapPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // create SubSequence with FillBitmapPrimitive2D
+ const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
+ basegfx::B2DHomMatrix aNewObjectTransform;
+ aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth());
+ aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight());
+ aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX());
+ aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY());
+ FillBitmapPrimitive2D* pNewBitmap = new FillBitmapPrimitive2D(aNewObjectTransform, getFillBitmap());
+ const Primitive2DReference xSubRef(pNewBitmap);
+ const Primitive2DSequence aSubSequence(&xSubRef, 1L);
+
+ // create mask primitive
+ MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
+ const Primitive2DReference xRef(pNewMask);
+ return Primitive2DSequence(&xRef, 1L);
+ }
+
+ PolyPolygonBitmapPrimitive2D::PolyPolygonBitmapPrimitive2D(
+ const basegfx::B2DPolyPolygon& rPolyPolygon,
+ const basegfx::BColor& rBColor,
+ const attribute::FillBitmapAttribute& rFillBitmap)
+ : PolyPolygonColorPrimitive2D(rPolyPolygon, rBColor),
+ maFillBitmap(rFillBitmap)
+ {
+ }
+
+ bool PolyPolygonBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(PolyPolygonColorPrimitive2D::operator==(rPrimitive))
+ {
+ const PolyPolygonBitmapPrimitive2D& rCompare = (PolyPolygonBitmapPrimitive2D&)rPrimitive;
+
+ return (getFillBitmap() == rCompare.getFillBitmap());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(PolyPolygonBitmapPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/primitivetools2d.cxx b/drawinglayer/source/primitive2d/primitivetools2d.cxx
new file mode 100644
index 000000000000..d288a697d729
--- /dev/null
+++ b/drawinglayer/source/primitive2d/primitivetools2d.cxx
@@ -0,0 +1,106 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: baseprimitive2d.cxx,v $
+ *
+ * $Revision: 1.6 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/primitivetools2d.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence DiscreteMetricDependentPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // get the current DiscreteUnit
+ const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength());
+
+ if(getLocalDecomposition().hasElements() && !basegfx::fTools::equal(fDiscreteUnit, getDiscreteUnit()))
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< DiscreteMetricDependentPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember new valid DiscreteUnit
+ const_cast< DiscreteMetricDependentPrimitive2D* >(this)->mfDiscreteUnit = fDiscreteUnit;
+ }
+
+ // call base implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence ViewportDependentPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // get the current Viewport
+ const basegfx::B2DRange& rViewport = rViewInformation.getViewport();
+
+ if(getLocalDecomposition().hasElements() && !rViewport.equal(getViewport()))
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< ViewportDependentPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember new valid DiscreteUnit
+ const_cast< ViewportDependentPrimitive2D* >(this)->maViewport = rViewport;
+ }
+
+ // call base implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
new file mode 100644
index 000000000000..ad36a40ea996
--- /dev/null
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -0,0 +1,484 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sceneprimitive2d.cxx,v $
+ *
+ * $Revision: 1.16 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/sceneprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/processor3d/zbufferprocessor3d.hxx>
+#include <drawinglayer/processor3d/shadow3dextractor.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <drawinglayer/processor3d/geometry2dextractor.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ bool ScenePrimitive2D::impGetShadow3D(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // create on demand
+ if(!mbShadow3DChecked && getChildren3D().hasElements())
+ {
+ basegfx::B3DVector aLightNormal;
+ const double fShadowSlant(getSdrSceneAttribute().getShadowSlant());
+ const basegfx::B3DRange aScene3DRange(primitive3d::getB3DRangeFromPrimitive3DSequence(getChildren3D(), getViewInformation3D()));
+
+ if(maSdrLightingAttribute.getLightVector().size())
+ {
+ // get light normal from first light and normalize
+ aLightNormal = maSdrLightingAttribute.getLightVector()[0].getDirection();
+ aLightNormal.normalize();
+ }
+
+ // create shadow extraction processor
+ processor3d::Shadow3DExtractingProcessor aShadowProcessor(
+ getViewInformation3D(),
+ getObjectTransformation(),
+ aLightNormal,
+ fShadowSlant,
+ aScene3DRange);
+
+ // process local primitives
+ aShadowProcessor.process(getChildren3D());
+
+ // fetch result and set checked flag
+ const_cast< ScenePrimitive2D* >(this)->maShadowPrimitives = aShadowProcessor.getPrimitive2DSequence();
+ const_cast< ScenePrimitive2D* >(this)->mbShadow3DChecked = true;
+ }
+
+ // return if there are shadow primitives
+ return maShadowPrimitives.hasElements();
+ }
+
+ void ScenePrimitive2D::calculateDiscreteSizes(
+ const geometry::ViewInformation2D& rViewInformation,
+ basegfx::B2DRange& rDiscreteRange,
+ basegfx::B2DRange& rVisibleDiscreteRange,
+ basegfx::B2DRange& rUnitVisibleRange) const
+ {
+ // use unit range and transform to discrete coordinates
+ rDiscreteRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+ rDiscreteRange.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
+
+ // clip it against discrete Viewport (if set)
+ rVisibleDiscreteRange = rDiscreteRange;
+
+ if(!rViewInformation.getViewport().isEmpty())
+ {
+ rVisibleDiscreteRange.intersect(rViewInformation.getDiscreteViewport());
+ }
+
+ if(rVisibleDiscreteRange.isEmpty())
+ {
+ rUnitVisibleRange = rVisibleDiscreteRange;
+ }
+ else
+ {
+ // create UnitVisibleRange containing unit range values [0.0 .. 1.0] describing
+ // the relative position of rVisibleDiscreteRange inside rDiscreteRange
+ const double fDiscreteScaleFactorX(basegfx::fTools::equalZero(rDiscreteRange.getWidth()) ? 1.0 : 1.0 / rDiscreteRange.getWidth());
+ const double fDiscreteScaleFactorY(basegfx::fTools::equalZero(rDiscreteRange.getHeight()) ? 1.0 : 1.0 / rDiscreteRange.getHeight());
+
+ const double fMinX(basegfx::fTools::equal(rVisibleDiscreteRange.getMinX(), rDiscreteRange.getMinX())
+ ? 0.0
+ : (rVisibleDiscreteRange.getMinX() - rDiscreteRange.getMinX()) * fDiscreteScaleFactorX);
+ const double fMinY(basegfx::fTools::equal(rVisibleDiscreteRange.getMinY(), rDiscreteRange.getMinY())
+ ? 0.0
+ : (rVisibleDiscreteRange.getMinY() - rDiscreteRange.getMinY()) * fDiscreteScaleFactorY);
+
+ const double fMaxX(basegfx::fTools::equal(rVisibleDiscreteRange.getMaxX(), rDiscreteRange.getMaxX())
+ ? 1.0
+ : (rVisibleDiscreteRange.getMaxX() - rDiscreteRange.getMinX()) * fDiscreteScaleFactorX);
+ const double fMaxY(basegfx::fTools::equal(rVisibleDiscreteRange.getMaxY(), rDiscreteRange.getMaxY())
+ ? 1.0
+ : (rVisibleDiscreteRange.getMaxY() - rDiscreteRange.getMinY()) * fDiscreteScaleFactorY);
+
+ rUnitVisibleRange = basegfx::B2DRange(fMinX, fMinY, fMaxX, fMaxY);
+ }
+ }
+
+ Primitive2DSequence ScenePrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+
+ // create 2D shadows from contained 3D primitives. This creates the shadow primitives on demand and tells if
+ // there are some or not. Do this at start, the shadow might still be visible even when the scene is not
+ if(impGetShadow3D(rViewInformation))
+ {
+ // test visibility
+ const basegfx::B2DRange aShadow2DRange(getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
+ const basegfx::B2DRange aViewRange(rViewInformation.getViewport());
+
+ if(aViewRange.isEmpty() || aShadow2DRange.overlaps(aViewRange))
+ {
+ // add extracted 2d shadows (before 3d scene creations itself)
+ aRetval = maShadowPrimitives;
+ }
+ }
+
+ // get the involved ranges (see helper method calculateDiscreteSizes for details)
+ basegfx::B2DRange aDiscreteRange;
+ basegfx::B2DRange aVisibleDiscreteRange;
+ basegfx::B2DRange aUnitVisibleRange;
+ calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
+
+ if(!aVisibleDiscreteRange.isEmpty())
+ {
+ // test if discrete view size (pixel) maybe too big and limit it
+ double fViewSizeX(aVisibleDiscreteRange.getWidth());
+ double fViewSizeY(aVisibleDiscreteRange.getHeight());
+ const double fViewVisibleArea(fViewSizeX * fViewSizeY);
+ const SvtOptionsDrawinglayer aDrawinglayerOpt;
+ const double fMaximumVisibleArea(aDrawinglayerOpt.GetQuadratic3DRenderLimit());
+ double fReduceFactor(1.0);
+
+ if(fViewVisibleArea > fMaximumVisibleArea)
+ {
+ fReduceFactor = sqrt(fMaximumVisibleArea / fViewVisibleArea);
+ fViewSizeX *= fReduceFactor;
+ fViewSizeY *= fReduceFactor;
+ }
+
+ if(rViewInformation.getReducedDisplayQuality())
+ {
+ // when reducing the visualisation is allowed (e.g. an OverlayObject
+ // only needed for dragging), reduce resolution extra
+ // to speed up dragging interactions
+ const double fArea(fViewSizeX * fViewSizeY);
+ double fReducedVisualisationFactor(1.0 / (sqrt(fArea) * (1.0 / 170.0)));
+
+ if(fReducedVisualisationFactor > 1.0)
+ {
+ fReducedVisualisationFactor = 1.0;
+ }
+ else if(fReducedVisualisationFactor < 0.20)
+ {
+ fReducedVisualisationFactor = 0.20;
+ }
+
+ if(fReducedVisualisationFactor != 1.0)
+ {
+ fReduceFactor *= fReducedVisualisationFactor;
+ fViewSizeX *= fReducedVisualisationFactor;
+ fViewSizeY *= fReducedVisualisationFactor;
+ }
+ }
+
+ // calculate logic render size in world coordinates for usage in renderer
+ basegfx::B2DVector aLogicRenderSize(
+ aDiscreteRange.getWidth() * fReduceFactor,
+ aDiscreteRange.getHeight() * fReduceFactor);
+ aLogicRenderSize *= rViewInformation.getInverseObjectToViewTransformation();
+
+ // determine the oversample value
+ static sal_uInt16 nDefaultOversampleValue(3);
+ const sal_uInt16 nOversampleValue(aDrawinglayerOpt.IsAntiAliasing() ? nDefaultOversampleValue : 0);
+
+ // use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process
+ processor3d::ZBufferProcessor3D aZBufferProcessor3D(
+ getViewInformation3D(),
+ rViewInformation,
+ getSdrSceneAttribute(),
+ getSdrLightingAttribute(),
+ aLogicRenderSize.getX(),
+ aLogicRenderSize.getY(),
+ aUnitVisibleRange,
+ nOversampleValue);
+
+ aZBufferProcessor3D.processNonTransparent(getChildren3D());
+ aZBufferProcessor3D.processTransparent(getChildren3D());
+ const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = aZBufferProcessor3D.getBitmapEx();
+ const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
+
+ if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())
+ {
+ // create transform for the created bitmap in discrete coordinates first.
+ basegfx::B2DHomMatrix aNew2DTransform;
+
+ aNew2DTransform.set(0, 0, aVisibleDiscreteRange.getWidth());
+ aNew2DTransform.set(1, 1, aVisibleDiscreteRange.getHeight());
+ aNew2DTransform.set(0, 2, aVisibleDiscreteRange.getMinX());
+ aNew2DTransform.set(1, 2, aVisibleDiscreteRange.getMinY());
+
+ // transform back to world coordinates for usage in primitive creation
+ aNew2DTransform *= rViewInformation.getInverseObjectToViewTransformation();
+
+ // create bitmap primitive and add
+ const Primitive2DReference xRef(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef);
+
+ // test: Allow to add an outline in the debugger when tests are needed
+ static bool bAddOutlineToCreated3DSceneRepresentation(false);
+
+ if(bAddOutlineToCreated3DSceneRepresentation)
+ {
+ basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
+ aOutline.transform(aNew2DTransform);
+ const Primitive2DReference xRef2(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0)));
+ appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef2);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ Primitive2DSequence ScenePrimitive2D::getGeometry2D() const
+ {
+ Primitive2DSequence aRetval;
+
+ // create 2D projected geometry from 3D geometry
+ if(getChildren3D().hasElements())
+ {
+ // create 2D geometry extraction processor
+ processor3d::Geometry2DExtractingProcessor aGeometryProcessor(
+ getViewInformation3D(),
+ getObjectTransformation());
+
+ // process local primitives
+ aGeometryProcessor.process(getChildren3D());
+
+ // fetch result
+ aRetval = aGeometryProcessor.getPrimitive2DSequence();
+ }
+
+ return aRetval;
+ }
+
+ Primitive2DSequence ScenePrimitive2D::getShadow2D(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+
+ // create 2D shadows from contained 3D primitives
+ if(impGetShadow3D(rViewInformation))
+ {
+ // add extracted 2d shadows (before 3d scene creations itself)
+ aRetval = maShadowPrimitives;
+ }
+
+ return aRetval;
+ }
+
+ bool ScenePrimitive2D::tryToCheckLastVisualisationDirectHit(const basegfx::B2DPoint& rLogicHitPoint, bool& o_rResult) const
+ {
+ if(!maOldRenderedBitmap.IsEmpty() && !maOldUnitVisiblePart.isEmpty())
+ {
+ basegfx::B2DHomMatrix aInverseSceneTransform(getObjectTransformation());
+ aInverseSceneTransform.invert();
+ const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rLogicHitPoint);
+
+ if(maOldUnitVisiblePart.isInside(aRelativePoint))
+ {
+ // calculate coordinates relative to visualized part
+ double fDivisorX(maOldUnitVisiblePart.getWidth());
+ double fDivisorY(maOldUnitVisiblePart.getHeight());
+
+ if(basegfx::fTools::equalZero(fDivisorX))
+ {
+ fDivisorX = 1.0;
+ }
+
+ if(basegfx::fTools::equalZero(fDivisorY))
+ {
+ fDivisorY = 1.0;
+ }
+
+ const double fRelativeX((aRelativePoint.getX() - maOldUnitVisiblePart.getMinX()) / fDivisorX);
+ const double fRelativeY((aRelativePoint.getY() - maOldUnitVisiblePart.getMinY()) / fDivisorY);
+
+ // combine with real BitmapSizePixel to get bitmap coordinates
+ const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
+ const sal_Int32 nX(basegfx::fround(fRelativeX * aBitmapSizePixel.Width()));
+ const sal_Int32 nY(basegfx::fround(fRelativeY * aBitmapSizePixel.Height()));
+
+ // try to get a statement about transparency in that pixel
+ o_rResult = (0xff != maOldRenderedBitmap.GetTransparency(nX, nY));
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ScenePrimitive2D::ScenePrimitive2D(
+ const primitive3d::Primitive3DSequence& rxChildren3D,
+ const attribute::SdrSceneAttribute& rSdrSceneAttribute,
+ const attribute::SdrLightingAttribute& rSdrLightingAttribute,
+ const basegfx::B2DHomMatrix& rObjectTransformation,
+ const geometry::ViewInformation3D& rViewInformation3D)
+ : BasePrimitive2D(),
+ mxChildren3D(rxChildren3D),
+ maSdrSceneAttribute(rSdrSceneAttribute),
+ maSdrLightingAttribute(rSdrLightingAttribute),
+ maObjectTransformation(rObjectTransformation),
+ maViewInformation3D(rViewInformation3D),
+ maShadowPrimitives(),
+ mbShadow3DChecked(false),
+ mfOldDiscreteSizeX(0.0),
+ mfOldDiscreteSizeY(0.0),
+ maOldUnitVisiblePart(),
+ maOldRenderedBitmap()
+ {
+ }
+
+ bool ScenePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const ScenePrimitive2D& rCompare = (ScenePrimitive2D&)rPrimitive;
+
+ return (primitive3d::arePrimitive3DSequencesEqual(getChildren3D(), rCompare.getChildren3D())
+ && getSdrSceneAttribute() == rCompare.getSdrSceneAttribute()
+ && getSdrLightingAttribute() == rCompare.getSdrLightingAttribute()
+ && getObjectTransformation() == rCompare.getObjectTransformation()
+ && getViewInformation3D() == rCompare.getViewInformation3D());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange ScenePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // transform unit range to discrete coordinate range
+ basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+ aRetval.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
+
+ // force to discrete expanded bounds (it grows, so expanding works perfectly well)
+ aRetval.expand(basegfx::B2DTuple(floor(aRetval.getMinX()), floor(aRetval.getMinY())));
+ aRetval.expand(basegfx::B2DTuple(ceil(aRetval.getMaxX()), ceil(aRetval.getMaxY())));
+
+ // transform back from discrete (view) to world coordinates
+ aRetval.transform(rViewInformation.getInverseObjectToViewTransformation());
+
+ // expand by evtl. existing shadow primitives
+ if(impGetShadow3D(rViewInformation))
+ {
+ const basegfx::B2DRange aShadow2DRange(getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
+
+ if(!aShadow2DRange.isEmpty())
+ {
+ aRetval.expand(aShadow2DRange);
+ }
+ }
+
+ return aRetval;
+ }
+
+ Primitive2DSequence ScenePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // get the involved ranges (see helper method calculateDiscreteSizes for details)
+ basegfx::B2DRange aDiscreteRange;
+ basegfx::B2DRange aUnitVisibleRange;
+ bool bNeedNewDecomposition(false);
+ bool bDiscreteSizesAreCalculated(false);
+
+ if(getLocalDecomposition().hasElements())
+ {
+ basegfx::B2DRange aVisibleDiscreteRange;
+ calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
+ bDiscreteSizesAreCalculated = true;
+
+ // needs to be painted when the new part is not part of the last
+ // decomposition
+ if(!maOldUnitVisiblePart.isInside(aUnitVisibleRange))
+ {
+ bNeedNewDecomposition = true;
+ }
+
+ // display has changed and cannot be reused when resolution got bigger. It
+ // can be reused when resolution got smaller, though.
+ if(!bNeedNewDecomposition)
+ {
+ if(basegfx::fTools::more(aDiscreteRange.getWidth(), mfOldDiscreteSizeX) ||
+ basegfx::fTools::more(aDiscreteRange.getHeight(), mfOldDiscreteSizeY))
+ {
+ bNeedNewDecomposition = true;
+ }
+ }
+ }
+
+ if(bNeedNewDecomposition)
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< ScenePrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ if(!bDiscreteSizesAreCalculated)
+ {
+ basegfx::B2DRange aVisibleDiscreteRange;
+ calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
+ }
+
+ // remember last used NewDiscreteSize and NewUnitVisiblePart
+ ScenePrimitive2D* pThat = const_cast< ScenePrimitive2D* >(this);
+ pThat->mfOldDiscreteSizeX = aDiscreteRange.getWidth();
+ pThat->mfOldDiscreteSizeY = aDiscreteRange.getHeight();
+ pThat->maOldUnitVisiblePart = aUnitVisibleRange;
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(ScenePrimitive2D, PRIMITIVE2D_ID_SCENEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
new file mode 100644
index 000000000000..5681f7f98d7e
--- /dev/null
+++ b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: shadowprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+#include <basegfx/color/bcolormodifier.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/alphaprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence ShadowPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence aRetval;
+
+ if(getChildren().hasElements())
+ {
+ // create a modifiedColorPrimitive containing the shadow color and the content
+ const basegfx::BColorModifier aBColorModifier(getShadowColor());
+ const Primitive2DReference xRefA(new ModifiedColorPrimitive2D(getChildren(), aBColorModifier));
+ const Primitive2DSequence aSequenceB(&xRefA, 1L);
+
+ // build transformed primitiveVector with shadow offset and add to target
+ const Primitive2DReference xRefB(new TransformPrimitive2D(getShadowTransform(), aSequenceB));
+ aRetval = Primitive2DSequence(&xRefB, 1L);
+ }
+
+ return aRetval;
+ }
+
+ ShadowPrimitive2D::ShadowPrimitive2D(
+ const basegfx::B2DHomMatrix& rShadowTransform,
+ const basegfx::BColor& rShadowColor,
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren),
+ maShadowTransform(rShadowTransform),
+ maShadowColor(rShadowColor)
+ {
+ }
+
+ bool ShadowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const ShadowPrimitive2D& rCompare = static_cast< const ShadowPrimitive2D& >(rPrimitive);
+
+ return (getShadowTransform() == rCompare.getShadowTransform()
+ && getShadowColor() == rCompare.getShadowColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange ShadowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval(getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation));
+ aRetval.transform(getShadowTransform());
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(ShadowPrimitive2D, PRIMITIVE2D_ID_SHADOWPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
new file mode 100644
index 000000000000..191b24dfcbf9
--- /dev/null
+++ b/drawinglayer/source/primitive2d/structuretagprimitive2d.cxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: structuretagprimitive2d.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ StructureTagPrimitive2D::StructureTagPrimitive2D(
+ const vcl::PDFWriter::StructElement& rStructureElement,
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren),
+ maStructureElement(rStructureElement)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(StructureTagPrimitive2D, PRIMITIVE2D_ID_STRUCTURETAGRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
new file mode 100644
index 000000000000..d337950c6c6b
--- /dev/null
+++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx
@@ -0,0 +1,888 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textdecoratedprimitive2d.cxx,v $
+ *
+ * $Revision: 1.12 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/attribute/strokeattribute.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <drawinglayer/primitive2d/texteffectprimitive2d.hxx>
+#include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ void TextDecoratedPortionPrimitive2D::impCreateTextLine(
+ std::vector< Primitive2DReference >& rTarget,
+ basegfx::DecomposedB2DHomMatrixContainer& rDecTrans,
+ const basegfx::B2DHomMatrix &rUnscaledTransform,
+ FontUnderline eLineStyle,
+ double fLineOffset,
+ double fLineHeight,
+ double fLineWidth,
+ const basegfx::BColor& rLineColor) const
+ {
+ bool bDoubleLine(false);
+ bool bWaveLine(false);
+ bool bBoldLine(false);
+ const int* pDotDashArray(0);
+ basegfx::B2DLineJoin eLineJoin(basegfx::B2DLINEJOIN_NONE);
+
+ static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE
+ static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT
+ static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT
+ static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE
+ static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH
+
+ switch(eLineStyle)
+ {
+ default: // case FONT_UNDERLINE_SINGLE:
+ {
+ break;
+ }
+ case FONT_UNDERLINE_DOUBLE:
+ {
+ bDoubleLine = true;
+ break;
+ }
+ case FONT_UNDERLINE_DOTTED:
+ {
+ pDotDashArray = aDottedArray;
+ break;
+ }
+ case FONT_UNDERLINE_DASH:
+ {
+ pDotDashArray = aDashedArray;
+ break;
+ }
+ case FONT_UNDERLINE_LONGDASH:
+ {
+ pDotDashArray = aLongDashArray;
+ break;
+ }
+ case FONT_UNDERLINE_DASHDOT:
+ {
+ pDotDashArray = aDotDashArray;
+ break;
+ }
+ case FONT_UNDERLINE_DASHDOTDOT:
+ {
+ pDotDashArray = aDashDotDotArray;
+ break;
+ }
+ case FONT_UNDERLINE_SMALLWAVE:
+ {
+ bWaveLine = true;
+ break;
+ }
+ case FONT_UNDERLINE_WAVE:
+ {
+ bWaveLine = true;
+ break;
+ }
+ case FONT_UNDERLINE_DOUBLEWAVE:
+ {
+ bDoubleLine = true;
+ bWaveLine = true;
+ break;
+ }
+ case FONT_UNDERLINE_BOLD:
+ {
+ bBoldLine = true;
+ break;
+ }
+ case FONT_UNDERLINE_BOLDDOTTED:
+ {
+ bBoldLine = true;
+ pDotDashArray = aDottedArray;
+ break;
+ }
+ case FONT_UNDERLINE_BOLDDASH:
+ {
+ bBoldLine = true;
+ pDotDashArray = aDashedArray;
+ break;
+ }
+ case FONT_UNDERLINE_BOLDLONGDASH:
+ {
+ bBoldLine = true;
+ pDotDashArray = aLongDashArray;
+ break;
+ }
+ case FONT_UNDERLINE_BOLDDASHDOT:
+ {
+ bBoldLine = true;
+ pDotDashArray = aDotDashArray;
+ break;
+ }
+ case FONT_UNDERLINE_BOLDDASHDOTDOT:
+ {
+ bBoldLine = true;
+ pDotDashArray = aDashDotDotArray;
+ break;
+ }
+ case FONT_UNDERLINE_BOLDWAVE:
+ {
+ bWaveLine = true;
+ bBoldLine = true;
+ break;
+ }
+ }
+
+ if(bBoldLine)
+ {
+ fLineHeight *= 2.0;
+ }
+
+ if(bDoubleLine)
+ {
+ fLineOffset -= 0.50 * fLineHeight;
+ fLineHeight *= 0.64;
+ }
+
+ if(bWaveLine)
+ {
+ eLineJoin = basegfx::B2DLINEJOIN_ROUND;
+ fLineHeight *= 0.25;
+ }
+
+ // prepare Line and Stroke Attributes
+ const attribute::LineAttribute aLineAttribute(rLineColor, fLineHeight, eLineJoin);
+ attribute::StrokeAttribute aStrokeAttribute;
+
+ if(pDotDashArray)
+ {
+ ::std::vector< double > aDoubleArray;
+
+ for(const int* p = pDotDashArray; *p; ++p)
+ {
+ aDoubleArray.push_back((double)(*p) * fLineHeight);
+ }
+
+ aStrokeAttribute = attribute::StrokeAttribute(aDoubleArray);
+ }
+
+ // create base polygon and new primitive
+ basegfx::B2DPolygon aLine;
+ Primitive2DReference aNewPrimitive;
+
+ aLine.append(basegfx::B2DPoint(0.0, fLineOffset));
+ aLine.append(basegfx::B2DPoint(fLineWidth, fLineOffset));
+ aLine.transform(rUnscaledTransform);
+
+ if(bWaveLine)
+ {
+ double fWaveWidth(10.6 * fLineHeight);
+
+ if(FONT_UNDERLINE_SMALLWAVE == eLineStyle)
+ {
+ fWaveWidth *= 0.7;
+ }
+ else if(FONT_UNDERLINE_WAVE == eLineStyle)
+ {
+ // extra multiply to get the same WaveWidth as with the bold version
+ fWaveWidth *= 2.0;
+ }
+
+ aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, fWaveWidth * 0.5));
+ }
+ else
+ {
+ aNewPrimitive = Primitive2DReference(new PolygonStrokePrimitive2D(aLine, aLineAttribute, aStrokeAttribute));
+ }
+
+ // add primitive
+ rTarget.push_back(aNewPrimitive);
+
+ if(bDoubleLine)
+ {
+ // double line, create 2nd primitive with offset using TransformPrimitive based on
+ // already created NewPrimitive
+ double fLineDist(2.3 * fLineHeight);
+
+ if(bWaveLine)
+ {
+ fLineDist = 6.3 * fLineHeight;
+ }
+
+ basegfx::B2DHomMatrix aTransform;
+
+ // move base point of text to 0.0 and de-rotate
+ aTransform.translate(-rDecTrans.getTranslate().getX(), -rDecTrans.getTranslate().getY());
+ aTransform.rotate(-rDecTrans.getRotate());
+
+ // translate in Y by offset
+ aTransform.translate(0.0, fLineDist);
+
+ // move back and rotate
+ aTransform.rotate(rDecTrans.getRotate());
+ aTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY());
+
+ // add transform primitive
+ const Primitive2DSequence aContent(&aNewPrimitive, 1);
+ rTarget.push_back(Primitive2DReference(new TransformPrimitive2D(aTransform, aContent)));
+ }
+ }
+
+ void TextDecoratedPortionPrimitive2D::impCreateGeometryContent(
+ std::vector< Primitive2DReference >& rTarget,
+ basegfx::DecomposedB2DHomMatrixContainer& rDecTrans,
+ const String& rText,
+ xub_StrLen aTextPosition,
+ xub_StrLen aTextLength,
+ const ::std::vector< double >& rDXArray,
+ const FontAttributes& rFontAttributes) const
+ {
+ // create the SimpleTextPrimitive needed in any case
+ rTarget.push_back(Primitive2DReference(
+ new TextSimplePortionPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ rText,
+ aTextPosition,
+ aTextLength,
+ rDXArray,
+ rFontAttributes,
+ getLocale(),
+ getFontColor())));
+
+ // see if something else needs to be done
+ const bool bOverlineUsed(FONT_UNDERLINE_NONE != getFontOverline());
+ const bool bUnderlineUsed(FONT_UNDERLINE_NONE != getFontUnderline());
+ const bool bStrikeoutUsed(FONT_STRIKEOUT_NONE != getFontStrikeout());
+
+ if(bUnderlineUsed || bStrikeoutUsed || bOverlineUsed)
+ {
+ // common preparations
+ basegfx::B2DHomMatrix aUnscaledTransform;
+ TextLayouterDevice aTextLayouter;
+
+ // unscaled is needed since scale contains already the font size
+ aUnscaledTransform.shearX(rDecTrans.getShearX());
+ aUnscaledTransform.rotate(rDecTrans.getRotate());
+ aUnscaledTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY());
+
+ // TextLayouterDevice is needed to get metrics for text decorations like
+ // underline/strikeout/emphasis marks from it. For setup, the font size is needed
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ rDecTrans.getScale().getX(),
+ rDecTrans.getScale().getY(),
+ getLocale());
+
+ // get text width
+ double fTextWidth(0.0);
+
+ if(rDXArray.empty())
+ {
+ fTextWidth = aTextLayouter.getTextWidth(rText, aTextPosition, aTextLength);
+ }
+ else
+ {
+ fTextWidth = rDXArray.back() * rDecTrans.getScale().getX();
+ const double fFontScaleX(rDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ // need to take FontScaling out of the DXArray
+ fTextWidth /= fFontScaleX;
+ }
+ }
+
+ if(bOverlineUsed)
+ {
+ // create primitive geometry for overline
+ impCreateTextLine(rTarget, rDecTrans, aUnscaledTransform, getFontOverline(), aTextLayouter.getOverlineOffset(),
+ aTextLayouter.getOverlineHeight(), fTextWidth, getOverlineColor());
+ }
+
+ if(bUnderlineUsed)
+ {
+ // create primitive geometry for underline
+ impCreateTextLine(rTarget, rDecTrans, aUnscaledTransform, getFontUnderline(), aTextLayouter.getUnderlineOffset(),
+ aTextLayouter.getUnderlineHeight(), fTextWidth, getTextlineColor());
+ }
+
+ if(bStrikeoutUsed)
+ {
+ // create primitive geometry for strikeout
+ if(FONT_STRIKEOUT_SLASH == getFontStrikeout() || FONT_STRIKEOUT_X == getFontStrikeout())
+ {
+ // strikeout with character
+ const sal_Unicode aStrikeoutChar(FONT_STRIKEOUT_SLASH == getFontStrikeout() ? '/' : 'X');
+ const String aSingleCharString(aStrikeoutChar);
+ const double fStrikeCharWidth(aTextLayouter.getTextWidth(aSingleCharString, 0, 1));
+ const double fStrikeCharCount(fabs(fTextWidth/fStrikeCharWidth));
+ const sal_uInt32 nStrikeCharCount(static_cast< sal_uInt32 >(fStrikeCharCount + 0.5));
+ std::vector<double> aDXArray(nStrikeCharCount);
+ String aStrikeoutString;
+
+ for(sal_uInt32 a(0); a < nStrikeCharCount; a++)
+ {
+ aStrikeoutString += aSingleCharString;
+ aDXArray[a] = (a + 1) * fStrikeCharWidth;
+ }
+
+ rTarget.push_back(Primitive2DReference(
+ new TextSimplePortionPrimitive2D(
+ rDecTrans.getB2DHomMatrix(),
+ aStrikeoutString,
+ 0,
+ aStrikeoutString.Len(),
+ aDXArray,
+ rFontAttributes,
+ getLocale(),
+ getFontColor())));
+ }
+ else
+ {
+ // strikeout with geometry
+ double fStrikeoutHeight(aTextLayouter.getUnderlineHeight());
+ double fStrikeoutOffset(aTextLayouter.getStrikeoutOffset());
+ bool bDoubleLine(false);
+
+ // set line attribute
+ switch(getFontStrikeout())
+ {
+ default : // case primitive2d::FONT_STRIKEOUT_SINGLE:
+ {
+ break;
+ }
+ case primitive2d::FONT_STRIKEOUT_DOUBLE:
+ {
+ bDoubleLine = true;
+ break;
+ }
+ case primitive2d::FONT_STRIKEOUT_BOLD:
+ {
+ fStrikeoutHeight *= 2.0;
+ break;
+ }
+ }
+
+ if(bDoubleLine)
+ {
+ fStrikeoutOffset -= 0.50 * fStrikeoutHeight;
+ fStrikeoutHeight *= 0.64;
+ }
+
+ // create base polygon and new primitive
+ basegfx::B2DPolygon aStrikeoutLine;
+
+ aStrikeoutLine.append(basegfx::B2DPoint(0.0, -fStrikeoutOffset));
+ aStrikeoutLine.append(basegfx::B2DPoint(fTextWidth, -fStrikeoutOffset));
+ aStrikeoutLine.transform(aUnscaledTransform);
+
+ const attribute::LineAttribute aLineAttribute(getFontColor(), fStrikeoutHeight, basegfx::B2DLINEJOIN_NONE);
+ Primitive2DReference aNewPrimitive(new PolygonStrokePrimitive2D(aStrikeoutLine, aLineAttribute));
+
+ // add primitive
+ rTarget.push_back(aNewPrimitive);
+
+ if(bDoubleLine)
+ {
+ // double line, create 2nd primitive with offset using TransformPrimitive based on
+ // already created NewPrimitive
+ const double fLineDist(2.0 * fStrikeoutHeight);
+ basegfx::B2DHomMatrix aTransform;
+
+ // move base point of text to 0.0 and de-rotate
+ aTransform.translate(-rDecTrans.getTranslate().getX(), -rDecTrans.getTranslate().getY());
+ aTransform.rotate(-rDecTrans.getRotate());
+
+ // translate in Y by offset
+ aTransform.translate(0.0, -fLineDist);
+
+ // move back and rotate
+ aTransform.rotate(rDecTrans.getRotate());
+ aTransform.translate(rDecTrans.getTranslate().getX(), rDecTrans.getTranslate().getY());
+
+ // add transform primitive
+ const Primitive2DSequence aContent(&aNewPrimitive, 1);
+ rTarget.push_back(Primitive2DReference(new TransformPrimitive2D(aTransform, aContent)));
+ }
+ }
+ }
+ }
+
+ // TODO: Handle Font Emphasis Above/Below
+ }
+
+ void TextDecoratedPortionPrimitive2D::impCorrectTextBoundary(::com::sun::star::i18n::Boundary& rNextWordBoundary) const
+ {
+ // truncate aNextWordBoundary to min/max possible values. This is necessary since the word start may be
+ // before/after getTextPosition() when a long string is the content and getTextPosition()
+ // is right inside a word. Same for end.
+ const sal_Int32 aMinPos(static_cast< sal_Int32 >(getTextPosition()));
+ const sal_Int32 aMaxPos(aMinPos + static_cast< sal_Int32 >(getTextLength()));
+
+ if(rNextWordBoundary.startPos < aMinPos)
+ {
+ rNextWordBoundary.startPos = aMinPos;
+ }
+ else if(rNextWordBoundary.startPos > aMaxPos)
+ {
+ rNextWordBoundary.startPos = aMaxPos;
+ }
+
+ if(rNextWordBoundary.endPos < aMinPos)
+ {
+ rNextWordBoundary.endPos = aMinPos;
+ }
+ else if(rNextWordBoundary.endPos > aMaxPos)
+ {
+ rNextWordBoundary.endPos = aMaxPos;
+ }
+ }
+
+ void TextDecoratedPortionPrimitive2D::impSplitSingleWords(
+ std::vector< Primitive2DReference >& rTarget,
+ basegfx::DecomposedB2DHomMatrixContainer& rDecTrans) const
+ {
+ // break iterator support
+ // made static so it only needs to be fetched once, even with many single
+ // constructed VclMetafileProcessor2D. It's still incarnated on demand,
+ // but exists for OOo runtime now by purpose.
+ static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xLocalBreakIterator;
+
+ if(!xLocalBreakIterator.is())
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory());
+ xLocalBreakIterator.set(xMSF->createInstance(rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")), ::com::sun::star::uno::UNO_QUERY);
+ }
+
+ if(xLocalBreakIterator.is() && getTextLength())
+ {
+ // init word iterator, get first word and truncate to possibilities
+ ::com::sun::star::i18n::Boundary aNextWordBoundary(xLocalBreakIterator->getWordBoundary(
+ getText(), getTextPosition(), getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True));
+
+ if(aNextWordBoundary.endPos == getTextPosition())
+ {
+ // backward hit, force next word
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), getTextPosition() + 1, getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+ }
+
+ impCorrectTextBoundary(aNextWordBoundary);
+
+ // prepare new font attributes WITHOUT outline
+ const FontAttributes aNewFontAttributes(
+ getFontAttributes().getFamilyName(),
+ getFontAttributes().getStyleName(),
+ getFontAttributes().getWeight(),
+ getFontAttributes().getSymbol(),
+ getFontAttributes().getVertical(),
+ getFontAttributes().getItalic(),
+ false, // no outline anymore, handled locally
+ getFontAttributes().getRTL(),
+ getFontAttributes().getBiDiStrong());
+
+ if(aNextWordBoundary.startPos == getTextPosition() && aNextWordBoundary.endPos == getTextLength())
+ {
+ // it IS only a single word, handle as one word
+ impCreateGeometryContent(rTarget, rDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttributes);
+ }
+ else
+ {
+ // prepare TextLayouter
+ const bool bNoDXArray(getDXArray().empty());
+ TextLayouterDevice aTextLayouter;
+
+ if(bNoDXArray)
+ {
+ // ..but only completely when no DXArray
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ rDecTrans.getScale().getX(),
+ rDecTrans.getScale().getY(),
+ getLocale());
+ }
+
+ // do iterate over single words
+ while(aNextWordBoundary.startPos != aNextWordBoundary.endPos)
+ {
+ // prepare values for new portion
+ const xub_StrLen nNewTextStart(static_cast< xub_StrLen >(aNextWordBoundary.startPos));
+ const xub_StrLen nNewTextEnd(static_cast< xub_StrLen >(aNextWordBoundary.endPos));
+
+ // prepare transform for the single word
+ basegfx::B2DHomMatrix aNewTransform;
+ ::std::vector< double > aNewDXArray;
+ const bool bNewStartIsNotOldStart(nNewTextStart > getTextPosition());
+
+ if(!bNoDXArray)
+ {
+ // prepare new DXArray for the single word
+ aNewDXArray = ::std::vector< double >(
+ getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextStart - getTextPosition()),
+ getDXArray().begin() + static_cast< sal_uInt32 >(nNewTextEnd - getTextPosition()));
+ }
+
+ if(bNewStartIsNotOldStart)
+ {
+ // needs to be moved to a new start position
+ double fOffset(0.0);
+
+ if(bNoDXArray)
+ {
+ // evaluate using TextLayouter
+ fOffset = aTextLayouter.getTextWidth(getText(), getTextPosition(), nNewTextStart);
+ }
+ else
+ {
+ // get from DXArray
+ const sal_uInt32 nIndex(static_cast< sal_uInt32 >(nNewTextStart - getTextPosition()));
+ fOffset = getDXArray()[nIndex - 1];
+ }
+
+ // need offset without FontScale for building the new transformation. The
+ // new transformation will be multiplied with the current text transformation
+ // so FontScale would be double
+ double fOffsetNoScale(fOffset);
+ const double fFontScaleX(rDecTrans.getScale().getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ fOffsetNoScale /= fFontScaleX;
+ }
+
+ // apply needed offset to transformation
+ aNewTransform.translate(fOffsetNoScale, 0.0);
+
+ if(!bNoDXArray)
+ {
+ // DXArray values need to be corrected with the offset, too. Here,
+ // take the scaled offset since the DXArray is scaled
+ const sal_uInt32 nArraySize(aNewDXArray.size());
+
+ for(sal_uInt32 a(0); a < nArraySize; a++)
+ {
+ aNewDXArray[a] -= fOffset;
+ }
+ }
+ }
+
+ // add text transformation to new transformation
+ aNewTransform *= rDecTrans.getB2DHomMatrix();
+
+ // create geometry content for the single word. Do not forget
+ // to use the new transformation
+ basegfx::DecomposedB2DHomMatrixContainer aDecTrans(aNewTransform);
+
+ impCreateGeometryContent(rTarget, aDecTrans, getText(), nNewTextStart,
+ nNewTextEnd - nNewTextStart, aNewDXArray, aNewFontAttributes);
+
+ if(aNextWordBoundary.endPos >= getTextPosition() + getTextLength())
+ {
+ // end reached
+ aNextWordBoundary.startPos = aNextWordBoundary.endPos;
+ }
+ else
+ {
+ // get new word portion
+ const sal_Int32 nLastEndPos(aNextWordBoundary.endPos);
+
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), aNextWordBoundary.endPos, getLocale(),
+ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+
+ if(nLastEndPos == aNextWordBoundary.endPos)
+ {
+ // backward hit, force next word
+ aNextWordBoundary = xLocalBreakIterator->getWordBoundary(
+ getText(), nLastEndPos + 1, getLocale(),
+ ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True);
+ }
+
+ impCorrectTextBoundary(aNextWordBoundary);
+ }
+ }
+ }
+ }
+ }
+
+ Primitive2DSequence TextDecoratedPortionPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ std::vector< Primitive2DReference > aNewPrimitives;
+ basegfx::DecomposedB2DHomMatrixContainer aDecTrans(getTextTransform());
+ Primitive2DSequence aRetval;
+
+ // create basic geometry such as SimpleTextPrimitive, Overline, Underline,
+ // Strikeout, etc...
+ if(getWordLineMode())
+ {
+ // support for single word mode
+ impSplitSingleWords(aNewPrimitives, aDecTrans);
+ }
+ else
+ {
+ // prepare new font attributes WITHOUT outline
+ const FontAttributes aNewFontAttributes(
+ getFontAttributes().getFamilyName(),
+ getFontAttributes().getStyleName(),
+ getFontAttributes().getWeight(),
+ getFontAttributes().getSymbol(),
+ getFontAttributes().getVertical(),
+ getFontAttributes().getItalic(),
+ false, // no outline anymore, handled locally
+ getFontAttributes().getRTL(),
+ getFontAttributes().getBiDiStrong());
+
+ // handle as one word
+ impCreateGeometryContent(aNewPrimitives, aDecTrans, getText(), getTextPosition(), getTextLength(), getDXArray(), aNewFontAttributes);
+ }
+
+ // convert to Primitive2DSequence
+ const sal_uInt32 nMemberCount(aNewPrimitives.size());
+
+ if(nMemberCount)
+ {
+ aRetval.realloc(nMemberCount);
+
+ for(sal_uInt32 a(0); a < nMemberCount; a++)
+ {
+ aRetval[a] = aNewPrimitives[a];
+ }
+ }
+
+ // Handle Shadow, Outline and FontRelief
+ if(aRetval.hasElements())
+ {
+ // outline AND shadow depend on NO FontRelief (see dialog)
+ const bool bHasFontRelief(FONT_RELIEF_NONE != getFontRelief());
+ const bool bHasShadow(!bHasFontRelief && getShadow());
+ const bool bHasOutline(!bHasFontRelief && getFontAttributes().getOutline());
+
+ if(bHasShadow || bHasFontRelief || bHasOutline)
+ {
+ Primitive2DReference aShadow;
+
+ if(bHasShadow)
+ {
+ // create shadow with current content (in aRetval). Text shadow
+ // is constant, relative to font size, rotated with the text and has a
+ // constant color.
+ // shadow parameter values
+ static double fFactor(1.0 / 24.0);
+ const double fTextShadowOffset(aDecTrans.getScale().getY() * fFactor);
+ static basegfx::BColor aShadowColor(0.3, 0.3, 0.3);
+
+ // preapare shadow transform matrix
+ basegfx::B2DHomMatrix aShadowTransform;
+ aShadowTransform.translate(fTextShadowOffset, fTextShadowOffset);
+
+ // create shadow primitive
+ aShadow = Primitive2DReference(new ShadowPrimitive2D(
+ aShadowTransform,
+ aShadowColor,
+ aRetval));
+ }
+
+ if(bHasFontRelief)
+ {
+ // create emboss using an own helper primitive since this will
+ // be view-dependent
+ const basegfx::BColor aBBlack(0.0, 0.0, 0.0);
+ const bool bDefaultTextColor(aBBlack == getFontColor());
+ TextEffectStyle2D aTextEffectStyle2D(TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED);
+
+ if(bDefaultTextColor)
+ {
+ if(FONT_RELIEF_ENGRAVED == getFontRelief())
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT;
+ }
+ else
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT;
+ }
+ }
+ else
+ {
+ if(FONT_RELIEF_ENGRAVED == getFontRelief())
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED;
+ }
+ else
+ {
+ aTextEffectStyle2D = TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED;
+ }
+ }
+
+ Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D(
+ aRetval,
+ aDecTrans.getTranslate(),
+ aDecTrans.getRotate(),
+ aTextEffectStyle2D));
+ aRetval = Primitive2DSequence(&aNewTextEffect, 1);
+ }
+ else if(bHasOutline)
+ {
+ // create outline using an own helper primitive since this will
+ // be view-dependent
+ Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D(
+ aRetval,
+ aDecTrans.getTranslate(),
+ aDecTrans.getRotate(),
+ TEXTEFFECTSTYLE2D_OUTLINE));
+ aRetval = Primitive2DSequence(&aNewTextEffect, 1);
+ }
+
+ if(aShadow.is())
+ {
+ // put shadow in front if there is one to paint timely before
+ // but placed behind content
+ const Primitive2DSequence aContent(aRetval);
+ aRetval = Primitive2DSequence(&aShadow, 1);
+ appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aContent);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ TextDecoratedPortionPrimitive2D::TextDecoratedPortionPrimitive2D(
+
+ // TextSimplePortionPrimitive2D parameters
+ const basegfx::B2DHomMatrix& rNewTransform,
+ const String& rText,
+ xub_StrLen aTextPosition,
+ xub_StrLen aTextLength,
+ const ::std::vector< double >& rDXArray,
+ const FontAttributes& rFontAttributes,
+ const ::com::sun::star::lang::Locale& rLocale,
+ const basegfx::BColor& rFontColor,
+
+ // local parameters
+ const basegfx::BColor& rOverlineColor,
+ const basegfx::BColor& rTextlineColor,
+ FontUnderline eFontOverline,
+ FontUnderline eFontUnderline,
+ bool bUnderlineAbove,
+ FontStrikeout eFontStrikeout,
+ bool bWordLineMode,
+ FontEmphasisMark eFontEmphasisMark,
+ bool bEmphasisMarkAbove,
+ bool bEmphasisMarkBelow,
+ FontRelief eFontRelief,
+ bool bShadow)
+ : TextSimplePortionPrimitive2D(rNewTransform, rText, aTextPosition, aTextLength, rDXArray, rFontAttributes, rLocale, rFontColor),
+ maOverlineColor(rOverlineColor),
+ maTextlineColor(rTextlineColor),
+ meFontOverline(eFontOverline),
+ meFontUnderline(eFontUnderline),
+ meFontStrikeout(eFontStrikeout),
+ meFontEmphasisMark(eFontEmphasisMark),
+ meFontRelief(eFontRelief),
+ mbUnderlineAbove(bUnderlineAbove),
+ mbWordLineMode(bWordLineMode),
+ mbEmphasisMarkAbove(bEmphasisMarkAbove),
+ mbEmphasisMarkBelow(bEmphasisMarkBelow),
+ mbShadow(bShadow)
+ {
+ }
+
+ bool TextDecoratedPortionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(TextSimplePortionPrimitive2D::operator==(rPrimitive))
+ {
+ const TextDecoratedPortionPrimitive2D& rCompare = (TextDecoratedPortionPrimitive2D&)rPrimitive;
+
+ return (getOverlineColor() == rCompare.getOverlineColor()
+ && getTextlineColor() == rCompare.getTextlineColor()
+ && getFontOverline() == rCompare.getFontOverline()
+ && getFontUnderline() == rCompare.getFontUnderline()
+ && getFontStrikeout() == rCompare.getFontStrikeout()
+ && getFontEmphasisMark() == rCompare.getFontEmphasisMark()
+ && getFontRelief() == rCompare.getFontRelief()
+ && getUnderlineAbove() == rCompare.getUnderlineAbove()
+ && getWordLineMode() == rCompare.getWordLineMode()
+ && getEmphasisMarkAbove() == rCompare.getEmphasisMarkAbove()
+ && getEmphasisMarkBelow() == rCompare.getEmphasisMarkBelow()
+ && getShadow() == rCompare.getShadow());
+ }
+
+ return false;
+ }
+
+ // #i96475#
+ // Added missing implementation. Decorations may (will) stick out of the text's
+ // inking area, so add them if needed
+ basegfx::B2DRange TextDecoratedPortionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ const bool bDecoratedIsNeeded(
+ FONT_UNDERLINE_NONE != getFontOverline()
+ || FONT_UNDERLINE_NONE != getFontUnderline()
+ || FONT_STRIKEOUT_NONE != getFontStrikeout()
+ || FONT_EMPHASISMARK_NONE != getFontEmphasisMark()
+ || FONT_RELIEF_NONE != getFontRelief()
+ || getShadow());
+
+ if(bDecoratedIsNeeded)
+ {
+ // decoration is used, fallback to BasePrimitive2D::getB2DRange which uses
+ // the own local decomposition for computation and thus creates all necessary
+ // geometric objects
+ return BasePrimitive2D::getB2DRange(rViewInformation);
+ }
+ else
+ {
+ // no relevant decoration used, fallback to TextSimplePortionPrimitive2D::getB2DRange
+ return TextSimplePortionPrimitive2D::getB2DRange(rViewInformation);
+ }
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextDecoratedPortionPrimitive2D, PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
new file mode 100644
index 000000000000..c1963f4ba2a4
--- /dev/null
+++ b/drawinglayer/source/primitive2d/texteffectprimitive2d.cxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: texteffectprimitive2d.cxx,v $
+ *
+ * $Revision: 1.4 $
+ *
+ * last change: $Author: aw $ $Date: 2008-06-24 15:31:08 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/texteffectprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ static double fDiscreteSize(1.1);
+
+ Primitive2DSequence TextEffectPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ Primitive2DSequence aRetval;
+
+ // get the distance of one discrete units from target display. Use between 1.0 and sqrt(2) to
+ // have good results on rotated objects, too
+ const basegfx::B2DVector aDistance(rViewInformation.getInverseObjectToViewTransformation() *
+ basegfx::B2DVector(fDiscreteSize, fDiscreteSize));
+ const basegfx::B2DVector aDiagonalDistance(aDistance * (1.0 / 1.44));
+
+ switch(getTextEffectStyle2D())
+ {
+ case TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED:
+ case TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED:
+ case TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT:
+ case TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT:
+ {
+ // prepare transform of sub-group back to (0,0) and align to X-Axis
+ basegfx::B2DHomMatrix aBackTransform;
+ aBackTransform.translate(-getRotationCenter().getX(), -getRotationCenter().getY());
+ aBackTransform.rotate(-getDirection());
+
+ // prepare transform of sub-group back to it's position and rotation
+ basegfx::B2DHomMatrix aForwardTransform;
+ aForwardTransform.rotate(getDirection());
+ aForwardTransform.translate(getRotationCenter().getX(), getRotationCenter().getY());
+
+ // create transformation for one discrete unit
+ const bool bEmbossed(
+ TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED == getTextEffectStyle2D()
+ || TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT == getTextEffectStyle2D());
+ const bool bDefaultTextColor(
+ TEXTEFFECTSTYLE2D_RELIEF_EMBOSSED_DEFAULT == getTextEffectStyle2D()
+ || TEXTEFFECTSTYLE2D_RELIEF_ENGRAVED_DEFAULT == getTextEffectStyle2D());
+ basegfx::B2DHomMatrix aTransform(aBackTransform);
+ aRetval.realloc(2);
+
+ if(bEmbossed)
+ {
+ // to bottom-right
+ aTransform.translate(aDiagonalDistance.getX(), aDiagonalDistance.getY());
+ }
+ else
+ {
+ // to top-left
+ aTransform.translate(-aDiagonalDistance.getX(), -aDiagonalDistance.getY());
+ }
+
+ aTransform *= aForwardTransform;
+
+ if(bDefaultTextColor)
+ {
+ // emboss/engrave in black, original forced to white
+ const basegfx::BColorModifier aBColorModifierToGray(basegfx::BColor(0.0));
+ const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToGray));
+ aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, Primitive2DSequence(&xModifiedColor, 1)));
+
+ // add original, too
+ const basegfx::BColorModifier aBColorModifierToWhite(basegfx::BColor(1.0));
+ aRetval[1] = Primitive2DReference(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToWhite));
+ }
+ else
+ {
+ // emboss/engrave in gray, keep original's color
+ const basegfx::BColorModifier aBColorModifierToGray(basegfx::BColor(0.75)); // 192
+ const Primitive2DReference xModifiedColor(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToGray));
+ aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, Primitive2DSequence(&xModifiedColor, 1)));
+
+ // add original, too
+ aRetval[1] = Primitive2DReference(new GroupPrimitive2D(getChildren()));
+ }
+
+ break;
+ }
+ case TEXTEFFECTSTYLE2D_OUTLINE:
+ {
+ // create transform primitives in all directions
+ basegfx::B2DHomMatrix aTransform;
+ aRetval.realloc(9);
+
+ aTransform.set(0, 2, aDistance.getX());
+ aTransform.set(1, 2, 0.0);
+ aRetval[0] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, aDiagonalDistance.getX());
+ aTransform.set(1, 2, aDiagonalDistance.getY());
+ aRetval[1] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, 0.0);
+ aTransform.set(1, 2, aDistance.getY());
+ aRetval[2] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, -aDiagonalDistance.getX());
+ aTransform.set(1, 2, aDiagonalDistance.getY());
+ aRetval[3] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, -aDistance.getX());
+ aTransform.set(1, 2, 0.0);
+ aRetval[4] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, -aDiagonalDistance.getX());
+ aTransform.set(1, 2, -aDiagonalDistance.getY());
+ aRetval[5] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, 0.0);
+ aTransform.set(1, 2, -aDistance.getY());
+ aRetval[6] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ aTransform.set(0, 2, aDiagonalDistance.getX());
+ aTransform.set(1, 2, -aDiagonalDistance.getY());
+ aRetval[7] = Primitive2DReference(new TransformPrimitive2D(aTransform, getChildren()));
+
+ // at last, place original over it, but force to white
+ const basegfx::BColorModifier aBColorModifierToWhite(basegfx::BColor(1.0, 1.0, 1.0));
+ aRetval[8] = Primitive2DReference(new ModifiedColorPrimitive2D(getChildren(), aBColorModifierToWhite));
+
+ break;
+ }
+ }
+
+ return aRetval;
+ }
+
+ TextEffectPrimitive2D::TextEffectPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ const basegfx::B2DPoint& rRotationCenter,
+ double fDirection,
+ TextEffectStyle2D eTextEffectStyle2D)
+ : GroupPrimitive2D(rChildren),
+ maRotationCenter(rRotationCenter),
+ mfDirection(fDirection),
+ meTextEffectStyle2D(eTextEffectStyle2D)
+ {
+ }
+
+ bool TextEffectPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const TextEffectPrimitive2D& rCompare = (TextEffectPrimitive2D&)rPrimitive;
+
+ return (getRotationCenter() == rCompare.getRotationCenter()
+ && getDirection() == rCompare.getDirection()
+ && getTextEffectStyle2D() == rCompare.getTextEffectStyle2D());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange TextEffectPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ // get range of content and grow by used fDiscreteSize. That way it is not necessary to ask
+ // the whole decomposition for it's ranges (which may be expensive with outline mode which
+ // then will ask 9 times at nearly the same content. This may even be refined here using the
+ // TextEffectStyle information, e.g. for TEXTEFFECTSTYLE2D_RELIEF the grow needs only to
+ // be in two directions
+ basegfx::B2DRange aRetval(getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation));
+ aRetval.grow(fDiscreteSize);
+
+ return aRetval;
+ }
+
+ Primitive2DSequence TextEffectPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if(getLocalDecomposition().hasElements())
+ {
+ if(maLastObjectToViewTransformation != rViewInformation.getObjectToViewTransformation())
+ {
+ // conditions of last local decomposition have changed, delete
+ const_cast< TextEffectPrimitive2D* >(this)->setLocalDecomposition(Primitive2DSequence());
+ }
+ }
+
+ if(!getLocalDecomposition().hasElements())
+ {
+ // remember ViewRange and ViewTransformation
+ const_cast< TextEffectPrimitive2D* >(this)->maLastObjectToViewTransformation = rViewInformation.getObjectToViewTransformation();
+ }
+
+ // use parent implementation
+ return BasePrimitive2D::get2DDecomposition(rViewInformation);
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextEffectPrimitive2D, PRIMITIVE2D_ID_TEXTEFFECTPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
new file mode 100644
index 000000000000..72249e673c1b
--- /dev/null
+++ b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: texthierarchyprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextHierarchyLinePrimitive2D::TextHierarchyLinePrimitive2D(const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextHierarchyLinePrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYLINEPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextHierarchyParagraphPrimitive2D::TextHierarchyParagraphPrimitive2D(const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextHierarchyParagraphPrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextHierarchyBulletPrimitive2D::TextHierarchyBulletPrimitive2D(const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextHierarchyBulletPrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYBULLETPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextHierarchyBlockPrimitive2D::TextHierarchyBlockPrimitive2D(const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextHierarchyBlockPrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYBLOCKPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextHierarchyFieldPrimitive2D::TextHierarchyFieldPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ const FieldType& rFieldType,
+ const rtl::OUString& rString)
+ : GroupPrimitive2D(rChildren),
+ meType(rFieldType),
+ maString(rString)
+ {
+ }
+
+ bool TextHierarchyFieldPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const TextHierarchyFieldPrimitive2D& rCompare = (TextHierarchyFieldPrimitive2D&)rPrimitive;
+
+ return (getType() == rCompare.getType()
+ && getString() == rCompare.getString());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextHierarchyFieldPrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYFIELDPRIMITIVE2D)
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TextHierarchyEditPrimitive2D::TextHierarchyEditPrimitive2D(const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren)
+ {
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextHierarchyEditPrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
new file mode 100644
index 000000000000..e321783c8406
--- /dev/null
+++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx
@@ -0,0 +1,430 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textlayoutdevice.cxx,v $
+ *
+ * $Revision: 1.10 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/font.hxx>
+#include <vcl/metric.hxx>
+#include <i18npool/mslangid.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <vcl/svapp.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// VDev RevDevice provider
+
+namespace
+{
+ class ImpTimedRefDev : public Timer
+ {
+ ImpTimedRefDev** mppStaticPointerOnMe;
+ VirtualDevice* mpVirDev;
+ sal_uInt32 mnUseCount;
+
+ public:
+ ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe);
+ ~ImpTimedRefDev();
+ virtual void Timeout();
+
+ VirtualDevice& acquireVirtualDevice();
+ void releaseVirtualDevice();
+ };
+
+ ImpTimedRefDev::ImpTimedRefDev(ImpTimedRefDev** ppStaticPointerOnMe)
+ : mppStaticPointerOnMe(ppStaticPointerOnMe),
+ mpVirDev(0L),
+ mnUseCount(0L)
+ {
+ SetTimeout(3L * 60L * 1000L); // three minutes
+ Start();
+ }
+
+ ImpTimedRefDev::~ImpTimedRefDev()
+ {
+ OSL_ENSURE(0L == mnUseCount, "destruction of a still used ImpTimedRefDev (!)");
+
+ if(mppStaticPointerOnMe && *mppStaticPointerOnMe)
+ {
+ *mppStaticPointerOnMe = 0L;
+ }
+
+ if(mpVirDev)
+ {
+ delete mpVirDev;
+ }
+ }
+
+ void ImpTimedRefDev::Timeout()
+ {
+ // for obvious reasons, do not call anything after this
+ delete (this);
+ }
+
+ VirtualDevice& ImpTimedRefDev::acquireVirtualDevice()
+ {
+ if(!mpVirDev)
+ {
+ mpVirDev = new VirtualDevice();
+ mpVirDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_MSO1 );
+ }
+
+ if(!mnUseCount)
+ {
+ Stop();
+ }
+
+ mnUseCount++;
+
+ return *mpVirDev;
+ }
+
+ void ImpTimedRefDev::releaseVirtualDevice()
+ {
+ OSL_ENSURE(mnUseCount, "mismatch call number to releaseVirtualDevice() (!)");
+ mnUseCount--;
+
+ if(!mnUseCount)
+ {
+ Start();
+ }
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// access to one global ImpTimedRefDev incarnation in namespace drawinglayer::primitive
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ // static pointer here
+ static ImpTimedRefDev* pImpGlobalRefDev = 0L;
+
+ // static methods here
+ VirtualDevice& acquireGlobalVirtualDevice()
+ {
+ if(!pImpGlobalRefDev)
+ {
+ pImpGlobalRefDev = new ImpTimedRefDev(&pImpGlobalRefDev);
+ }
+
+ return pImpGlobalRefDev->acquireVirtualDevice();
+ }
+
+ void releaseGlobalVirtualDevice()
+ {
+ OSL_ENSURE(pImpGlobalRefDev, "releaseGlobalVirtualDevice() without prior acquireGlobalVirtualDevice() call(!)");
+ pImpGlobalRefDev->releaseVirtualDevice();
+ }
+
+ TextLayouterDevice::TextLayouterDevice()
+ : mrDevice(acquireGlobalVirtualDevice())
+ {
+ }
+
+ TextLayouterDevice::~TextLayouterDevice()
+ {
+ releaseGlobalVirtualDevice();
+ }
+
+ void TextLayouterDevice::setFont(const Font& rFont)
+ {
+ mrDevice.SetFont( rFont );
+ }
+
+ void TextLayouterDevice::setFontAttributes(
+ const FontAttributes& rFontAttributes,
+ double fFontScaleX,
+ double fFontScaleY,
+ const ::com::sun::star::lang::Locale& rLocale)
+ {
+ setFont(getVclFontFromFontAttributes(
+ rFontAttributes,
+ fFontScaleX,
+ fFontScaleY,
+ 0.0,
+ rLocale));
+ }
+
+ double TextLayouterDevice::getOverlineOffset() const
+ {
+ const ::FontMetric& rMetric = mrDevice.GetFontMetric();
+ double fRet = (rMetric.GetIntLeading() / 2.0) - rMetric.GetAscent();
+ return fRet;
+ }
+
+ double TextLayouterDevice::getUnderlineOffset() const
+ {
+ const ::FontMetric& rMetric = mrDevice.GetFontMetric();
+ double fRet = rMetric.GetDescent() / 2.0;
+ return fRet;
+ }
+
+ double TextLayouterDevice::getStrikeoutOffset() const
+ {
+ const ::FontMetric& rMetric = mrDevice.GetFontMetric();
+ double fRet = (rMetric.GetAscent() - rMetric.GetIntLeading()) / 3.0;
+ return fRet;
+ }
+
+ double TextLayouterDevice::getOverlineHeight() const
+ {
+ const ::FontMetric& rMetric = mrDevice.GetFontMetric();
+ double fRet = rMetric.GetIntLeading() / 2.5;
+ return fRet;
+ }
+
+ double TextLayouterDevice::getUnderlineHeight() const
+ {
+ const ::FontMetric& rMetric = mrDevice.GetFontMetric();
+ double fRet = rMetric.GetDescent() / 4.0;
+ return fRet;
+ }
+
+ double TextLayouterDevice::getTextHeight() const
+ {
+ return mrDevice.GetTextHeight();
+ }
+
+ double TextLayouterDevice::getTextWidth(
+ const String& rText,
+ xub_StrLen nIndex,
+ xub_StrLen nLength) const
+ {
+ return mrDevice.GetTextWidth(rText, nIndex, nLength);
+ }
+
+ bool TextLayouterDevice::getTextOutlines(
+ basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector,
+ const String& rText,
+ xub_StrLen nIndex,
+ xub_StrLen nLength,
+ const ::std::vector< double >& rDXArray)
+ {
+ const sal_uInt32 nDXArrayCount(rDXArray.size());
+
+ if(nDXArrayCount)
+ {
+ OSL_ENSURE(nDXArrayCount == nLength, "DXArray size does not correspond to text portion size (!)");
+ std::vector< sal_Int32 > aIntegerDXArray(nDXArrayCount);
+
+ for(sal_uInt32 a(0); a < nDXArrayCount; a++)
+ {
+ aIntegerDXArray[a] = basegfx::fround(rDXArray[a]);
+ }
+
+ return mrDevice.GetTextOutlines(
+ rB2DPolyPolyVector,
+ rText,
+ nIndex,
+ nIndex,
+ nLength,
+ true,
+ 0,
+ &(aIntegerDXArray[0]));
+ }
+ else
+ {
+ return mrDevice.GetTextOutlines(
+ rB2DPolyPolyVector,
+ rText,
+ nIndex,
+ nIndex,
+ nLength,
+ true,
+ 0,
+ 0);
+ }
+ }
+
+ basegfx::B2DRange TextLayouterDevice::getTextBoundRect(
+ const String& rText,
+ xub_StrLen nIndex,
+ xub_StrLen nLength) const
+ {
+ if(nLength)
+ {
+ Rectangle aRect;
+
+ mrDevice.GetTextBoundRect(
+ aRect,
+ rText,
+ nIndex,
+ nIndex,
+ nLength);
+
+ // #i104432#, #i102556# take empty results into account
+ if(!aRect.IsEmpty())
+ {
+ return basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+ }
+ }
+
+ return basegfx::B2DRange();
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// helper methods for vcl font handling
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Font getVclFontFromFontAttributes(
+ const FontAttributes& rFontAttributes,
+ double fFontScaleX,
+ double fFontScaleY,
+ double fFontRotation,
+ const ::com::sun::star::lang::Locale& rLocale)
+ {
+ // detect FontScaling
+ const sal_uInt32 nHeight(basegfx::fround(fabs(fFontScaleY)));
+ const sal_uInt32 nWidth(basegfx::fround(fabs(fFontScaleX)));
+ const bool bFontIsScaled(nHeight != nWidth);
+
+#ifdef WIN32
+ // for WIN32 systems, start with creating an unscaled font. If FontScaling
+ // is wanted, that width needs to be adapted using FontMetric again to get a
+ // width of the unscaled font
+ Font aRetval(
+ rFontAttributes.getFamilyName(),
+ rFontAttributes.getStyleName(),
+ Size(0, nHeight));
+#else
+ // for non-WIN32 systems things are easier since these accept a Font creation
+ // with initially nWidth != nHeight for FontScaling. Despite that, use zero for
+ // FontWidth when no scaling is used to explicitely have that zero when e.g. the
+ // Font would be recorded in a MetaFile (The MetaFile FontAction WILL record a
+ // set FontWidth; import that in a WIN32 system, and trouble is there)
+ Font aRetval(
+ rFontAttributes.getFamilyName(),
+ rFontAttributes.getStyleName(),
+ Size(bFontIsScaled ? nWidth : 0, nHeight));
+#endif
+ // define various other FontAttributes
+ aRetval.SetAlign(ALIGN_BASELINE);
+ aRetval.SetCharSet(rFontAttributes.getSymbol() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE);
+ aRetval.SetVertical(rFontAttributes.getVertical() ? TRUE : FALSE);
+ aRetval.SetWeight(static_cast<FontWeight>(rFontAttributes.getWeight()));
+ aRetval.SetItalic(rFontAttributes.getItalic() ? ITALIC_NORMAL : ITALIC_NONE);
+ aRetval.SetOutline(rFontAttributes.getOutline());
+ aRetval.SetLanguage(MsLangId::convertLocaleToLanguage(rLocale));
+
+#ifdef WIN32
+ // for WIN32 systems, correct the FontWidth if FontScaling is used
+ if(bFontIsScaled && nHeight > 0)
+ {
+ const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aRetval));
+
+ if(aUnscaledFontMetric.GetWidth() > 0)
+ {
+ const double fScaleFactor((double)nWidth / (double)nHeight);
+ const sal_uInt32 nScaledWidth(basegfx::fround((double)aUnscaledFontMetric.GetWidth() * fScaleFactor));
+ aRetval.SetWidth(nScaledWidth);
+ }
+ }
+#endif
+ // handle FontRotation (if defined)
+ if(!basegfx::fTools::equalZero(fFontRotation))
+ {
+ sal_Int16 aRotate10th((sal_Int16)(fFontRotation * (-1800.0/F_PI)));
+ aRetval.SetOrientation(aRotate10th % 3600);
+ }
+
+ return aRetval;
+ }
+
+ FontAttributes getFontAttributesFromVclFont(
+ basegfx::B2DVector& o_rSize,
+ const Font& rFont,
+ bool bRTL,
+ bool bBiDiStrong)
+ {
+ const FontAttributes aRetval(
+ rFont.GetName(),
+ rFont.GetStyleName(),
+ static_cast<sal_uInt16>(rFont.GetWeight()),
+ RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet(),
+ rFont.IsVertical(),
+ ITALIC_NONE != rFont.GetItalic(),
+ rFont.IsOutline(),
+ bRTL,
+ bBiDiStrong);
+ // TODO: eKerning
+
+ // set FontHeight and init to no FontScaling
+ o_rSize.setY(rFont.GetSize().getHeight() > 0 ? rFont.GetSize().getHeight() : 0);
+ o_rSize.setX(o_rSize.getY());
+
+#ifdef WIN32
+ // for WIN32 systems, the FontScaling at the Font is detected by
+ // checking that FontWidth != 0. When FontScaling is used, WIN32
+ // needs to do extra stuff to detect the correct width (since it's
+ // zero and not equal the font height) and it's relationship to
+ // the height
+ if(rFont.GetSize().getWidth() > 0)
+ {
+ Font aUnscaledFont(rFont);
+ aUnscaledFont.SetWidth(0);
+ const FontMetric aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont));
+
+ if(aUnscaledFontMetric.GetWidth() > 0)
+ {
+ const double fScaleFactor((double)rFont.GetSize().getWidth() / (double)aUnscaledFontMetric.GetWidth());
+ o_rSize.setX(fScaleFactor * o_rSize.getY());
+ }
+ }
+#else
+ // For non-WIN32 systems the detection is the same, but the value
+ // is easier achieved since width == height is interpreted as no
+ // scaling. Ergo, Width == 0 means width == height, and width != 0
+ // means the scaling is in the direct relation of width to height
+ if(rFont.GetSize().getWidth() > 0)
+ {
+ o_rSize.setX((double)rFont.GetSize().getWidth());
+ }
+#endif
+ return aRetval;
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/textprimitive2d.cxx b/drawinglayer/source/primitive2d/textprimitive2d.cxx
new file mode 100644
index 000000000000..f8e413da0e8c
--- /dev/null
+++ b/drawinglayer/source/primitive2d/textprimitive2d.cxx
@@ -0,0 +1,374 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: textprimitive2d.cxx,v $
+ *
+ * $Revision: 1.22 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/texteffectprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ bool FontAttributes::operator==(const FontAttributes& rCompare) const
+ {
+ return (getFamilyName() == rCompare.getFamilyName()
+ && getStyleName() == rCompare.getStyleName()
+ && getWeight() == rCompare.getWeight()
+ && getSymbol() == rCompare.getSymbol()
+ && getVertical() == rCompare.getVertical()
+ && getItalic() == rCompare.getItalic()
+ && getOutline() == rCompare.getOutline()
+ && getRTL() == rCompare.getRTL()
+ && getBiDiStrong() == rCompare.getBiDiStrong());
+ }
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+ // adapts fontScale for usage with TextLayouter. Input is rScale which is the extracted
+ // scale from a text transformation. A copy is modified so that it contains only positive
+ // scalings and XY-equal scalings to allow to get a non-X-scaled Vcl-Font for TextLayouter.
+ // rScale is adapted accordingly to contain the corrected scale which would need to be
+ // applied to e.g. outlines received from TextLayouter under usage of fontScale. This
+ // includes Y-Scale, X-Scale-correction and mirrorings.
+ basegfx::B2DVector getCorrectedScaleAndFontScale(basegfx::B2DVector& rScale)
+ {
+ // copy input value
+ basegfx::B2DVector aFontScale(rScale);
+
+ // correct FontHeight settings
+ if(basegfx::fTools::equalZero(aFontScale.getY()))
+ {
+ // no font height; choose one and adapt scale to get back to original scaling
+ static double fDefaultFontScale(100.0);
+ rScale.setY(1.0 / fDefaultFontScale);
+ aFontScale.setY(fDefaultFontScale);
+ }
+ else if(basegfx::fTools::less(aFontScale.getY(), 0.0))
+ {
+ // negative font height; invert and adapt scale to get back to original scaling
+ aFontScale.setY(-aFontScale.getY());
+ rScale.setY(-1.0);
+ }
+ else
+ {
+ // positive font height; adapt scale; scaling will be part of the polygons
+ rScale.setY(1.0);
+ }
+
+ // correct FontWidth settings
+ if(basegfx::fTools::equal(aFontScale.getX(), aFontScale.getY()))
+ {
+ // no FontScale, adapt scale
+ rScale.setX(1.0);
+ }
+ else
+ {
+ // If FontScale is used, force to no FontScale to get a non-scaled VCL font.
+ // Adapt scaling in X accordingly.
+ rScale.setX(aFontScale.getX() / aFontScale.getY());
+ aFontScale.setX(aFontScale.getY());
+ }
+
+ return aFontScale;
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ void TextSimplePortionPrimitive2D::getTextOutlinesAndTransformation(basegfx::B2DPolyPolygonVector& rTarget, basegfx::B2DHomMatrix& rTransformation) const
+ {
+ if(getTextLength())
+ {
+ // decompose object transformation to single values
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+
+ // if decomposition returns false, create no geometry since e.g. scaling may
+ // be zero
+ if(getTextTransform().decompose(aScale, aTranslate, fRotate, fShearX))
+ {
+ // handle special case: If scale is negative in (x,y) (3rd quadrant), it can
+ // be expressed as rotation by PI
+ if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aScale = basegfx::absolute(aScale);
+ fRotate += F_PI;
+ }
+
+ // for the TextLayouterDevice, it is necessary to have a scaling representing
+ // the font size. Since we want to extract polygons here, it is okay to
+ // work just with scaling and to ignore shear, rotation and translation,
+ // all that can be applied to the polygons later
+ const basegfx::B2DVector aFontScale(getCorrectedScaleAndFontScale(aScale));
+
+ // prepare textlayoutdevice
+ TextLayouterDevice aTextLayouter;
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ aFontScale.getX(),
+ aFontScale.getY(),
+ getLocale());
+
+ // When getting outlines from stretched text (aScale.getX() != 1.0) it
+ // is necessary to inverse-scale the DXArray (if used) to not get the
+ // outlines already aligned to given, but wrong DXArray
+ if(getDXArray().size() && !basegfx::fTools::equal(aScale.getX(), 1.0))
+ {
+ ::std::vector< double > aScaledDXArray = getDXArray();
+ const double fDXArrayScale(1.0 / aScale.getX());
+
+ for(sal_uInt32 a(0); a < aScaledDXArray.size(); a++)
+ {
+ aScaledDXArray[a] *= fDXArrayScale;
+ }
+
+ // get the text outlines
+ aTextLayouter.getTextOutlines(
+ rTarget,
+ getText(),
+ getTextPosition(),
+ getTextLength(),
+ aScaledDXArray);
+ }
+ else
+ {
+ // get the text outlines
+ aTextLayouter.getTextOutlines(
+ rTarget,
+ getText(),
+ getTextPosition(),
+ getTextLength(),
+ getDXArray());
+ }
+
+ // create primitives for the outlines
+ const sal_uInt32 nCount(rTarget.size());
+
+ if(nCount)
+ {
+ // prepare object transformation for polygons
+ rTransformation.identity();
+ rTransformation.scale(aScale.getX(), aScale.getY());
+ rTransformation.shearX(fShearX);
+ rTransformation.rotate(fRotate);
+ rTransformation.translate(aTranslate.getX(), aTranslate.getY());
+ }
+ }
+ }
+ }
+
+ Primitive2DSequence TextSimplePortionPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ Primitive2DSequence aRetval;
+
+ if(getTextLength())
+ {
+ basegfx::B2DPolyPolygonVector aB2DPolyPolyVector;
+ basegfx::B2DHomMatrix aPolygonTransform;
+
+ // get text outlines and their object transformation
+ getTextOutlinesAndTransformation(aB2DPolyPolyVector, aPolygonTransform);
+
+ // create primitives for the outlines
+ const sal_uInt32 nCount(aB2DPolyPolyVector.size());
+
+ if(nCount)
+ {
+ // alloc space for the primitives
+ aRetval.realloc(nCount);
+
+ // color-filled polypolygons
+ for(sal_uInt32 a(0L); a < nCount; a++)
+ {
+ // prepare polypolygon
+ basegfx::B2DPolyPolygon& rPolyPolygon = aB2DPolyPolyVector[a];
+ rPolyPolygon.transform(aPolygonTransform);
+ aRetval[a] = new PolyPolygonColorPrimitive2D(rPolyPolygon, getFontColor());
+ }
+
+ if(getFontAttributes().getOutline())
+ {
+ // decompose polygon transformation to single values
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ aPolygonTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // create outline text effect with current content and replace
+ Primitive2DReference aNewTextEffect(new TextEffectPrimitive2D(
+ aRetval,
+ aTranslate,
+ fRotate,
+ TEXTEFFECTSTYLE2D_OUTLINE));
+
+ aRetval = Primitive2DSequence(&aNewTextEffect, 1);
+ }
+ }
+ }
+
+ return aRetval;
+ }
+
+ TextSimplePortionPrimitive2D::TextSimplePortionPrimitive2D(
+ const basegfx::B2DHomMatrix& rNewTransform,
+ const String& rText,
+ xub_StrLen aTextPosition,
+ xub_StrLen aTextLength,
+ const ::std::vector< double >& rDXArray,
+ const FontAttributes& rFontAttributes,
+ const ::com::sun::star::lang::Locale& rLocale,
+ const basegfx::BColor& rFontColor)
+ : BasePrimitive2D(),
+ maTextTransform(rNewTransform),
+ maText(rText),
+ maTextPosition(aTextPosition),
+ maTextLength(aTextLength),
+ maDXArray(rDXArray),
+ maFontAttributes(rFontAttributes),
+ maLocale(rLocale),
+ maFontColor(rFontColor),
+ maB2DRange()
+ {
+#ifdef DBG_UTIL
+ const xub_StrLen aStringLength(getText().Len());
+ OSL_ENSURE(aStringLength >= getTextPosition() && aStringLength >= getTextPosition() + getTextLength(),
+ "TextSimplePortionPrimitive2D with text out of range (!)");
+#endif
+ }
+
+ bool impLocalesAreEqual(const ::com::sun::star::lang::Locale& rA, const ::com::sun::star::lang::Locale& rB)
+ {
+ return (rA.Language == rB.Language
+ && rA.Country == rB.Country
+ && rA.Variant == rB.Variant);
+ }
+
+ bool TextSimplePortionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const TextSimplePortionPrimitive2D& rCompare = (TextSimplePortionPrimitive2D&)rPrimitive;
+
+ return (getTextTransform() == rCompare.getTextTransform()
+ && getText() == rCompare.getText()
+ && getTextPosition() == rCompare.getTextPosition()
+ && getTextLength() == rCompare.getTextLength()
+ && getDXArray() == rCompare.getDXArray()
+ && getFontAttributes() == rCompare.getFontAttributes()
+ && impLocalesAreEqual(getLocale(), rCompare.getLocale())
+ && getFontColor() == rCompare.getFontColor());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange TextSimplePortionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ if(maB2DRange.isEmpty() && getTextLength())
+ {
+ // get TextBoundRect as base size
+ // decompose object transformation to single values
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+
+ if(getTextTransform().decompose(aScale, aTranslate, fRotate, fShearX))
+ {
+ // for the TextLayouterDevice, it is necessary to have a scaling representing
+ // the font size. Since we want to extract polygons here, it is okay to
+ // work just with scaling and to ignore shear, rotation and translation,
+ // all that can be applied to the polygons later
+ const basegfx::B2DVector aFontScale(getCorrectedScaleAndFontScale(aScale));
+
+ // prepare textlayoutdevice
+ TextLayouterDevice aTextLayouter;
+ aTextLayouter.setFontAttributes(
+ getFontAttributes(),
+ aFontScale.getX(),
+ aFontScale.getY(),
+ getLocale());
+
+ // get basic text range
+ basegfx::B2DRange aNewRange(aTextLayouter.getTextBoundRect(getText(), getTextPosition(), getTextLength()));
+
+ // #i104432#, #i102556# take empty results into account
+ if(!aNewRange.isEmpty())
+ {
+ // prepare object transformation for range
+ basegfx::B2DHomMatrix aRangeTransformation;
+
+ aRangeTransformation.scale(aScale.getX(), aScale.getY());
+ aRangeTransformation.shearX(fShearX);
+ aRangeTransformation.rotate(fRotate);
+ aRangeTransformation.translate(aTranslate.getX(), aTranslate.getY());
+
+ // apply range transformation to it
+ aNewRange.transform(aRangeTransformation);
+
+ // assign to buffered value
+ const_cast< TextSimplePortionPrimitive2D* >(this)->maB2DRange = aNewRange;
+ }
+ }
+ }
+
+ return maB2DRange;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TextSimplePortionPrimitive2D, PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/transformprimitive2d.cxx b/drawinglayer/source/primitive2d/transformprimitive2d.cxx
new file mode 100644
index 000000000000..7fe8293df854
--- /dev/null
+++ b/drawinglayer/source/primitive2d/transformprimitive2d.cxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: transformprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ TransformPrimitive2D::TransformPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransformation,
+ const Primitive2DSequence& rChildren)
+ : GroupPrimitive2D(rChildren),
+ maTransformation(rTransformation)
+ {
+ }
+
+ bool TransformPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const TransformPrimitive2D& rCompare = static_cast< const TransformPrimitive2D& >(rPrimitive);
+
+ return (getTransformation() == rCompare.getTransformation());
+ }
+
+ return false;
+ }
+
+ basegfx::B2DRange TransformPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ basegfx::B2DRange aRetval(getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation));
+ aRetval.transform(getTransformation());
+ return aRetval;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(TransformPrimitive2D, PRIMITIVE2D_ID_TRANSFORMPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx b/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx
new file mode 100644
index 000000000000..49039e1a6e5c
--- /dev/null
+++ b/drawinglayer/source/primitive2d/unifiedalphaprimitive2d.cxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: unifiedalphaprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/alphaprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence UnifiedAlphaPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+ {
+ if(0.0 == getAlpha())
+ {
+ // no transparence used, so just use the content
+ return getChildren();
+ }
+ else if(getAlpha() > 0.0 && getAlpha() < 1.0)
+ {
+ // The idea is to create a AlphaPrimitive2D with alpha content using a fill color
+ // corresponding to the alpha value. Problem is that in most systems, the right
+ // and bottom pixel array is not filled when filling polygons, thus this would not
+ // always produce a complete alpha bitmap. There are some solutions:
+ //
+ // - Grow the used polygon range by one discrete unit in X and Y. This
+ // will make the decomposition view-dependent.
+ //
+ // - For all filled polygon renderings, dra wthe polygon outline extra. This
+ // would lead to unwanted side effects when using concatenated polygons.
+ //
+ // - At this decomposition, add a filled polygon and a hairline polygon. This
+ // solution stays view-independent.
+ //
+ // I will take the last one here. The small overhead of two primitives will only be
+ // used when UnifiedAlphaPrimitive2D is not handled directly.
+ const basegfx::B2DRange aPolygonRange(getB2DRangeFromPrimitive2DSequence(getChildren(), rViewInformation));
+ const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aPolygonRange));
+ const basegfx::BColor aGray(getAlpha(), getAlpha(), getAlpha());
+ Primitive2DSequence aAlphaContent(2);
+
+ aAlphaContent[0] = Primitive2DReference(new PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPolygon), aGray));
+ aAlphaContent[1] = Primitive2DReference(new PolygonHairlinePrimitive2D(aPolygon, aGray));
+
+ // create sub-transparence group with a gray-colored rectangular fill polygon
+ const Primitive2DReference xRefB(new AlphaPrimitive2D(getChildren(), aAlphaContent));
+ return Primitive2DSequence(&xRefB, 1L);
+ }
+ else
+ {
+ // completely transparent or invalid definition, add nothing
+ return Primitive2DSequence();
+ }
+ }
+
+ UnifiedAlphaPrimitive2D::UnifiedAlphaPrimitive2D(
+ const Primitive2DSequence& rChildren,
+ double fAlpha)
+ : GroupPrimitive2D(rChildren),
+ mfAlpha(fAlpha)
+ {
+ }
+
+ bool UnifiedAlphaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(GroupPrimitive2D::operator==(rPrimitive))
+ {
+ const UnifiedAlphaPrimitive2D& rCompare = (UnifiedAlphaPrimitive2D&)rPrimitive;
+
+ return (getAlpha() == rCompare.getAlpha());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(UnifiedAlphaPrimitive2D, PRIMITIVE2D_ID_UNIFIEDALPHAPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx b/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx
new file mode 100644
index 000000000000..93a51d5379b3
--- /dev/null
+++ b/drawinglayer/source/primitive2d/wrongspellprimitive2d.cxx
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: wrongspellprimitive2d.cxx,v $
+ *
+ * $Revision: 1.5 $
+ *
+ * last change: $Author: aw $ $Date: 2008-05-27 14:11: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
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace primitive2d
+ {
+ Primitive2DSequence WrongSpellPrimitive2D::createLocalDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+ {
+ // ATM this decompose is view-independent, what the original VCL-Display is not. To mimic
+ // the old behaviour here if wanted it is necessary to add get2DDecomposition and implement
+ // it similar to the usage in e.g. HelplinePrimitive2D. Remembering the ViewTransformation
+ // should be enough then.
+ // The view-independent wavelines work well (if You ask me). Maybe the old VCL-Behaviour is only
+ // in place because it was not possible/too expensive at that time to scale the wavelines with the
+ // view...
+ // With the VCL-PixelRenderer this will not even be used since it implements WrongSpellPrimitive2D
+ // directly and mimics the old VCL-Display there. If You implemented a new renderer without
+ // direct WrongSpellPrimitive2D support, You may want to do the described change here.
+
+ // get the font height (part of scale), so decompose the matrix
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ getTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // calculate distances based on a static default (to allow testing in debugger)
+ static double fDefaultDistance(0.03);
+ const double fFontHeight(aScale.getY());
+ const double fUnderlineDistance(fFontHeight * fDefaultDistance);
+ const double fWaveWidth(2.0 * fUnderlineDistance);
+
+ // the Y-distance needs to be relativated to FontHeight since the points get
+ // transformed with the transformation containing that scale already.
+ const double fRelativeUnderlineDistance(basegfx::fTools::equalZero(aScale.getY()) ? 0.0 : fUnderlineDistance / aScale.getY());
+ basegfx::B2DPoint aStart(getStart(), fRelativeUnderlineDistance);
+ basegfx::B2DPoint aStop(getStop(), fRelativeUnderlineDistance);
+ basegfx::B2DPolygon aPolygon;
+
+ aPolygon.append(getTransformation() * aStart);
+ aPolygon.append(getTransformation() * aStop);
+
+ // prepare line attribute
+ const attribute::LineAttribute aLineAttribute(getColor());
+
+ // create the waveline primitive
+ Primitive2DReference xPrimitive(new PolygonWavePrimitive2D(aPolygon, aLineAttribute, fWaveWidth, 0.5 * fWaveWidth));
+ Primitive2DSequence xRetval(&xPrimitive, 1);
+
+ return xRetval;
+ }
+
+ WrongSpellPrimitive2D::WrongSpellPrimitive2D(
+ const basegfx::B2DHomMatrix& rTransformation,
+ double fStart,
+ double fStop,
+ const basegfx::BColor& rColor)
+ : BasePrimitive2D(),
+ maTransformation(rTransformation),
+ mfStart(fStart),
+ mfStop(fStop),
+ maColor(rColor)
+ {
+ }
+
+ bool WrongSpellPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+ {
+ if(BasePrimitive2D::operator==(rPrimitive))
+ {
+ const WrongSpellPrimitive2D& rCompare = (WrongSpellPrimitive2D&)rPrimitive;
+
+ return (getTransformation() == rCompare.getTransformation()
+ && getStart() == rCompare.getStart()
+ && getStop() == rCompare.getStop()
+ && getColor() == rCompare.getColor());
+ }
+
+ return false;
+ }
+
+ // provide unique ID
+ ImplPrimitrive2DIDBlock(WrongSpellPrimitive2D, PRIMITIVE2D_ID_WRONGSPELLPRIMITIVE2D)
+
+ } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof