blob: d725dc92ab1661ec85caff82e5d55aebf82c382b [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_drawinglayer.hxx"
#include <drawinglayer/texture/texture.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/gradienttools.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
//////////////////////////////////////////////////////////////////////////////
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::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 (for testing only, may also be pure virtual)
basegfx::BColor aBaseColor;
modifyBColor(rUV, aBaseColor, rfOpacity);
rfOpacity = 1.0 - aBaseColor.luminance();
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradient::GeoTexSvxGradient(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 /* nSteps */,
double fBorder)
: GeoTexSvx(),
maGradientInfo(),
maDefinitionRange(rDefinitionRange),
maStart(rStart),
maEnd(rEnd),
mfBorder(fBorder)
{
}
GeoTexSvxGradient::~GeoTexSvxGradient()
{
}
bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
{
const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
return (pCompare
&& maGradientInfo == pCompare->maGradientInfo
&& maDefinitionRange == pCompare->maDefinitionRange
&& mfBorder == pCompare->mfBorder);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradientLinear::GeoTexSvxGradientLinear(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::B2DRange& rOutputRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 nSteps,
double fBorder,
double fAngle)
: GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder),
mfUnitMinX(0.0),
mfUnitWidth(1.0),
mfUnitMaxY(1.0)
{
maGradientInfo = basegfx::tools::createLinearODFGradientInfo(
rDefinitionRange,
nSteps,
fBorder,
fAngle);
if(rDefinitionRange != rOutputRange)
{
basegfx::B2DRange aInvOutputRange(rOutputRange);
aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
mfUnitMinX = aInvOutputRange.getMinX();
mfUnitWidth = aInvOutputRange.getWidth();
mfUnitMaxY = aInvOutputRange.getMaxY();
}
}
GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
{
}
void GeoTexSvxGradientLinear::appendTransformationsAndColors(
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
rOuterColor = maStart;
if(maGradientInfo.getSteps())
{
const double fStripeWidth(1.0 / maGradientInfo.getSteps());
B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
basegfx::B2DHomMatrix aPattern;
// bring from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
aPattern.scale(0.5, 0.5);
aPattern.translate(0.5, 0.5);
// scale and translate in X
aPattern.scale(mfUnitWidth, 1.0);
aPattern.translate(mfUnitMinX, 0.0);
for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
{
const double fPos(fStripeWidth * a);
basegfx::B2DHomMatrix aNew(aPattern);
// scale and translate in Y
double fHeight(1.0 - fPos);
if(a + 1 == maGradientInfo.getSteps() && mfUnitMaxY > 1.0)
{
fHeight += mfUnitMaxY - 1.0;
}
aNew.scale(1.0, fHeight);
aNew.translate(0.0, fPos);
// set at target
aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
// interpolate and set color
aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
rEntries.push_back(aB2DHomMatrixAndBColor);
}
}
}
void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getLinearGradientAlpha(rUV, maGradientInfo));
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::B2DRange& rOutputRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 nSteps,
double fBorder,
double fAngle)
: GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder),
mfUnitMinX(0.0),
mfUnitWidth(1.0)
{
maGradientInfo = basegfx::tools::createAxialODFGradientInfo(
rDefinitionRange,
nSteps,
fBorder,
fAngle);
if(rDefinitionRange != rOutputRange)
{
basegfx::B2DRange aInvOutputRange(rOutputRange);
aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
mfUnitMinX = aInvOutputRange.getMinX();
mfUnitWidth = aInvOutputRange.getWidth();
}
}
GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
{
}
void GeoTexSvxGradientAxial::appendTransformationsAndColors(
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
rOuterColor = maEnd;
if(maGradientInfo.getSteps())
{
const double fStripeWidth(1.0 / maGradientInfo.getSteps());
B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
{
const double fPos(fStripeWidth * a);
basegfx::B2DHomMatrix aNew;
// bring in X from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
aNew.scale(0.5, 1.0);
aNew.translate(0.5, 0.0);
// scale/translate in X
aNew.scale(mfUnitWidth, 1.0);
aNew.translate(mfUnitMinX, 0.0);
// already centerd in Y on X-Axis, just scale in Y
aNew.scale(1.0, 1.0 - fPos);
// set at target
aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
// interpolate and set color
aB2DHomMatrixAndBColor.maBColor = interpolate(maEnd, maStart, double(a) / double(maGradientInfo.getSteps() - 1));
rEntries.push_back(aB2DHomMatrixAndBColor);
}
}
}
void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getAxialGradientAlpha(rUV, maGradientInfo));
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradientRadial::GeoTexSvxGradientRadial(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 nSteps,
double fBorder,
double fOffsetX,
double fOffsetY)
: GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
{
maGradientInfo = basegfx::tools::createRadialODFGradientInfo(
rDefinitionRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder);
}
GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
{
}
void GeoTexSvxGradientRadial::appendTransformationsAndColors(
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
rOuterColor = maStart;
if(maGradientInfo.getSteps())
{
const double fStepSize(1.0 / maGradientInfo.getSteps());
B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
{
const double fSize(1.0 - (fStepSize * a));
aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fSize, fSize);
aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
rEntries.push_back(aB2DHomMatrixAndBColor);
}
}
}
void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getRadialGradientAlpha(rUV, maGradientInfo));
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 nSteps,
double fBorder,
double fOffsetX,
double fOffsetY,
double fAngle)
: GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
{
maGradientInfo = basegfx::tools::createEllipticalODFGradientInfo(
rDefinitionRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
{
}
void GeoTexSvxGradientElliptical::appendTransformationsAndColors(
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
rOuterColor = maStart;
if(maGradientInfo.getSteps())
{
double fWidth(1.0);
double fHeight(1.0);
double fIncrementX(0.0);
double fIncrementY(0.0);
if(maGradientInfo.getAspectRatio() > 1.0)
{
fIncrementY = fHeight / maGradientInfo.getSteps();
fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
}
else
{
fIncrementX = fWidth / maGradientInfo.getSteps();
fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
}
B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
{
// next step
fWidth -= fIncrementX;
fHeight -= fIncrementY;
aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fWidth, fHeight);
aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
rEntries.push_back(aB2DHomMatrixAndBColor);
}
}
}
void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getEllipticalGradientAlpha(rUV, maGradientInfo));
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradientSquare::GeoTexSvxGradientSquare(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 nSteps,
double fBorder,
double fOffsetX,
double fOffsetY,
double fAngle)
: GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
{
maGradientInfo = basegfx::tools::createSquareODFGradientInfo(
rDefinitionRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
{
}
void GeoTexSvxGradientSquare::appendTransformationsAndColors(
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
rOuterColor = maStart;
if(maGradientInfo.getSteps())
{
const double fStepSize(1.0 / maGradientInfo.getSteps());
B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
{
const double fSize(1.0 - (fStepSize * a));
aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fSize, fSize);
aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
rEntries.push_back(aB2DHomMatrixAndBColor);
}
}
}
void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getSquareGradientAlpha(rUV, maGradientInfo));
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxGradientRect::GeoTexSvxGradientRect(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
sal_uInt32 nSteps,
double fBorder,
double fOffsetX,
double fOffsetY,
double fAngle)
: GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
{
maGradientInfo = basegfx::tools::createRectangularODFGradientInfo(
rDefinitionRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
{
}
void GeoTexSvxGradientRect::appendTransformationsAndColors(
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
rOuterColor = maStart;
if(maGradientInfo.getSteps())
{
double fWidth(1.0);
double fHeight(1.0);
double fIncrementX(0.0);
double fIncrementY(0.0);
if(maGradientInfo.getAspectRatio() > 1.0)
{
fIncrementY = fHeight / maGradientInfo.getSteps();
fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
}
else
{
fIncrementX = fWidth / maGradientInfo.getSteps();
fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
}
B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
{
// next step
fWidth -= fIncrementX;
fHeight -= fIncrementY;
aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fWidth, fHeight);
aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
rEntries.push_back(aB2DHomMatrixAndBColor);
}
}
}
void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getRectangularGradientAlpha(rUV, maGradientInfo));
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxHatch::GeoTexSvxHatch(
const basegfx::B2DRange& rDefinitionRange,
const basegfx::B2DRange& rOutputRange,
double fDistance,
double fAngle)
: maOutputRange(rOutputRange),
maTextureTransform(),
maBackTextureTransform(),
mfDistance(0.1),
mfAngle(fAngle),
mnSteps(10),
mbDefinitionRangeEqualsOutputRange(rDefinitionRange == rOutputRange)
{
double fTargetSizeX(rDefinitionRange.getWidth());
double fTargetSizeY(rDefinitionRange.getHeight());
double fTargetOffsetX(rDefinitionRange.getMinX());
double fTargetOffsetY(rDefinitionRange.getMinY());
fAngle = -fAngle;
// 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 = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
* maTextureTransform;
}
// 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;
}
GeoTexSvxHatch::~GeoTexSvxHatch()
{
}
bool GeoTexSvxHatch::operator==(const GeoTexSvx& rGeoTexSvx) const
{
const GeoTexSvxHatch* pCompare = dynamic_cast< const GeoTexSvxHatch* >(&rGeoTexSvx);
return (pCompare
&& maOutputRange == pCompare->maOutputRange
&& maTextureTransform == pCompare->maTextureTransform
&& mfDistance == pCompare->mfDistance
&& mfAngle == pCompare->mfAngle
&& mnSteps == pCompare->mnSteps);
}
void GeoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(mbDefinitionRangeEqualsOutputRange)
{
// simple hatch where the definition area equals the output area
for(sal_uInt32 a(1); a < mnSteps; a++)
{
// create matrix
const double fOffset(mfDistance * (double)a);
basegfx::B2DHomMatrix aNew;
aNew.set(1, 2, fOffset);
rMatrices.push_back(maTextureTransform * aNew);
}
}
else
{
// output area is different from definition area, back-transform to get
// the output area in unit coordinates and fill this with hatch lines
// using the settings derived from the definition area
basegfx::B2DRange aBackUnitRange(maOutputRange);
aBackUnitRange.transform(getBackTextureTransform());
// calculate vertical start value and a security maximum integer value to avoid death loops
double fStart(basegfx::snapToNearestMultiple(aBackUnitRange.getMinY(), mfDistance));
const sal_uInt32 nNeededIntegerSteps(basegfx::fround((aBackUnitRange.getHeight() / mfDistance) + 0.5));
sal_uInt32 nMaxIntegerSteps(::std::min(nNeededIntegerSteps, sal_uInt32(10000)));
while(fStart < aBackUnitRange.getMaxY() && nMaxIntegerSteps)
{
// create new transform for
basegfx::B2DHomMatrix aNew;
// adapt x scale and position
//aNew.scale(aBackUnitRange.getWidth(), 1.0);
//aNew.translate(aBackUnitRange.getMinX(), 0.0);
aNew.set(0, 0, aBackUnitRange.getWidth());
aNew.set(0, 2, aBackUnitRange.getMinX());
// adapt y position to current step
aNew.set(1, 2, fStart);
//aNew.translate(0.0, fStart);
// add new transformation
rMatrices.push_back(maTextureTransform * aNew);
// next step
fStart += mfDistance;
nMaxIntegerSteps--;
}
}
}
double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
{
const basegfx::B2DPoint aCoor(getBackTextureTransform() * rUV);
return fmod(aCoor.getY(), mfDistance);
}
const basegfx::B2DHomMatrix& GeoTexSvxHatch::getBackTextureTransform() const
{
if(maBackTextureTransform.isIdentity())
{
const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform = maTextureTransform;
const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform.invert();
}
return maBackTextureTransform;
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
namespace drawinglayer
{
namespace texture
{
GeoTexSvxTiled::GeoTexSvxTiled(
const basegfx::B2DRange& rRange,
double fOffsetX,
double fOffsetY)
: maRange(rRange),
mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)),
mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0))
{
if(!basegfx::fTools::equalZero(mfOffsetX))
{
mfOffsetY = 0.0;
}
}
GeoTexSvxTiled::~GeoTexSvxTiled()
{
}
bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
{
const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
return (pCompare
&& maRange == pCompare->maRange
&& mfOffsetX == pCompare->mfOffsetX
&& mfOffsetY == pCompare->mfOffsetY);
}
void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
const double fWidth(maRange.getWidth());
if(!basegfx::fTools::equalZero(fWidth))
{
const double fHeight(maRange.getHeight());
if(!basegfx::fTools::equalZero(fHeight))
{
double fStartX(maRange.getMinX());
double fStartY(maRange.getMinY());
sal_Int32 nPosX(0);
sal_Int32 nPosY(0);
if(basegfx::fTools::more(fStartX, 0.0))
{
const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartX / fWidth)) + 1);
nPosX -= nDiff;
fStartX -= nDiff * fWidth;
}
if(basegfx::fTools::less(fStartX + fWidth, 0.0))
{
const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartX / fWidth)));
nPosX += nDiff;
fStartX += nDiff * fWidth;
}
if(basegfx::fTools::more(fStartY, 0.0))
{
const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartY / fHeight)) + 1);
nPosY -= nDiff;
fStartY -= nDiff * fHeight;
}
if(basegfx::fTools::less(fStartY + fHeight, 0.0))
{
const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartY / fHeight)));
nPosY += nDiff;
fStartY += nDiff * fHeight;
}
if(!basegfx::fTools::equalZero(mfOffsetY))
{
for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth, nPosX++)
{
for(double fPosY(nPosX % 2 ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY);
basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight)
{
rMatrices.push_back(
basegfx::tools::createScaleTranslateB2DHomMatrix(
fWidth,
fHeight,
fPosX,
fPosY));
}
}
}
else
{
for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++)
{
for(double fPosX(nPosY % 2 ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX);
basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth)
{
rMatrices.push_back(
basegfx::tools::createScaleTranslateB2DHomMatrix(
fWidth,
fHeight,
fPosX,
fPosY));
}
}
}
}
}
}
} // end of namespace texture
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
// eof