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