00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _BGFX_TOOLS_GRADIENTTOOLS_HXX
00029 #define _BGFX_TOOLS_GRADIENTTOOLS_HXX
00030
00031 #include <basegfx/point/b2dpoint.hxx>
00032 #include <basegfx/range/b2drange.hxx>
00033 #include <basegfx/vector/b2dvector.hxx>
00034 #include <basegfx/matrix/b2dhommatrix.hxx>
00035 #include <basegfx/numeric/ftools.hxx>
00036
00037 namespace basegfx
00038 {
00045 struct ODFGradientInfo
00046 {
00050 B2DHomMatrix maTextureTransform;
00051
00058 B2DHomMatrix maBackTextureTransform;
00059
00064 double mfAspectRatio;
00065
00071 sal_uInt32 mnSteps;
00072 };
00073
00074 namespace tools
00075 {
00095 ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00096 const B2DRange& rTargetArea,
00097 sal_uInt32 nSteps,
00098 double fBorder,
00099 double fAngle);
00100
00114 inline double getLinearGradientAlpha(const B2DPoint& rUV,
00115 const ODFGradientInfo& rGradInfo )
00116 {
00117 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00118 const double t(clamp(aCoor.getY(), 0.0, 1.0));
00119 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00120
00121 if(nSteps > 2L && nSteps < 128L)
00122 return floor(t * nSteps) / double(nSteps + 1L);
00123
00124 return t;
00125 }
00126
00146 ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00147 const B2DRange& rTargetArea,
00148 sal_uInt32 nSteps,
00149 double fBorder,
00150 double fAngle);
00151
00165 inline double getAxialGradientAlpha(const B2DPoint& rUV,
00166 const ODFGradientInfo& rGradInfo )
00167 {
00168 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00169 const double t(clamp(fabs(aCoor.getY()), 0.0, 1.0));
00170 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00171 const double fInternalSteps((nSteps * 2L) - 1L);
00172
00173 if(nSteps > 2L && nSteps < 128L)
00174 return floor(((t * fInternalSteps) + 1.0) / 2.0) / double(nSteps - 1L);
00175
00176 return t;
00177 }
00178
00201 ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00202 const B2DRange& rTargetArea,
00203 const B2DVector& rOffset,
00204 sal_uInt32 nSteps,
00205 double fBorder);
00206
00220 inline double getRadialGradientAlpha(const B2DPoint& rUV,
00221 const ODFGradientInfo& rGradInfo )
00222 {
00223 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00224 const double fDist(
00225 clamp(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY(),
00226 0.0,
00227 1.0));
00228
00229 const double t(1.0 - sqrt(fDist));
00230 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00231
00232 if(nSteps > 2L && nSteps < 128L)
00233 return floor(t * nSteps) / double(nSteps - 1L);
00234
00235 return t;
00236 }
00237
00260 ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00261 const B2DRange& rTargetArea,
00262 const B2DVector& rOffset,
00263 sal_uInt32 nSteps,
00264 double fBorder,
00265 double fAngle);
00266
00280 inline double getEllipticalGradientAlpha(const B2DPoint& rUV,
00281 const ODFGradientInfo& rGradInfo )
00282 {
00283 return getRadialGradientAlpha(rUV,rGradInfo);
00284 }
00285
00308 ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00309 const B2DRange& rTargetArea,
00310 const B2DVector& rOffset,
00311 sal_uInt32 nSteps,
00312 double fBorder,
00313 double fAngle);
00314
00328 inline double getSquareGradientAlpha(const B2DPoint& rUV,
00329 const ODFGradientInfo& rGradInfo )
00330 {
00331 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00332 const double fAbsX(fabs(aCoor.getX()));
00333 const double fAbsY(fabs(aCoor.getY()));
00334
00335 if(fTools::moreOrEqual(fAbsX, 1.0) || fTools::moreOrEqual(fAbsY, 1.0))
00336 return 0.0;
00337
00338 const double t(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
00339 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00340
00341 if(nSteps > 2L && nSteps < 128L)
00342 return floor(t * nSteps) / double(nSteps - 1L);
00343
00344 return t;
00345 }
00346
00369 ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00370 const B2DRange& rTargetArea,
00371 const B2DVector& rOffset,
00372 sal_uInt32 nSteps,
00373 double fBorder,
00374 double fAngle);
00375
00389 inline double getRectangularGradientAlpha(const B2DPoint& rUV,
00390 const ODFGradientInfo& rGradInfo )
00391 {
00392 return getSquareGradientAlpha(rUV, rGradInfo);
00393 }
00394
00395 }
00396 }
00397
00398 #endif