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
00029
00030
00031 #ifndef _BGFX_TOOLS_GRADIENTTOOLS_HXX
00032 #define _BGFX_TOOLS_GRADIENTTOOLS_HXX
00033
00034 #include <basegfx/point/b2dpoint.hxx>
00035 #include <basegfx/range/b2drange.hxx>
00036 #include <basegfx/vector/b2dvector.hxx>
00037 #include <basegfx/matrix/b2dhommatrix.hxx>
00038 #include <basegfx/numeric/ftools.hxx>
00039
00040 namespace basegfx
00041 {
00048 struct ODFGradientInfo
00049 {
00053 B2DHomMatrix maTextureTransform;
00054
00061 B2DHomMatrix maBackTextureTransform;
00062
00067 double mfAspectRatio;
00068
00074 sal_uInt32 mnSteps;
00075 };
00076
00077 namespace tools
00078 {
00098 ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00099 const B2DRange& rTargetArea,
00100 sal_uInt32 nSteps,
00101 double fBorder,
00102 double fAngle);
00103
00117 inline double getLinearGradientAlpha(const B2DPoint& rUV,
00118 const ODFGradientInfo& rGradInfo )
00119 {
00120 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00121 const double t(clamp(aCoor.getY(), 0.0, 1.0));
00122 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00123
00124 if(nSteps > 2L && nSteps < 128L)
00125 return floor(t * nSteps) / double(nSteps + 1L);
00126
00127 return t;
00128 }
00129
00149 ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00150 const B2DRange& rTargetArea,
00151 sal_uInt32 nSteps,
00152 double fBorder,
00153 double fAngle);
00154
00168 inline double getAxialGradientAlpha(const B2DPoint& rUV,
00169 const ODFGradientInfo& rGradInfo )
00170 {
00171 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00172 const double t(clamp(fabs(aCoor.getY()), 0.0, 1.0));
00173 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00174 const double fInternalSteps((nSteps * 2L) - 1L);
00175
00176 if(nSteps > 2L && nSteps < 128L)
00177 return floor(((t * fInternalSteps) + 1.0) / 2.0) / double(nSteps - 1L);
00178
00179 return t;
00180 }
00181
00204 ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00205 const B2DRange& rTargetArea,
00206 const B2DVector& rOffset,
00207 sal_uInt32 nSteps,
00208 double fBorder);
00209
00223 inline double getRadialGradientAlpha(const B2DPoint& rUV,
00224 const ODFGradientInfo& rGradInfo )
00225 {
00226 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00227 const double fDist(
00228 clamp(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY(),
00229 0.0,
00230 1.0));
00231
00232 const double t(1.0 - sqrt(fDist));
00233 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00234
00235 if(nSteps > 2L && nSteps < 128L)
00236 return floor(t * nSteps) / double(nSteps - 1L);
00237
00238 return t;
00239 }
00240
00263 ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00264 const B2DRange& rTargetArea,
00265 const B2DVector& rOffset,
00266 sal_uInt32 nSteps,
00267 double fBorder,
00268 double fAngle);
00269
00283 inline double getEllipticalGradientAlpha(const B2DPoint& rUV,
00284 const ODFGradientInfo& rGradInfo )
00285 {
00286 return getRadialGradientAlpha(rUV,rGradInfo);
00287 }
00288
00311 ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00312 const B2DRange& rTargetArea,
00313 const B2DVector& rOffset,
00314 sal_uInt32 nSteps,
00315 double fBorder,
00316 double fAngle);
00317
00331 inline double getSquareGradientAlpha(const B2DPoint& rUV,
00332 const ODFGradientInfo& rGradInfo )
00333 {
00334 const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
00335 const double fAbsX(fabs(aCoor.getX()));
00336 const double fAbsY(fabs(aCoor.getY()));
00337
00338 if(fTools::moreOrEqual(fAbsX, 1.0) || fTools::moreOrEqual(fAbsY, 1.0))
00339 return 0.0;
00340
00341 const double t(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
00342 const sal_uInt32 nSteps(rGradInfo.mnSteps);
00343
00344 if(nSteps > 2L && nSteps < 128L)
00345 return floor(t * nSteps) / double(nSteps - 1L);
00346
00347 return t;
00348 }
00349
00372 ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
00373 const B2DRange& rTargetArea,
00374 const B2DVector& rOffset,
00375 sal_uInt32 nSteps,
00376 double fBorder,
00377 double fAngle);
00378
00392 inline double getRectangularGradientAlpha(const B2DPoint& rUV,
00393 const ODFGradientInfo& rGradInfo )
00394 {
00395 return getSquareGradientAlpha(rUV, rGradInfo);
00396 }
00397
00398 }
00399 }
00400
00401 #endif