Revert "Revert "Revert "stronger typing for SwClient::GetRegisteredIn"" and fix SwIte...
[LibreOffice.git] / include / basegfx / utils / gradienttools.hxx
blobd56e73b90dd9d9f9069514ac1abb601ac190d930
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 <basegfx/utils/bgradient.hxx>
30 #include <osl/endian.h>
32 namespace basegfx { class B2DRange; }
34 namespace
36 /* Internal helper to convert ::Color from tools::color.hxx to BColor
37 without the need to link against tools library. Be on the
38 safe side by using the same union
40 struct ColorToBColorConverter
42 union {
43 sal_uInt32 mValue;
44 struct {
45 #ifdef OSL_BIGENDIAN
46 sal_uInt8 T;
47 sal_uInt8 R;
48 sal_uInt8 G;
49 sal_uInt8 B;
50 #else
51 sal_uInt8 B;
52 sal_uInt8 G;
53 sal_uInt8 R;
54 sal_uInt8 T;
55 #endif
59 ColorToBColorConverter GetRGBColor() const
61 return {R, G, B};
64 ColorToBColorConverter(sal_uInt32 nColor)
65 : mValue(nColor)
66 { T=0; }
68 constexpr ColorToBColorConverter(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
69 : mValue(sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16))
72 explicit ColorToBColorConverter(const basegfx::BColor& rBColor)
73 : ColorToBColorConverter(
74 sal_uInt8(std::lround(rBColor.getRed() * 255.0)),
75 sal_uInt8(std::lround(rBColor.getGreen() * 255.0)),
76 sal_uInt8(std::lround(rBColor.getBlue() * 255.0)))
79 basegfx::BColor getBColor() const
81 return basegfx::BColor(R / 255.0, G / 255.0, B / 255.0);
84 constexpr explicit operator sal_Int32() const
86 return sal_Int32(mValue);
89 constexpr explicit operator sal_uInt32() const
91 return mValue;
96 namespace basegfx
98 /** Gradient definition as used in ODF 1.2
100 This struct collects all data necessary for rendering ODF
101 1.2-compatible gradients. Use the createXXXODFGradientInfo()
102 methods below for initializing from ODF attributes.
104 class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ODFGradientInfo
106 private:
107 /** transformation mapping from [0,1]^2 texture coordinate
108 space to [0,1]^2 shape coordinate space
110 B2DHomMatrix maTextureTransform;
112 /** transformation mapping from [0,1]^2 shape coordinate space
113 to [0,1]^2 texture coordinate space. This is the
114 transformation commonly used to create gradients from a
115 scanline rasterizer (put shape u/v coordinates into it, get
116 texture s/t coordinates out of it)
118 B2DHomMatrix maBackTextureTransform;
120 /** Aspect ratio of the gradient. Only used in drawinglayer
121 for generating nested gradient polygons currently. Already
122 catered for in the transformations above.
124 double mfAspectRatio;
126 /** Requested gradient steps to render. See the
127 implementations of the getXXXGradientAlpha() methods below,
128 the semantic differs slightly for the different gradient
129 types.
131 sal_uInt32 mnRequestedSteps;
133 public:
134 ODFGradientInfo()
135 : mfAspectRatio(1.0),
136 mnRequestedSteps(0)
140 ODFGradientInfo(
141 B2DHomMatrix aTextureTransform,
142 double fAspectRatio,
143 sal_uInt32 nRequestedSteps)
144 : maTextureTransform(std::move(aTextureTransform)),
145 mfAspectRatio(fAspectRatio),
146 mnRequestedSteps(nRequestedSteps)
150 ODFGradientInfo(const ODFGradientInfo& rODFGradientInfo)
151 : maTextureTransform(rODFGradientInfo.getTextureTransform()),
152 maBackTextureTransform(rODFGradientInfo.maBackTextureTransform),
153 mfAspectRatio(rODFGradientInfo.getAspectRatio()),
154 mnRequestedSteps(rODFGradientInfo.getRequestedSteps())
158 ODFGradientInfo& operator=(const ODFGradientInfo& rODFGradientInfo)
160 maTextureTransform = rODFGradientInfo.getTextureTransform();
161 maBackTextureTransform = rODFGradientInfo.maBackTextureTransform;
162 mfAspectRatio = rODFGradientInfo.getAspectRatio();
163 mnRequestedSteps = rODFGradientInfo.getRequestedSteps();
165 return *this;
168 // compare operator
169 bool operator==(const ODFGradientInfo& rGeoTexSvx) const;
171 const B2DHomMatrix& getTextureTransform() const { return maTextureTransform; }
172 const B2DHomMatrix& getBackTextureTransform() const;
173 double getAspectRatio() const { return mfAspectRatio; }
174 sal_uInt32 getRequestedSteps() const { return mnRequestedSteps; }
176 void setTextureTransform(const B2DHomMatrix& rNew)
178 maTextureTransform = rNew;
179 maBackTextureTransform.identity();
183 namespace utils
185 /* Tooling method to extract data from given BGradient
186 to ColorStops, doing some corrections, partially based
187 on given SingleColor.
188 This is used for export preparations in case these exports
189 do neither support Start/EndIntensity nor Border settings,
190 both will be eliminated if possible (see below).
191 The BGradient rGradient and BColorStops& rColorStops
192 are both return parameters and may be changed.
193 This will do quite some preparations for the gradient
194 as follows:
195 - It will check for single color (resetting rSingleColor when
196 this is the case) and return with empty ColorStops
197 - It will blend ColorStops to Intensity if StartIntensity/
198 EndIntensity != 100 is set in BGradient, so applying
199 that value(s) to the gradient directly
200 - It will adapt to Border if Border != 0 is set at the
201 given BGradient, so applying that value to the gradient
202 directly
204 BASEGFX_DLLPUBLIC void prepareColorStops(
205 const basegfx::BGradient& rGradient,
206 BColorStops& rColorStops,
207 BColor& rSingleColor);
209 /* Tooling method to synchronize the given ColorStops.
210 The intention is that a color GradientStops and an
211 alpha/transparence GradientStops gets synchronized
212 for export.
213 For the corrections the single values for color and
214 alpha may be used, e.g. when ColorStops is given
215 and not empty, but AlphaStops is empty, it will get
216 synchronized so that it will have the same number and
217 offsets in AlphaStops as in ColorStops, but with
218 the given SingleAlpha as value.
219 At return it guarantees that both have the same
220 number of entries with the same StopOffsets, so
221 that synchronized pair of ColorStops can e.g. be used
222 to export a Gradient with defined/adapted alpha
223 being 'coupled' indirectly using the
224 'FillTransparenceGradient' method (at import time).
226 BASEGFX_DLLPUBLIC void synchronizeColorStops(
227 BColorStops& rColorStops,
228 BColorStops& rAlphaStops,
229 const BColor& rSingleColor,
230 const BColor& rSingleAlpha);
232 /* Helper to calculate numberOfSteps needed to represent
233 gradient for the given two colors:
234 - to define only based on color distance, give 0 == nRequestedSteps
235 as wanted value, so color distance will be used
236 - if a wanted value of nRequestedSteps is given, it gets synched
237 against the maximum number of steps defined by the color
238 distance of the two colors
239 - a minimum result of 1 is returned which means a single
240 step -> no real gradient
242 BASEGFX_DLLPUBLIC sal_uInt32 calculateNumberOfSteps(
243 sal_uInt32 nRequestedSteps,
244 const BColor& rStart,
245 const BColor& rEnd);
247 /** Create matrix for ODF's linear gradient definition
249 Note that odf linear gradients are varying in y direction.
251 @param o_rGradientInfo
252 Receives the calculated texture transformation matrix (for
253 use with standard [0,1]x[0,1] texture coordinates)
255 @param rTargetArea
256 Output area, needed for aspect ratio calculations and
257 texture transformation
259 @param nRequestedSteps
260 Number of gradient steps (from ODF)
262 @param fBorder
263 Width of gradient border (from ODF)
265 @param fAngle
266 Gradient angle (from ODF)
268 BASEGFX_DLLPUBLIC ODFGradientInfo createLinearODFGradientInfo(
269 const B2DRange& rTargetArea,
270 sal_uInt32 nRequestedSteps,
271 double fBorder,
272 double fAngle);
275 /** Calculate linear gradient blend value
277 This method generates you the lerp alpha value for
278 blending linearly between gradient start and end color,
279 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
281 @param rUV
282 Current uv coordinate. Values outside [0,1] will be
283 clamped. Assumes gradient color varies along the y axis.
285 @param rGradInfo
286 Gradient info, for transformation and number of steps
288 BASEGFX_DLLPUBLIC double getLinearGradientAlpha(const B2DPoint& rUV,
289 const ODFGradientInfo& rGradInfo);
291 /** Create matrix for ODF's axial gradient definition
293 Note that odf axial gradients are varying in y
294 direction. Note further that you can map the axial
295 gradient to a linear gradient (in case you want or need to
296 avoid an extra gradient renderer), by using
297 createLinearODFGradientInfo() instead, shifting the
298 resulting texture transformation by 0.5 to the top and
299 appending the same stop colors again, but mirrored.
301 @param o_rGradientInfo
302 Receives the calculated texture transformation matrix (for
303 use with standard [0,1]x[0,1] texture coordinates)
305 @param rTargetArea
306 Output area, needed for aspect ratio calculations and
307 texture transformation
309 @param nRequestedSteps
310 Number of gradient steps (from ODF)
312 @param fBorder
313 Width of gradient border (from ODF)
315 @param fAngle
316 Gradient angle (from ODF)
318 BASEGFX_DLLPUBLIC ODFGradientInfo createAxialODFGradientInfo(
319 const B2DRange& rTargetArea,
320 sal_uInt32 nRequestedSteps,
321 double fBorder,
322 double fAngle);
325 /** Calculate axial gradient blend value
327 This method generates you the lerp alpha value for
328 blending linearly between gradient start and end color,
329 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
331 @param rUV
332 Current uv coordinate. Values outside [0,1] will be
333 clamped. Assumes gradient color varies along the y axis.
335 @param rGradInfo
336 Gradient info, for transformation and number of steps
338 BASEGFX_DLLPUBLIC double getAxialGradientAlpha(const B2DPoint& rUV,
339 const ODFGradientInfo& rGradInfo);
341 /** Create matrix for ODF's radial gradient definition
343 @param o_rGradientInfo
344 Receives the calculated texture transformation matrix (for
345 use with standard [0,1]x[0,1] texture coordinates)
347 @param rTargetArea
348 Output area, needed for aspect ratio calculations and
349 texture transformation
351 @param rOffset
352 Gradient offset value (from ODF)
354 @param nRequestedSteps
355 Number of gradient steps (from ODF)
357 @param fBorder
358 Width of gradient border (from ODF)
360 @param fAngle
361 Gradient angle (from ODF)
363 BASEGFX_DLLPUBLIC ODFGradientInfo createRadialODFGradientInfo(
364 const B2DRange& rTargetArea,
365 const B2DVector& rOffset,
366 sal_uInt32 nRequestedSteps,
367 double fBorder);
370 /** Calculate radial gradient blend value
372 This method generates you the lerp alpha value for
373 blending linearly between gradient start and end color,
374 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
376 @param rUV
377 Current uv coordinate. Values outside [0,1] will be
378 clamped.
380 @param rGradInfo
381 Gradient info, for transformation and number of steps
383 BASEGFX_DLLPUBLIC double getRadialGradientAlpha(const B2DPoint& rUV,
384 const ODFGradientInfo& rGradInfo);
386 /** Create matrix for ODF's elliptical gradient definition
388 @param o_rGradientInfo
389 Receives the calculated texture transformation matrix (for
390 use with standard [0,1]x[0,1] texture coordinates)
392 @param rTargetArea
393 Output area, needed for aspect ratio calculations and
394 texture transformation
396 @param rOffset
397 Gradient offset value (from ODF)
399 @param nRequestedSteps
400 Number of gradient steps (from ODF)
402 @param fBorder
403 Width of gradient border (from ODF)
405 @param fAngle
406 Gradient angle (from ODF)
408 BASEGFX_DLLPUBLIC ODFGradientInfo createEllipticalODFGradientInfo(
409 const B2DRange& rTargetArea,
410 const B2DVector& rOffset,
411 sal_uInt32 nRequestedSteps,
412 double fBorder,
413 double fAngle);
416 /** Calculate elliptical gradient blend value
418 This method generates you the lerp alpha value for
419 blending linearly between gradient start and end color,
420 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
422 @param rUV
423 Current uv coordinate. Values outside [0,1] will be
424 clamped.
426 @param rGradInfo
427 Gradient info, for transformation and number of steps
429 BASEGFX_DLLPUBLIC double getEllipticalGradientAlpha(const B2DPoint& rUV,
430 const ODFGradientInfo& rGradInfo);
432 /** Create matrix for ODF's square gradient definition
434 @param o_rGradientInfo
435 Receives the calculated texture transformation matrix (for
436 use with standard [0,1]x[0,1] texture coordinates)
438 @param rTargetArea
439 Output area, needed for aspect ratio calculations and
440 texture transformation
442 @param rOffset
443 Gradient offset value (from ODF)
445 @param nRequestedSteps
446 Number of gradient steps (from ODF)
448 @param fBorder
449 Width of gradient border (from ODF)
451 @param fAngle
452 Gradient angle (from ODF)
454 BASEGFX_DLLPUBLIC ODFGradientInfo createSquareODFGradientInfo(
455 const B2DRange& rTargetArea,
456 const B2DVector& rOffset,
457 sal_uInt32 nRequestedSteps,
458 double fBorder,
459 double fAngle);
462 /** Calculate square gradient blend value
464 This method generates you the lerp alpha value for
465 blending linearly between gradient start and end color,
466 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
468 @param rUV
469 Current uv coordinate. Values outside [0,1] will be
470 clamped.
472 @param rGradInfo
473 Gradient info, for transformation and number of steps
475 BASEGFX_DLLPUBLIC double getSquareGradientAlpha(const B2DPoint& rUV,
476 const ODFGradientInfo& rGradInfo);
478 /** Create matrix for ODF's rectangular gradient definition
480 @param o_rGradientInfo
481 Receives the calculated texture transformation matrix (for
482 use with standard [0,1]x[0,1] texture coordinates)
484 @param rTargetArea
485 Output area, needed for aspect ratio calculations and
486 texture transformation
488 @param rOffset
489 Gradient offset value (from ODF)
491 @param nRequestedSteps
492 Number of gradient steps (from ODF)
494 @param fBorder
495 Width of gradient border (from ODF)
497 @param fAngle
498 Gradient angle (from ODF)
500 BASEGFX_DLLPUBLIC ODFGradientInfo createRectangularODFGradientInfo(
501 const B2DRange& rTargetArea,
502 const B2DVector& rOffset,
503 sal_uInt32 nRequestedSteps,
504 double fBorder,
505 double fAngle);
508 /** Calculate rectangular gradient blend value
510 This method generates you the lerp alpha value for
511 blending linearly between gradient start and end color,
512 according to the formula (startCol*(1.0-alpha) + endCol*alpha)
514 @param rUV
515 Current uv coordinate. Values outside [0,1] will be
516 clamped.
518 @param rGradInfo
519 Gradient info, for transformation and number of steps
521 BASEGFX_DLLPUBLIC double getRectangularGradientAlpha(const B2DPoint& rUV,
522 const ODFGradientInfo& rGradInfo);
526 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */