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