summaryrefslogtreecommitdiff
path: root/drawinglayer/source/texture
diff options
context:
space:
mode:
authorArmin Weiss <aw@openoffice.org>2006-08-09 16:00:16 +0000
committerArmin Weiss <aw@openoffice.org>2006-08-09 16:00:16 +0000
commit9927e1ca23c8353c880a3ae0a196caabdf747c4b (patch)
tree474f197a8ec74e16d64c3f31f389dbb07e7cd7f9 /drawinglayer/source/texture
parent4d0a693b85b6191d351f7a6bb0e5c30b2e47eca8 (diff)
#i39532#
Diffstat (limited to 'drawinglayer/source/texture')
-rw-r--r--drawinglayer/source/texture/makefile.mk51
-rw-r--r--drawinglayer/source/texture/texture.cxx1090
2 files changed, 1141 insertions, 0 deletions
diff --git a/drawinglayer/source/texture/makefile.mk b/drawinglayer/source/texture/makefile.mk
new file mode 100644
index 000000000000..877a929a8f1e
--- /dev/null
+++ b/drawinglayer/source/texture/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: aw $ $Date: 2006-08-09 16:58:20 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=drawinglayer
+TARGET=texture
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/texture.obj
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx
new file mode 100644
index 000000000000..afc6e63071ce
--- /dev/null
+++ b/drawinglayer/source/texture/texture.cxx
@@ -0,0 +1,1090 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: texture.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: aw $ $Date: 2006-08-09 16:58:20 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef _DRAWINGLAYER_TEXTURE_TEXTURE_HXX
+#include <drawinglayer/texture/texture.hxx>
+#endif
+
+#ifndef _BGFX_NUMERIC_FTOOLS_HXX
+#include <basegfx/numeric/ftools.hxx>
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvx::geoTexSvx()
+ {
+ }
+
+ geoTexSvx::~geoTexSvx()
+ {
+ }
+
+ bool geoTexSvx::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ // default implementation says yes (no data -> no difference)
+ return true;
+ }
+
+ void geoTexSvx::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ // default implementation does nothing
+ }
+
+ void geoTexSvx::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ // base implementation creates random color (for testing only, may also be pure virtual)
+ rBColor.setRed((rand() & 0x7fff) / 32767.0);
+ rBColor.setGreen((rand() & 0x7fff) / 32767.0);
+ rBColor.setBlue((rand() & 0x7fff) / 32767.0);
+ }
+
+ void geoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
+ {
+ // base implementation uses inverse of luminance of solved color
+ basegfx::BColor aBaseColor;
+ modifyBColor(rUV, aBaseColor, rfOpacity);
+ rfOpacity = 1.0 - aBaseColor.luminance();
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ void geoTexSvxGradient::impAppendMatrix(::std::vector< basegfx::B2DHomMatrix >& rMatrices, const basegfx::B2DRange& rRange)
+ {
+ basegfx::B2DHomMatrix aNew;
+ aNew.set(0, 0, rRange.getWidth());
+ aNew.set(1, 1, rRange.getHeight());
+ aNew.set(0, 2, rRange.getMinX());
+ aNew.set(1, 2, rRange.getMinY());
+ rMatrices.push_back(maTextureTransform * aNew);
+ }
+
+ void geoTexSvxGradient::impAppendColorsRadial(::std::vector< basegfx::BColor >& rColors)
+ {
+ if(mnSteps)
+ {
+ rColors.push_back(maStart);
+
+ for(sal_uInt32 a(1L); a < mnSteps - 1L; a++)
+ {
+ rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)mnSteps));
+ }
+
+ rColors.push_back(maEnd);
+ }
+ }
+
+ geoTexSvxGradient::geoTexSvxGradient(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder)
+ : maTargetRange(rTargetRange),
+ maStart(rStart),
+ maEnd(rEnd),
+ mnSteps(nSteps),
+ mfAspect(1.0),
+ mfBorder(fBorder)
+ {
+ }
+
+ geoTexSvxGradient::~geoTexSvxGradient()
+ {
+ }
+
+ bool geoTexSvxGradient::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxGradient* pCompare = dynamic_cast< const geoTexSvxGradient* >(&rGeoTexSvx);
+ return (pCompare
+ && maTextureTransform == pCompare->maTextureTransform
+ && maTargetRange == pCompare->maTargetRange
+ && mnSteps == pCompare->mnSteps
+ && mfAspect == pCompare->mfAspect
+ && mfBorder == pCompare->mfBorder);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientLinear::geoTexSvxGradientLinear(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(0.0, -mfBorder);
+ const double fSizeWithoutBorder(1.0 - mfBorder);
+
+ if(!basegfx::fTools::equal(fSizeWithoutBorder, 0.0))
+ {
+ maBackTextureTransform.scale(1.0, 1.0 / fSizeWithoutBorder);
+ }
+ }
+
+ geoTexSvxGradientLinear::~geoTexSvxGradientLinear()
+ {
+ }
+
+ void geoTexSvxGradientLinear::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fTop(mfBorder);
+ const double fStripeWidth((1.0 - fTop) / mnSteps);
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ const double fOffsetUpper(fStripeWidth * (double)a);
+
+ // create matrix
+ const basegfx::B2DRange aRect(0.0, fTop + fOffsetUpper, 1.0, 1.0);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientLinear::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ if(mnSteps)
+ {
+ rColors.push_back(maStart);
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)(mnSteps + 1L)));
+ }
+ }
+ }
+
+ void geoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+
+ if(basegfx::fTools::lessOrEqual(aCoor.getY(), 0.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ if(basegfx::fTools::moreOrEqual(aCoor.getY(), 1.0))
+ {
+ rBColor = maEnd;
+ return;
+ }
+
+ double fScaler(aCoor.getY());
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps + 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientAxial::geoTexSvxGradientAxial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(0.0, -0.5);
+ const double fSizeWithoutBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fSizeWithoutBorder, 0.0))
+ {
+ maBackTextureTransform.scale(1.0, 1.0 / fSizeWithoutBorder);
+ }
+
+ // fill internal steps for getBColor implementation
+ mfInternalSteps = (double)((mnSteps * 2L) - 1L);
+ }
+
+ geoTexSvxGradientAxial::~geoTexSvxGradientAxial()
+ {
+ }
+
+ void geoTexSvxGradientAxial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder(mfBorder * 0.5);
+ double fTop(fHalfBorder);
+ double fBottom(1.0 - fHalfBorder);
+ const double fStripeWidth((fBottom - fTop) / ((mnSteps * 2L) - 1L));
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ const double fOffset(fStripeWidth * (double)a);
+
+ // create matrix
+ const basegfx::B2DRange aRect(0.0, fTop + fOffset, 1.0, fBottom - fOffset);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientAxial::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ if(mnSteps)
+ {
+ rColors.push_back(maEnd);
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ rColors.push_back(interpolate(maEnd, maStart, (double)a / (double)mnSteps));
+ }
+ }
+ }
+
+ void geoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(basegfx::fTools::moreOrEqual(fAbsY, 1.0))
+ {
+ rBColor = maEnd;
+ return;
+ }
+
+ double fScaler(fAbsY);
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(((fScaler * mfInternalSteps) + 1.0) / 2.0) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientRadial::geoTexSvxGradientRadial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
+ fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
+ fTargetSizeX = fOriginalDiag;
+ fTargetSizeY = fOriginalDiag;
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use original target size
+ fTargetOffsetX += (fOffsetX - 0.5) * maTargetRange.getWidth();
+ fTargetOffsetY += (fOffsetY - 0.5) * maTargetRange.getHeight();
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientRadial::~geoTexSvxGradientRadial()
+ {
+ }
+
+ void geoTexSvxGradientRadial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ fIncrementY = (fBottom - fTop) / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+ else
+ {
+ fIncrementX = (fRight - fLeft) / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientRadial::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fDist(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY());
+
+ if(basegfx::fTools::moreOrEqual(fDist, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - sqrt(fDist));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientElliptical::geoTexSvxGradientElliptical(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX;
+ fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY;
+ fTargetSizeX = 1.4142 * fTargetSizeX;
+ fTargetSizeY = 1.4142 * fTargetSizeY;
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use original target size
+ fTargetOffsetX += (fOffsetX - 0.5) * maTargetRange.getWidth();
+ fTargetOffsetY += (fOffsetY - 0.5) * maTargetRange.getHeight();
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientElliptical::~geoTexSvxGradientElliptical()
+ {
+ }
+
+ void geoTexSvxGradientElliptical::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ fIncrementY = (fBottom - fTop) / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+ else
+ {
+ fIncrementX = (fRight - fLeft) / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientElliptical::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fDist(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY());
+
+ if(basegfx::fTools::moreOrEqual(fDist, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - sqrt(fDist));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientSquare::geoTexSvxGradientSquare(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use scaled target size
+ fTargetOffsetX += (fOffsetX - 0.5) * fTargetSizeX;
+ fTargetOffsetY += (fOffsetY - 0.5) * fTargetSizeY;
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientSquare::~geoTexSvxGradientSquare()
+ {
+ }
+
+ void geoTexSvxGradientSquare::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ const double fWidth(fRight - fLeft);
+ const double fHalfAspectExpansion(((mfAspect - 1.0) * 0.5) * fWidth);
+ fTop -= fHalfAspectExpansion;
+ fBottom += fHalfAspectExpansion;
+ fIncrementX = fWidth / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+ else
+ {
+ const double fHeight(fBottom - fTop);
+ const double fHalfAspectExpansion((((1.0 / mfAspect) - 1.0) * 0.5) * fHeight);
+ fLeft -= fHalfAspectExpansion;
+ fRight += fHalfAspectExpansion;
+ fIncrementY = fHeight / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientSquare::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fAbsX(fabs(aCoor.getX()));
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(basegfx::fTools::moreOrEqual(fAbsX, 1.0) || basegfx::fTools::moreOrEqual(fAbsY, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxGradientRect::geoTexSvxGradientRect(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
+ : geoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
+ {
+ double fTargetSizeX(maTargetRange.getWidth());
+ double fTargetSizeY(maTargetRange.getHeight());
+ double fTargetOffsetX(maTargetRange.getMinX());
+ double fTargetOffsetY(maTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add defined offsets after rotation
+ if(0.5 != fOffsetX || 0.5 != fOffsetY)
+ {
+ // use scaled target size
+ fTargetOffsetX += (fOffsetX - 0.5) * fTargetSizeX;
+ fTargetOffsetY += (fOffsetY - 0.5) * fTargetSizeY;
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare aspect for texture
+ mfAspect = (0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ maBackTextureTransform.translate(-0.5, -0.5);
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+
+ if(!basegfx::fTools::equal(fHalfBorder, 0.0))
+ {
+ const double fFactor(1.0 / fHalfBorder);
+ maBackTextureTransform.scale(fFactor, fFactor);
+ }
+ }
+
+ geoTexSvxGradientRect::~geoTexSvxGradientRect()
+ {
+ }
+
+ void geoTexSvxGradientRect::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ if(mnSteps)
+ {
+ const double fHalfBorder((1.0 - mfBorder) * 0.5);
+ double fLeft(0.5 - fHalfBorder);
+ double fTop(0.5 - fHalfBorder);
+ double fRight(0.5 + fHalfBorder);
+ double fBottom(0.5 + fHalfBorder);
+ double fIncrementX, fIncrementY;
+
+ if(mfAspect > 1.0)
+ {
+ fIncrementY = (fBottom - fTop) / (double)(mnSteps * 2L);
+ fIncrementX = fIncrementY / mfAspect;
+ }
+ else
+ {
+ fIncrementX = (fRight - fLeft) / (double)(mnSteps * 2L);
+ fIncrementY = fIncrementX * mfAspect;
+ }
+
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // next step
+ fLeft += fIncrementX;
+ fRight -= fIncrementX;
+ fTop += fIncrementY;
+ fBottom -= fIncrementY;
+
+ // create matrix
+ const basegfx::B2DRange aRect(fLeft, fTop, fRight, fBottom);
+ impAppendMatrix(rMatrices, aRect);
+ }
+ }
+ }
+
+ void geoTexSvxGradientRect::appendColors(::std::vector< basegfx::BColor >& rColors)
+ {
+ impAppendColorsRadial(rColors);
+ }
+
+ void geoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ const double fAbsX(fabs(aCoor.getX()));
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(basegfx::fTools::moreOrEqual(fAbsX, 1.0) || basegfx::fTools::moreOrEqual(fAbsY, 1.0))
+ {
+ rBColor = maStart;
+ return;
+ }
+
+ double fScaler(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
+
+ if(mnSteps > 2L && mnSteps < 128L)
+ {
+ fScaler = floor(fScaler * (double)mnSteps) / (double)(mnSteps - 1L);
+ }
+
+ rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxHatch::geoTexSvxHatch(const basegfx::B2DRange& rTargetRange, double fDistance, double fAngle)
+ : mfDistance(0.1),
+ mfAngle(fAngle),
+ mnSteps(10L)
+ {
+ double fTargetSizeX(rTargetRange.getWidth());
+ double fTargetSizeY(rTargetRange.getHeight());
+ double fTargetOffsetX(rTargetRange.getMinX());
+ double fTargetOffsetY(rTargetRange.getMinY());
+
+ // add object expansion
+ if(0.0 != fAngle)
+ {
+ const double fAbsCos(fabs(cos(fAngle)));
+ const double fAbsSin(fabs(sin(fAngle)));
+ const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
+ const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+ fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
+ fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
+ fTargetSizeX = fNewX;
+ fTargetSizeY = fNewY;
+ }
+
+ // add object scale before rotate
+ maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+
+ // add texture rotate after scale to keep perpendicular angles
+ if(0.0 != fAngle)
+ {
+ basegfx::B2DPoint aCenter(0.5, 0.5);
+ aCenter *= maTextureTransform;
+
+ maTextureTransform.translate(-aCenter.getX(), -aCenter.getY());
+ maTextureTransform.rotate(fAngle);
+ maTextureTransform.translate(aCenter.getX(), aCenter.getY());
+ }
+
+ // add object translate
+ maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+
+ // prepare height for texture
+ const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
+ mnSteps = basegfx::fround(fSteps + 0.5);
+ mfDistance = 1.0 / fSteps;
+
+ // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
+ maBackTextureTransform = maTextureTransform;
+ maBackTextureTransform.invert();
+ }
+
+ geoTexSvxHatch::~geoTexSvxHatch()
+ {
+ }
+
+ bool geoTexSvxHatch::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxHatch* pCompare = dynamic_cast< const geoTexSvxHatch* >(&rGeoTexSvx);
+ return (pCompare
+ && maTextureTransform == pCompare->maTextureTransform
+ && mfDistance == pCompare->mfDistance
+ && mfAngle == pCompare->mfAngle
+ && mnSteps == pCompare->mnSteps);
+ }
+
+ void geoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ for(sal_uInt32 a(1L); a < mnSteps; a++)
+ {
+ // create matrix
+ const double fOffset(mfDistance * (double)a);
+ basegfx::B2DHomMatrix aNew;
+ aNew.set(1, 2, fOffset);
+ rMatrices.push_back(maTextureTransform * aNew);
+ }
+ }
+
+ double geoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
+ {
+ const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
+ return fmod(aCoor.getY(), mfDistance);
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+ namespace texture
+ {
+ geoTexSvxTiled::geoTexSvxTiled(const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
+ : maTopLeft(rTopLeft),
+ maSize(rSize)
+ {
+ if(basegfx::fTools::lessOrEqual(maSize.getX(), 0.0))
+ {
+ maSize.setX(1.0);
+ }
+
+ if(basegfx::fTools::lessOrEqual(maSize.getY(), 0.0))
+ {
+ maSize.setY(1.0);
+ }
+ }
+
+ geoTexSvxTiled::~geoTexSvxTiled()
+ {
+ }
+
+ bool geoTexSvxTiled::operator==(const geoTexSvx& rGeoTexSvx) const
+ {
+ const geoTexSvxTiled* pCompare = dynamic_cast< const geoTexSvxTiled* >(&rGeoTexSvx);
+ return (pCompare
+ && maTopLeft == pCompare->maTopLeft
+ && maSize == pCompare->maSize);
+ }
+
+ void geoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
+ {
+ double fStartX(maTopLeft.getX());
+ double fStartY(maTopLeft.getY());
+
+ if(basegfx::fTools::more(fStartX, 0.0))
+ {
+ fStartX -= (floor(fStartX / maSize.getX()) + 1.0) * maSize.getX();
+ }
+
+ if(basegfx::fTools::less(fStartX + maSize.getX(), 0.0))
+ {
+ fStartX += floor(-fStartX / maSize.getX()) * maSize.getX();
+ }
+
+ if(basegfx::fTools::more(fStartY, 0.0))
+ {
+ fStartY -= (floor(fStartY / maSize.getY()) + 1.0) * maSize.getY();
+ }
+
+ if(basegfx::fTools::less(fStartY + maSize.getY(), 0.0))
+ {
+ fStartY += floor(-fStartY / maSize.getY()) * maSize.getY();
+ }
+
+ for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += maSize.getY())
+ {
+ for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += maSize.getX())
+ {
+ basegfx::B2DHomMatrix aNew;
+
+ aNew.set(0, 0, maSize.getX());
+ aNew.set(1, 1, maSize.getY());
+ aNew.set(0, 2, fPosX);
+ aNew.set(1, 2, fPosY);
+
+ rMatrices.push_back(aNew);
+ }
+ }
+ }
+ } // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof