1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _BGFX_TOOLS_GRADIENTTOOLS_HXX 25 #define _BGFX_TOOLS_GRADIENTTOOLS_HXX 26 27 #include <basegfx/point/b2dpoint.hxx> 28 #include <basegfx/range/b2drange.hxx> 29 #include <basegfx/vector/b2dvector.hxx> 30 #include <basegfx/matrix/b2dhommatrix.hxx> 31 #include <basegfx/numeric/ftools.hxx> 32 #include <basegfx/basegfxdllapi.h> 33 34 #include <vector> 35 #include <algorithm> 36 37 namespace basegfx 38 { 39 /** Gradient definition as used in ODF 1.2 40 41 This struct collects all data necessary for rendering ODF 42 1.2-compatible gradients. Use the createXXXODFGradientInfo() 43 methods below for initializing from ODF attributes. 44 */ 45 class BASEGFX_DLLPUBLIC ODFGradientInfo 46 { 47 private: 48 /** transformation mapping from [0,1]^2 texture coordinate 49 space to [0,1]^2 shape coordinate space 50 */ 51 B2DHomMatrix maTextureTransform; 52 53 /** transformation mapping from [0,1]^2 shape coordinate space 54 to [0,1]^2 texture coordinate space. This is the 55 transformation commonly used to create gradients from a 56 scanline rasterizer (put shape u/v coordinates into it, get 57 texture s/t coordinates out of it) 58 */ 59 B2DHomMatrix maBackTextureTransform; 60 61 /** Aspect ratio of the gradient. Only used in drawinglayer 62 for generating nested gradient polygons currently. Already 63 catered for in the transformations above. 64 */ 65 double mfAspectRatio; 66 67 /** Requested gradient steps to render. See the 68 implementations of the getXXXGradientAlpha() methods below, 69 the semantic differs slightly for the different gradient 70 types. 71 */ 72 sal_uInt32 mnSteps; 73 74 public: ODFGradientInfo()75 ODFGradientInfo() 76 : maTextureTransform(), 77 maBackTextureTransform(), 78 mfAspectRatio(1.0), 79 mnSteps(0) 80 { 81 } 82 ODFGradientInfo(const B2DHomMatrix & rTextureTransform,double fAspectRatio,sal_uInt32 nSteps)83 ODFGradientInfo( 84 const B2DHomMatrix& rTextureTransform, 85 double fAspectRatio, 86 sal_uInt32 nSteps) 87 : maTextureTransform(rTextureTransform), 88 maBackTextureTransform(), 89 mfAspectRatio(fAspectRatio), 90 mnSteps(nSteps) 91 { 92 } 93 ODFGradientInfo(const ODFGradientInfo & rODFGradientInfo)94 ODFGradientInfo(const ODFGradientInfo& rODFGradientInfo) 95 : maTextureTransform(rODFGradientInfo.getTextureTransform()), 96 maBackTextureTransform(rODFGradientInfo.maBackTextureTransform), 97 mfAspectRatio(rODFGradientInfo.getAspectRatio()), 98 mnSteps(rODFGradientInfo.getSteps()) 99 { 100 } 101 operator =(const ODFGradientInfo & rODFGradientInfo)102 ODFGradientInfo& operator=(const ODFGradientInfo& rODFGradientInfo) 103 { 104 maTextureTransform = rODFGradientInfo.getTextureTransform(); 105 maBackTextureTransform = rODFGradientInfo.maBackTextureTransform; 106 mfAspectRatio = rODFGradientInfo.getAspectRatio(); 107 mnSteps = rODFGradientInfo.getSteps(); 108 109 return *this; 110 } 111 112 // compare operator 113 bool operator==(const ODFGradientInfo& rGeoTexSvx) const; 114 getTextureTransform() const115 const B2DHomMatrix& getTextureTransform() const { return maTextureTransform; } 116 const B2DHomMatrix& getBackTextureTransform() const; getAspectRatio() const117 double getAspectRatio() const { return mfAspectRatio; } getSteps() const118 sal_uInt32 getSteps() const { return mnSteps; } 119 setTextureTransform(const B2DHomMatrix & rNew)120 void setTextureTransform(const B2DHomMatrix& rNew) 121 { 122 maTextureTransform = rNew; 123 maBackTextureTransform.identity(); 124 } 125 }; 126 127 namespace tools 128 { 129 /** Create matrix for ODF's linear gradient definition 130 131 Note that odf linear gradients are varying in y direction. 132 133 @param o_rGradientInfo 134 Receives the calculated texture transformation matrix (for 135 use with standard [0,1]x[0,1] texture coordinates) 136 137 @param rTargetArea 138 Output area, needed for aspect ratio calculations and 139 texture transformation 140 141 @param nSteps 142 Number of gradient steps (from ODF) 143 144 @param fBorder 145 Width of gradient border (from ODF) 146 147 @param fAngle 148 Gradient angle (from ODF) 149 */ 150 BASEGFX_DLLPUBLIC ODFGradientInfo createLinearODFGradientInfo( 151 const B2DRange& rTargetArea, 152 sal_uInt32 nSteps, 153 double fBorder, 154 double fAngle); 155 156 /** Calculate linear gradient blend value 157 158 This method generates you the lerp alpha value for 159 blending linearly between gradient start and end color, 160 according to the formula (startCol*(1.0-alpha) + endCol*alpha) 161 162 @param rUV 163 Current uv coordinate. Values outside [0,1] will be 164 clamped. Assumes gradient color varies along the y axis. 165 166 @param rGradInfo 167 Gradient info, for transformation and number of steps 168 */ 169 BASEGFX_DLLPUBLIC double getLinearGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo); 170 171 /** Create matrix for ODF's axial gradient definition 172 173 Note that odf axial gradients are varying in y 174 direction. Note further that you can map the axial 175 gradient to a linear gradient (in case you want or need to 176 avoid an extra gradient renderer), by using 177 createLinearODFGradientInfo() instead, shifting the 178 resulting texture transformation by 0.5 to the top and 179 appending the same stop colors again, but mirrored. 180 181 @param o_rGradientInfo 182 Receives the calculated texture transformation matrix (for 183 use with standard [0,1]x[0,1] texture coordinates) 184 185 @param rTargetArea 186 Output area, needed for aspect ratio calculations and 187 texture transformation 188 189 @param nSteps 190 Number of gradient steps (from ODF) 191 192 @param fBorder 193 Width of gradient border (from ODF) 194 195 @param fAngle 196 Gradient angle (from ODF) 197 */ 198 BASEGFX_DLLPUBLIC ODFGradientInfo createAxialODFGradientInfo( 199 const B2DRange& rTargetArea, 200 sal_uInt32 nSteps, 201 double fBorder, 202 double fAngle); 203 204 /** Calculate axial gradient blend value 205 206 This method generates you the lerp alpha value for 207 blending linearly between gradient start and end color, 208 according to the formula (startCol*(1.0-alpha) + endCol*alpha) 209 210 @param rUV 211 Current uv coordinate. Values outside [0,1] will be 212 clamped. Assumes gradient color varies along the y axis. 213 214 @param rGradInfo 215 Gradient info, for transformation and number of steps 216 */ 217 BASEGFX_DLLPUBLIC double getAxialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo); 218 219 /** Create matrix for ODF's radial gradient definition 220 221 @param o_rGradientInfo 222 Receives the calculated texture transformation matrix (for 223 use with standard [0,1]x[0,1] texture coordinates) 224 225 @param rTargetArea 226 Output area, needed for aspect ratio calculations and 227 texture transformation 228 229 @param rOffset 230 Gradient offset value (from ODF) 231 232 @param nSteps 233 Number of gradient steps (from ODF) 234 235 @param fBorder 236 Width of gradient border (from ODF) 237 238 @param fAngle 239 Gradient angle (from ODF) 240 */ 241 BASEGFX_DLLPUBLIC ODFGradientInfo createRadialODFGradientInfo( 242 const B2DRange& rTargetArea, 243 const B2DVector& rOffset, 244 sal_uInt32 nSteps, 245 double fBorder); 246 247 /** Calculate radial gradient blend value 248 249 This method generates you the lerp alpha value for 250 blending linearly between gradient start and end color, 251 according to the formula (startCol*(1.0-alpha) + endCol*alpha) 252 253 @param rUV 254 Current uv coordinate. Values outside [0,1] will be 255 clamped. 256 257 @param rGradInfo 258 Gradient info, for transformation and number of steps 259 */ 260 BASEGFX_DLLPUBLIC double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo); 261 262 /** Create matrix for ODF's elliptical gradient definition 263 264 @param o_rGradientInfo 265 Receives the calculated texture transformation matrix (for 266 use with standard [0,1]x[0,1] texture coordinates) 267 268 @param rTargetArea 269 Output area, needed for aspect ratio calculations and 270 texture transformation 271 272 @param rOffset 273 Gradient offset value (from ODF) 274 275 @param nSteps 276 Number of gradient steps (from ODF) 277 278 @param fBorder 279 Width of gradient border (from ODF) 280 281 @param fAngle 282 Gradient angle (from ODF) 283 */ 284 BASEGFX_DLLPUBLIC ODFGradientInfo createEllipticalODFGradientInfo( 285 const B2DRange& rTargetArea, 286 const B2DVector& rOffset, 287 sal_uInt32 nSteps, 288 double fBorder, 289 double fAngle); 290 291 /** Calculate elliptical gradient blend value 292 293 This method generates you the lerp alpha value for 294 blending linearly between gradient start and end color, 295 according to the formula (startCol*(1.0-alpha) + endCol*alpha) 296 297 @param rUV 298 Current uv coordinate. Values outside [0,1] will be 299 clamped. 300 301 @param rGradInfo 302 Gradient info, for transformation and number of steps 303 */ 304 BASEGFX_DLLPUBLIC double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo); 305 306 /** Create matrix for ODF's square gradient definition 307 308 @param o_rGradientInfo 309 Receives the calculated texture transformation matrix (for 310 use with standard [0,1]x[0,1] texture coordinates) 311 312 @param rTargetArea 313 Output area, needed for aspect ratio calculations and 314 texture transformation 315 316 @param rOffset 317 Gradient offset value (from ODF) 318 319 @param nSteps 320 Number of gradient steps (from ODF) 321 322 @param fBorder 323 Width of gradient border (from ODF) 324 325 @param fAngle 326 Gradient angle (from ODF) 327 */ 328 BASEGFX_DLLPUBLIC ODFGradientInfo createSquareODFGradientInfo( 329 const B2DRange& rTargetArea, 330 const B2DVector& rOffset, 331 sal_uInt32 nSteps, 332 double fBorder, 333 double fAngle); 334 335 /** Calculate square gradient blend value 336 337 This method generates you the lerp alpha value for 338 blending linearly between gradient start and end color, 339 according to the formula (startCol*(1.0-alpha) + endCol*alpha) 340 341 @param rUV 342 Current uv coordinate. Values outside [0,1] will be 343 clamped. 344 345 @param rGradInfo 346 Gradient info, for transformation and number of steps 347 */ 348 BASEGFX_DLLPUBLIC double getSquareGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo); 349 350 /** Create matrix for ODF's rectangular gradient definition 351 352 @param o_rGradientInfo 353 Receives the calculated texture transformation matrix (for 354 use with standard [0,1]x[0,1] texture coordinates) 355 356 @param rTargetArea 357 Output area, needed for aspect ratio calculations and 358 texture transformation 359 360 @param rOffset 361 Gradient offset value (from ODF) 362 363 @param nSteps 364 Number of gradient steps (from ODF) 365 366 @param fBorder 367 Width of gradient border (from ODF) 368 369 @param fAngle 370 Gradient angle (from ODF) 371 */ 372 BASEGFX_DLLPUBLIC ODFGradientInfo createRectangularODFGradientInfo( 373 const B2DRange& rTargetArea, 374 const B2DVector& rOffset, 375 sal_uInt32 nSteps, 376 double fBorder, 377 double fAngle); 378 379 /** Calculate rectangular gradient blend value 380 381 This method generates you the lerp alpha value for 382 blending linearly between gradient start and end color, 383 according to the formula (startCol*(1.0-alpha) + endCol*alpha) 384 385 @param rUV 386 Current uv coordinate. Values outside [0,1] will be 387 clamped. 388 389 @param rGradInfo 390 Gradient info, for transformation and number of steps 391 */ 392 BASEGFX_DLLPUBLIC double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo); 393 } 394 } 395 396 #endif 397 398 // eof 399