Files
libreoffice/drawinglayer/source/texture/texture.cxx
Vladimir Glazounov 8cb613c6d0 CWS-TOOLING: integrate CWS aw061
2009-01-13 19:18:08 +0100 aw  r266250 : #i96669# changed initialisation order in Embedded3DPrimitive2D::Embedded3DPrimitive2D due to TinderBox
2009-01-13 19:15:37 +0100 aw  r266249 : #i96669# changed initialisation order in Embedded3DPrimitive2D::Embedded3DPrimitive2D due to TinderBox
2009-01-12 11:53:37 +0100 aw  r266141 : #i97874# corrected include for TinderBox build
2009-01-08 17:48:23 +0100 aw  r266029 : #i97874# extended SdrTextObj::ImpConvertAddText to copy needed attributes from original object
2009-01-08 14:59:08 +0100 aw  r266015 : #i96350# added fallback to solid fill in shadow TabPage when no fill is defined to get a reasonable shadow preview
2009-01-08 12:40:49 +0100 aw  r265995 : #i94832# remuved not needed E3DModifySceneSnapRectUpdater usages
2009-01-08 01:53:46 +0100 thb  r265982 : #i94860# Blacklisting another ATI card/driver that causes blank screens
2009-01-08 01:46:38 +0100 thb  r265981 : #i97853# Changed all gradient texture methods to use basegfx gradienttools. consolidated quite some code
2009-01-08 01:45:09 +0100 thb  r265980 : #i97853# Added lerp methods, slight changes to have everything necessary contained in the ODFGradientInfo struct
2009-01-08 00:01:54 +0100 thb  r265979 : #i97853# First part of the move - duplicated the stuff to basegfx
2009-01-06 16:23:09 +0100 aw  r265930 : #i97197# Changed SwDrawVirtObj to work well with changed aOutRect and bBoundRectValid functionality
2009-01-06 12:41:24 +0100 aw  r265909 : #i97784# corrected regression with connectors
2009-01-05 17:30:31 +0100 aw  r265881 : #i97772# added missing usage of reduce factor for BitmapPrimitive creation
2009-01-05 12:24:01 +0100 aw  r265863 : #i97321# added direct handling of HatchTexturePrimitive3D to not use it's decomposition for HitTest
2008-12-23 13:57:27 +0100 aw  r265782 : #i96669# changed SW's FlyFrame paint fallback with primitives to use createLocalDecomposition since get2Decomposition does not have to stay virtual on the long run
2008-12-23 13:47:59 +0100 aw  r265781 : #i96669# optimized impCreateTextPortionPrimitive to only create TextDecoratedPortionPrimitive2D when needed
2008-12-23 13:44:45 +0100 aw  r265780 : #i96669# added B2DRange buffering to some primitive implementations where it is most necessary
2008-12-19 15:45:45 +0100 aw  r265729 : #i96669# prepared TextPrimitives to work without DXarray, too. Had to rework impSplitSingleWords which gets active when a text portion has some word-wise decorations. Tested before committing
2008-12-19 15:44:16 +0100 aw  r265728 : #i96669# corrected error in createPolygonFromUnitEllipseSegment which popped up when investigating
2008-12-18 17:45:58 +0100 aw  r265708 : #i97149# added ActionChanged() call when visualisation object is modified
2008-12-18 15:34:42 +0100 aw  r265695 : #i96598# corrected SdrPageObj's usage of aOutRect
2008-12-17 16:59:37 +0100 aw  r265647 : #i96537# exchanged the marker for point number in string with correct one
2008-12-16 17:50:33 +0100 aw  r265566 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer
2008-12-16 17:50:17 +0100 aw  r265565 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer
2008-12-16 17:50:00 +0100 aw  r265564 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer
2008-12-16 17:49:48 +0100 aw  r265563 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer
2008-12-16 17:49:35 +0100 aw  r265562 : #i93170# added a bool to EndDrawLayer() and corresponding mechanisms to allow to end without drawing FormLayer
2009-01-20 09:49:16 +00:00

729 lines
28 KiB
C++

/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: texture.cxx,v $
*
* $Revision: 1.6 $
*
* last change: $Author: aw $ $Date: 2008-05-27 14:11:34 $
*
* 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/texture/texture.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/tools/gradienttools.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::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 (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
{
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(maGradientInfo.maTextureTransform * aNew);
}
void GeoTexSvxGradient::impAppendColorsRadial(::std::vector< basegfx::BColor >& rColors)
{
if(maGradientInfo.mnSteps)
{
rColors.push_back(maStart);
for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps - 1L; a++)
{
rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)maGradientInfo.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),
mfBorder(fBorder)
{
maGradientInfo.mnSteps = nSteps;
maGradientInfo.mfAspectRatio = 1.0;
}
GeoTexSvxGradient::~GeoTexSvxGradient()
{
}
bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
{
const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
return (pCompare
&& maGradientInfo.maTextureTransform == pCompare->maGradientInfo.maTextureTransform
&& maTargetRange == pCompare->maTargetRange
&& maGradientInfo.mnSteps == pCompare->maGradientInfo.mnSteps
&& maGradientInfo.mfAspectRatio == pCompare->maGradientInfo.mfAspectRatio
&& 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)
{
basegfx::tools::createLinearODFGradientInfo(maGradientInfo,
rTargetRange,
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
{
}
void GeoTexSvxGradientLinear::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(maGradientInfo.mnSteps)
{
const double fTop(mfBorder);
const double fStripeWidth((1.0 - fTop) / maGradientInfo.mnSteps);
for(sal_uInt32 a(1L); a < maGradientInfo.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(maGradientInfo.mnSteps)
{
rColors.push_back(maStart);
for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
{
rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)(maGradientInfo.mnSteps + 1L)));
}
}
}
void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getLinearGradientAlpha(rUV, maGradientInfo));
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)
{
basegfx::tools::createAxialODFGradientInfo(maGradientInfo,
rTargetRange,
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
{
}
void GeoTexSvxGradientAxial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(maGradientInfo.mnSteps)
{
const double fHalfBorder(mfBorder * 0.5);
double fTop(fHalfBorder);
double fBottom(1.0 - fHalfBorder);
const double fStripeWidth((fBottom - fTop) / ((maGradientInfo.mnSteps * 2L) - 1L));
for(sal_uInt32 a(1L); a < maGradientInfo.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(maGradientInfo.mnSteps)
{
rColors.push_back(maEnd);
for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
{
rColors.push_back(interpolate(maEnd, maStart, (double)a / (double)maGradientInfo.mnSteps));
}
}
}
void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
const double fScaler(basegfx::tools::getAxialGradientAlpha(rUV, maGradientInfo));
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)
{
basegfx::tools::createRadialODFGradientInfo(maGradientInfo,
rTargetRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder);
}
GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
{
}
void GeoTexSvxGradientRadial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(maGradientInfo.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(maGradientInfo.mfAspectRatio > 1.0)
{
fIncrementY = (fBottom - fTop) / (double)(maGradientInfo.mnSteps * 2L);
fIncrementX = fIncrementY / maGradientInfo.mfAspectRatio;
}
else
{
fIncrementX = (fRight - fLeft) / (double)(maGradientInfo.mnSteps * 2L);
fIncrementY = fIncrementX * maGradientInfo.mfAspectRatio;
}
for(sal_uInt32 a(1L); a < maGradientInfo.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 double fScaler(basegfx::tools::getRadialGradientAlpha(rUV, maGradientInfo));
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)
{
basegfx::tools::createEllipticalODFGradientInfo(maGradientInfo,
rTargetRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
{
}
void GeoTexSvxGradientElliptical::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(maGradientInfo.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(maGradientInfo.mfAspectRatio > 1.0)
{
fIncrementY = (fBottom - fTop) / (double)(maGradientInfo.mnSteps * 2L);
fIncrementX = fIncrementY / maGradientInfo.mfAspectRatio;
}
else
{
fIncrementX = (fRight - fLeft) / (double)(maGradientInfo.mnSteps * 2L);
fIncrementY = fIncrementX * maGradientInfo.mfAspectRatio;
}
for(sal_uInt32 a(1L); a < maGradientInfo.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 double fScaler(basegfx::tools::getEllipticalGradientAlpha(rUV, maGradientInfo));
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)
{
basegfx::tools::createSquareODFGradientInfo(maGradientInfo,
rTargetRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
{
}
void GeoTexSvxGradientSquare::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(maGradientInfo.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(maGradientInfo.mfAspectRatio > 1.0)
{
const double fWidth(fRight - fLeft);
const double fHalfAspectExpansion(((maGradientInfo.mfAspectRatio - 1.0) * 0.5) * fWidth);
fTop -= fHalfAspectExpansion;
fBottom += fHalfAspectExpansion;
fIncrementX = fWidth / (double)(maGradientInfo.mnSteps * 2L);
fIncrementY = fIncrementX * maGradientInfo.mfAspectRatio;
}
else
{
const double fHeight(fBottom - fTop);
const double fHalfAspectExpansion((((1.0 / maGradientInfo.mfAspectRatio) - 1.0) * 0.5) * fHeight);
fLeft -= fHalfAspectExpansion;
fRight += fHalfAspectExpansion;
fIncrementY = fHeight / (double)(maGradientInfo.mnSteps * 2L);
fIncrementX = fIncrementY / maGradientInfo.mfAspectRatio;
}
for(sal_uInt32 a(1L); a < maGradientInfo.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 double fScaler(basegfx::tools::getSquareGradientAlpha(rUV, maGradientInfo));
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)
{
basegfx::tools::createRectangularODFGradientInfo(maGradientInfo,
rTargetRange,
basegfx::B2DVector(fOffsetX,fOffsetY),
nSteps,
fBorder,
fAngle);
}
GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
{
}
void GeoTexSvxGradientRect::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
{
if(maGradientInfo.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(maGradientInfo.mfAspectRatio > 1.0)
{
fIncrementY = (fBottom - fTop) / (double)(maGradientInfo.mnSteps * 2L);
fIncrementX = fIncrementY / maGradientInfo.mfAspectRatio;
}
else
{
fIncrementX = (fRight - fLeft) / (double)(maGradientInfo.mnSteps * 2L);
fIncrementY = fIncrementX * maGradientInfo.mfAspectRatio;
}
for(sal_uInt32 a(1L); a < maGradientInfo.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 double fScaler(basegfx::tools::getRectangularGradientAlpha(rUV, maGradientInfo));
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