Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / include / basegfx / utils / gradienttools.hxx
blobf2c0de9aa8b4493a72bab21b5a8f3482a099e67c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <config_options.h>
23 #include <basegfx/point/b2dpoint.hxx>
24 #include <basegfx/vector/b2dvector.hxx>
25 #include <basegfx/matrix/b2dhommatrix.hxx>
26 #include <basegfx/color/bcolor.hxx>
27 #include <utility>
28 #include <basegfx/basegfxdllapi.h>
29 #include <vector>
30 #include <com/sun/star/awt/ColorStopSequence.hdl>
31 #include <basegfx/utils/bgradient.hxx>
32 #include <osl/endian.h>
34 namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }
35 namespace com { namespace sun { namespace star { namespace awt { struct Gradient2; } } } }
36 namespace basegfx { class B2DRange; }
38 namespace
40 /* Internal helper to convert ::Color from tools::color.hxx to BColor
41 without the need to link against tools library. Be on the
42 safe side by using the same union
44 struct ColorToBColorConverter
46 union {
47 sal_uInt32 mValue;
48 struct {
49 #ifdef OSL_BIGENDIAN
50 sal_uInt8 T;
51 sal_uInt8 R;
52 sal_uInt8 G;
53 sal_uInt8 B;
54 #else
55 sal_uInt8 B;
56 sal_uInt8 G;
57 sal_uInt8 R;
58 sal_uInt8 T;
59 #endif
63 ColorToBColorConverter GetRGBColor() const
65 return {R, G, B};
68 ColorToBColorConverter(sal_uInt32 nColor)
69 : mValue(nColor)
70 { T=0; }
72 constexpr ColorToBColorConverter(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
73 : mValue(sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16))
76 explicit ColorToBColorConverter(const basegfx::BColor& rBColor)
77 : ColorToBColorConverter(
78 sal_uInt8(std::lround(rBColor.getRed() * 255.0)),
79 sal_uInt8(std::lround(rBColor.getGreen() * 255.0)),
80 sal_uInt8(std::lround(rBColor.getBlue() * 255.0)))
83 basegfx::BColor getBColor() const
85 return basegfx::BColor(R / 255.0, G / 255.0, B / 255.0);
88 constexpr explicit operator sal_Int32() const
90 return sal_Int32(mValue);
93 constexpr explicit operator sal_uInt32() const
95 return mValue;
100 namespace basegfx
102 /** Gradient definition as used in ODF 1.2
104 This struct collects all data necessary for rendering ODF
105 1.2-compatible gradients. Use the createXXXODFGradientInfo()
106 methods below for initializing from ODF attributes.
108 class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ODFGradientInfo
110 private:
111 /** transformation mapping from [0,1]^2 texture coordinate
112 space to [0,1]^2 shape coordinate space
114 B2DHomMatrix maTextureTransform;
116 /** transformation mapping from [0,1]^2 shape coordinate space
117 to [0,1]^2 texture coordinate space. This is the
118 transformation commonly used to create gradients from a
119 scanline rasterizer (put shape u/v coordinates into it, get
120 texture s/t coordinates out of it)
122 B2DHomMatrix maBackTextureTransform;
124 /** Aspect ratio of the gradient. Only used in drawinglayer
125 for generating nested gradient polygons currently. Already
126 catered for in the transformations above.
128 double mfAspectRatio;
130 /** Requested gradient steps to render. See the
131 implementations of the getXXXGradientAlpha() methods below,
132 the semantic differs slightly for the different gradient
133 types.
135 sal_uInt32 mnRequestedSteps;
137 public:
138 ODFGradientInfo()
139 : mfAspectRatio(1.0),
140 mnRequestedSteps(0)
144 ODFGradientInfo(
145 B2DHomMatrix aTextureTransform,
146 double fAspectRatio,
147 sal_uInt32 nRequestedSteps)
148 : maTextureTransform(std::move(aTextureTransform)),
149 mfAspectRatio(fAspectRatio),
150 mnRequestedSteps(nRequestedSteps)
154 ODFGradientInfo(const ODFGradientInfo& rODFGradientInfo)
155 : maTextureTransform(rODFGradientInfo.getTextureTransform()),
156 maBackTextureTransform(rODFGradientInfo.maBackTextureTransform),
157 mfAspectRatio(rODFGradientInfo.getAspectRatio()),
158 mnRequestedSteps(rODFGradientInfo.getRequestedSteps())
162 ODFGradientInfo& operator=(const ODFGradientInfo& rODFGradientInfo)
164 maTextureTransform = rODFGradientInfo.getTextureTransform();
165 maBackTextureTransform = rODFGradientInfo.maBackTextureTransform;
166 mfAspectRatio = rODFGradientInfo.getAspectRatio();
167 mnRequestedSteps = rODFGradientInfo.getRequestedSteps();
169 return *this;
172 // compare operator
173 bool operator==(const ODFGradientInfo& rGeoTexSvx) const;
175 const B2DHomMatrix& getTextureTransform() const { return maTextureTransform; }
176 const B2DHomMatrix& getBackTextureTransform() const;
177 double getAspectRatio() const { return mfAspectRatio; }
178 sal_uInt32 getRequestedSteps() const { return mnRequestedSteps; }
180 void setTextureTransform(const B2DHomMatrix& rNew)
182 maTextureTransform = rNew;
183 maBackTextureTransform.identity();
187 namespace utils
189 /* Tooling method to extract data from given BGradient
190 to ColorStops, doing some corrections, partially based
191 on given SingleColor.
192 This is used for export preparations in case these exports
193 do neither support Start/EndIntensity nor Border settings,
194 both will be eliminated if possible (see below).
195 The BGradient rGradient and BColorStops& rColorStops
196 are both return parameters and may be changed.
197 This will do quite some preparations for the gradient
198 as follows:
199 - It will check for single color (resetting rSingleColor when
200 this is the case) and return with empty ColorStops
201 - It will blend ColorStops to Intensity if StartIntensity/
202 EndIntensity != 100 is set in BGradient, so applying
203 that value(s) to the gradient directly
204 - It will adapt to Border if Border != 0 is set at the
205 given BGradient, so applying that value to the gradient
206 directly
208 BASEGFX_DLLPUBLIC void prepareColorStops(
209 const basegfx::BGradient& rGradient,
210 BColorStops& rColorStops,
211 BColor& rSingleColor);
213 /* Tooling method to synchronize the given ColorStops.
214 The intention is that a color GradientStops and an
215 alpha/transparence GradientStops gets synchronized
216 for export.
217 For the corrections the single values for color and
218 alpha may be used, e.g. when ColorStops is given
219 and not empty, but AlphaStops is empty, it will get
220 synchronized so that it will have the same number and
221 offsets in AlphaStops as in ColorStops, but with
222 the given SingleAlpha as value.
223 At return it guarantees that both have the same
224 number of entries with the same StopOffsets, so
225 that synchronized pair of ColorStops can e.g. be used
226 to export a Gradient with defined/adapted alpha
227 being 'coupled' indirectly using the
228 'FillTransparenceGradient' method (at import time).
230 BASEGFX_DLLPUBLIC void synchronizeColorStops(
231 BColorStops& rColorStops,
232 BColorStops& rAlphaStops,
233 const BColor& rSingleColor,
234 const BColor& rSingleAlpha);
236 /* Helper to calculate numberOfSteps needed to represent
237 gradient for the given two colors:
238 - to define only based on color distance, give 0 == nRequestedSteps
239 as wanted value, so color distance will be used
240 - if a wanted value of nRequestedSteps is given, it gets synched
241 against the maximum number of steps defined by the color
242 distance of the two colors
243 - a minimum result of 1 is returned which means a single
244 step -> no real gradient
246 BASEGFX_DLLPUBLIC sal_uInt32 calculateNumberOfSteps(
247 sal_uInt32 nRequestedSteps,
248 const BColor& rStart,
249 const BColor& rEnd);
251 /** Create matrix for ODF's linear gradient definition
253 Note that odf linear gradients are varying in y direction.
255 @param o_rGradientInfo
256 Receives the calculated texture transformation matrix (for
257 use with standard [0,1]x[0,1] texture coordinates)
259 @param rTargetArea
260 Output area, needed for aspect ratio calculations and
261 texture transformation
263 @param nRequestedSteps
264 Number of gradient steps (from ODF)
266 @param fBorder
267 Width of gradient border (from ODF)
269 @param fAngle
270 Gradient angle (from ODF)
272 BASEGFX_DLLPUBLIC ODFGradientInfo createLinearODFGradientInfo(
273 const B2DRange& rTargetArea,
274 sal_uInt32 nRequestedSteps,
275 double fBorder,
276 double fAngle);
279 /** Calculate linear gradient blend value
281 This method generates you the lerp alpha value for
282 blending linearly between gradient start and end color,
283 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
285 @param rUV
286 Current uv coordinate. Values outside [0,1] will be
287 clamped. Assumes gradient color varies along the y axis.
289 @param rGradInfo
290 Gradient info, for transformation and number of steps
292 BASEGFX_DLLPUBLIC double getLinearGradientAlpha(const B2DPoint& rUV,
293 const ODFGradientInfo& rGradInfo);
295 /** Create matrix for ODF's axial gradient definition
297 Note that odf axial gradients are varying in y
298 direction. Note further that you can map the axial
299 gradient to a linear gradient (in case you want or need to
300 avoid an extra gradient renderer), by using
301 createLinearODFGradientInfo() instead, shifting the
302 resulting texture transformation by 0.5 to the top and
303 appending the same stop colors again, but mirrored.
305 @param o_rGradientInfo
306 Receives the calculated texture transformation matrix (for
307 use with standard [0,1]x[0,1] texture coordinates)
309 @param rTargetArea
310 Output area, needed for aspect ratio calculations and
311 texture transformation
313 @param nRequestedSteps
314 Number of gradient steps (from ODF)
316 @param fBorder
317 Width of gradient border (from ODF)
319 @param fAngle
320 Gradient angle (from ODF)
322 BASEGFX_DLLPUBLIC ODFGradientInfo createAxialODFGradientInfo(
323 const B2DRange& rTargetArea,
324 sal_uInt32 nRequestedSteps,
325 double fBorder,
326 double fAngle);
329 /** Calculate axial gradient blend value
331 This method generates you the lerp alpha value for
332 blending linearly between gradient start and end color,
333 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
335 @param rUV
336 Current uv coordinate. Values outside [0,1] will be
337 clamped. Assumes gradient color varies along the y axis.
339 @param rGradInfo
340 Gradient info, for transformation and number of steps
342 BASEGFX_DLLPUBLIC double getAxialGradientAlpha(const B2DPoint& rUV,
343 const ODFGradientInfo& rGradInfo);
345 /** Create matrix for ODF's radial gradient definition
347 @param o_rGradientInfo
348 Receives the calculated texture transformation matrix (for
349 use with standard [0,1]x[0,1] texture coordinates)
351 @param rTargetArea
352 Output area, needed for aspect ratio calculations and
353 texture transformation
355 @param rOffset
356 Gradient offset value (from ODF)
358 @param nRequestedSteps
359 Number of gradient steps (from ODF)
361 @param fBorder
362 Width of gradient border (from ODF)
364 @param fAngle
365 Gradient angle (from ODF)
367 BASEGFX_DLLPUBLIC ODFGradientInfo createRadialODFGradientInfo(
368 const B2DRange& rTargetArea,
369 const B2DVector& rOffset,
370 sal_uInt32 nRequestedSteps,
371 double fBorder);
374 /** Calculate radial gradient blend value
376 This method generates you the lerp alpha value for
377 blending linearly between gradient start and end color,
378 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
380 @param rUV
381 Current uv coordinate. Values outside [0,1] will be
382 clamped.
384 @param rGradInfo
385 Gradient info, for transformation and number of steps
387 BASEGFX_DLLPUBLIC double getRadialGradientAlpha(const B2DPoint& rUV,
388 const ODFGradientInfo& rGradInfo);
390 /** Create matrix for ODF's elliptical gradient definition
392 @param o_rGradientInfo
393 Receives the calculated texture transformation matrix (for
394 use with standard [0,1]x[0,1] texture coordinates)
396 @param rTargetArea
397 Output area, needed for aspect ratio calculations and
398 texture transformation
400 @param rOffset
401 Gradient offset value (from ODF)
403 @param nRequestedSteps
404 Number of gradient steps (from ODF)
406 @param fBorder
407 Width of gradient border (from ODF)
409 @param fAngle
410 Gradient angle (from ODF)
412 BASEGFX_DLLPUBLIC ODFGradientInfo createEllipticalODFGradientInfo(
413 const B2DRange& rTargetArea,
414 const B2DVector& rOffset,
415 sal_uInt32 nRequestedSteps,
416 double fBorder,
417 double fAngle);
420 /** Calculate elliptical gradient blend value
422 This method generates you the lerp alpha value for
423 blending linearly between gradient start and end color,
424 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
426 @param rUV
427 Current uv coordinate. Values outside [0,1] will be
428 clamped.
430 @param rGradInfo
431 Gradient info, for transformation and number of steps
433 BASEGFX_DLLPUBLIC double getEllipticalGradientAlpha(const B2DPoint& rUV,
434 const ODFGradientInfo& rGradInfo);
436 /** Create matrix for ODF's square gradient definition
438 @param o_rGradientInfo
439 Receives the calculated texture transformation matrix (for
440 use with standard [0,1]x[0,1] texture coordinates)
442 @param rTargetArea
443 Output area, needed for aspect ratio calculations and
444 texture transformation
446 @param rOffset
447 Gradient offset value (from ODF)
449 @param nRequestedSteps
450 Number of gradient steps (from ODF)
452 @param fBorder
453 Width of gradient border (from ODF)
455 @param fAngle
456 Gradient angle (from ODF)
458 BASEGFX_DLLPUBLIC ODFGradientInfo createSquareODFGradientInfo(
459 const B2DRange& rTargetArea,
460 const B2DVector& rOffset,
461 sal_uInt32 nRequestedSteps,
462 double fBorder,
463 double fAngle);
466 /** Calculate square gradient blend value
468 This method generates you the lerp alpha value for
469 blending linearly between gradient start and end color,
470 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
472 @param rUV
473 Current uv coordinate. Values outside [0,1] will be
474 clamped.
476 @param rGradInfo
477 Gradient info, for transformation and number of steps
479 BASEGFX_DLLPUBLIC double getSquareGradientAlpha(const B2DPoint& rUV,
480 const ODFGradientInfo& rGradInfo);
482 /** Create matrix for ODF's rectangular gradient definition
484 @param o_rGradientInfo
485 Receives the calculated texture transformation matrix (for
486 use with standard [0,1]x[0,1] texture coordinates)
488 @param rTargetArea
489 Output area, needed for aspect ratio calculations and
490 texture transformation
492 @param rOffset
493 Gradient offset value (from ODF)
495 @param nRequestedSteps
496 Number of gradient steps (from ODF)
498 @param fBorder
499 Width of gradient border (from ODF)
501 @param fAngle
502 Gradient angle (from ODF)
504 BASEGFX_DLLPUBLIC ODFGradientInfo createRectangularODFGradientInfo(
505 const B2DRange& rTargetArea,
506 const B2DVector& rOffset,
507 sal_uInt32 nRequestedSteps,
508 double fBorder,
509 double fAngle);
512 /** Calculate rectangular gradient blend value
514 This method generates you the lerp alpha value for
515 blending linearly between gradient start and end color,
516 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
518 @param rUV
519 Current uv coordinate. Values outside [0,1] will be
520 clamped.
522 @param rGradInfo
523 Gradient info, for transformation and number of steps
525 BASEGFX_DLLPUBLIC double getRectangularGradientAlpha(const B2DPoint& rUV,
526 const ODFGradientInfo& rGradInfo);
530 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */