Files
libreoffice/drawinglayer/source/texture/texture.cxx

1091 lines
40 KiB
C++
Raw Normal View History

2006-08-09 16:00:16 +00:00
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: texture.cxx,v $
*
2006-10-19 09:40:02 +00:00
* $Revision: 1.3 $
2006-08-09 16:00:16 +00:00
*
2006-10-19 09:40:02 +00:00
* last change: $Author: aw $ $Date: 2006-10-19 10:39:34 $
2006-08-09 16:00:16 +00:00
*
* 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
*
************************************************************************/
2006-10-19 09:40:02 +00:00
#ifndef INCLUDED_DRAWINGLAYER_TEXTURE_TEXTURE_HXX
2006-08-09 16:00:16 +00:00
#include <drawinglayer/texture/texture.hxx>
#endif
#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
2006-10-19 09:40:02 +00:00
GeoTexSvx::GeoTexSvx()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
GeoTexSvx::~GeoTexSvx()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
bool GeoTexSvx::operator==(const GeoTexSvx& /*rGeoTexSvx*/) const
2006-08-09 16:00:16 +00:00
{
// default implementation says yes (no data -> no difference)
return true;
}
2006-10-19 09:40:02 +00:00
void GeoTexSvx::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& /*rMatrices*/)
2006-08-09 16:00:16 +00:00
{
// default implementation does nothing
}
2006-10-19 09:40:02 +00:00
void GeoTexSvx::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
// 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);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
2006-08-09 16:00:16 +00:00
{
// 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
{
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradient::impAppendMatrix(::std::vector< basegfx::B2DHomMatrix >& rMatrices, const basegfx::B2DRange& rRange)
2006-08-09 16:00:16 +00:00
{
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);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradient::impAppendColorsRadial(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradient::GeoTexSvxGradient(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder)
2006-08-09 16:00:16 +00:00
: maTargetRange(rTargetRange),
maStart(rStart),
maEnd(rEnd),
mnSteps(nSteps),
mfAspect(1.0),
mfBorder(fBorder)
{
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradient::~GeoTexSvxGradient()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
2006-08-09 16:00:16 +00:00
{
2006-10-19 09:40:02 +00:00
const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
2006-08-09 16:00:16 +00:00
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
{
2006-10-19 09:40:02 +00:00
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)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientLinear::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientLinear::appendColors(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
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)));
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
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
{
2006-10-19 09:40:02 +00:00
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)
2006-08-09 16:00:16 +00:00
{
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);
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientAxial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientAxial::appendColors(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
if(mnSteps)
{
rColors.push_back(maEnd);
for(sal_uInt32 a(1L); a < mnSteps; a++)
{
rColors.push_back(interpolate(maEnd, maStart, (double)a / (double)mnSteps));
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
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
{
2006-10-19 09:40:02 +00:00
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)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientRadial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientRadial::appendColors(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
impAppendColorsRadial(rColors);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
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
{
2006-10-19 09:40:02 +00:00
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)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientElliptical::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientElliptical::appendColors(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
impAppendColorsRadial(rColors);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
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
{
2006-10-19 09:40:02 +00:00
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)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientSquare::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientSquare::appendColors(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
impAppendColorsRadial(rColors);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
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
{
2006-10-19 09:40:02 +00:00
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)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientRect::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientRect::appendColors(::std::vector< basegfx::BColor >& rColors)
2006-08-09 16:00:16 +00:00
{
impAppendColorsRadial(rColors);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
2006-08-09 16:00:16 +00:00
{
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
{
2006-10-19 09:40:02 +00:00
GeoTexSvxHatch::GeoTexSvxHatch(const basegfx::B2DRange& rTargetRange, double fDistance, double fAngle)
2006-08-09 16:00:16 +00:00
: 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();
}
2006-10-19 09:40:02 +00:00
GeoTexSvxHatch::~GeoTexSvxHatch()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
bool GeoTexSvxHatch::operator==(const GeoTexSvx& rGeoTexSvx) const
2006-08-09 16:00:16 +00:00
{
2006-10-19 09:40:02 +00:00
const GeoTexSvxHatch* pCompare = dynamic_cast< const GeoTexSvxHatch* >(&rGeoTexSvx);
2006-08-09 16:00:16 +00:00
return (pCompare
&& maTextureTransform == pCompare->maTextureTransform
&& mfDistance == pCompare->mfDistance
&& mfAngle == pCompare->mfAngle
&& mnSteps == pCompare->mnSteps);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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);
}
}
2006-10-19 09:40:02 +00:00
double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
2006-08-09 16:00:16 +00:00
{
const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
return fmod(aCoor.getY(), mfDistance);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
2006-10-19 09:40:02 +00:00
GeoTexSvxTiled::GeoTexSvxTiled(const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
2006-08-09 16:00:16 +00:00
: 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);
}
}
2006-10-19 09:40:02 +00:00
GeoTexSvxTiled::~GeoTexSvxTiled()
2006-08-09 16:00:16 +00:00
{
}
2006-10-19 09:40:02 +00:00
bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
2006-08-09 16:00:16 +00:00
{
2006-10-19 09:40:02 +00:00
const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
2006-08-09 16:00:16 +00:00
return (pCompare
&& maTopLeft == pCompare->maTopLeft
&& maSize == pCompare->maSize);
}
2006-10-19 09:40:02 +00:00
void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
2006-08-09 16:00:16 +00:00
{
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