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