1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <config_options.h>
23 #include <basegfx/basegfxdllapi.h>
24 #include <basegfx/matrix/b3dhommatrix.hxx>
25 #include <basegfx/color/bcolor.hxx>
26 #include <rtl/ustring.hxx>
28 #include <osl/diagnose.h>
35 enum class BColorModifierType
: sal_uInt16
{
38 BCMType_luminance_to_alpha
,
44 BCMType_black_and_white
,
46 BCMType_RGBLuminanceContrast
,
50 /** base class to define color modifications
52 The basic idea is to have instances of color modifiers where each
53 of these can be asked to get a modified version of a color. This
54 can be as easy as to return a fixed color, but may also do any
55 other computation based on the given source color and the local
58 This base implementation defines the abstract base class. Every
59 derivation offers another color blending effect, when needed with
60 parameters for that blending defined as members.
62 As long as aw080 is not applied, an operator== is needed to implement
63 the operator== of the primitive based on this instances.
65 For the exact definitions of the color blending applied refer to the
66 implementation of the method getModifiedColor
68 BColorModifier is not copyable (no copy constructor, no assignment
69 operator); local values cannot be changed after construction. The
70 instances are cheap and the idea is to create them on demand. To
71 be able to reuse these as much as possible, a define for a
72 std::shared_ptr named BColorModifierSharedPtr exists below.
73 All usages should handle instances of BColorModifier encapsulated
74 into these shared pointers.
76 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier
79 BColorModifierType maType
;
80 BColorModifier(const BColorModifier
&) = delete;
81 BColorModifier
& operator=(const BColorModifier
&) = delete;
83 // no one is allowed to incarnate the abstract base class
85 BColorModifier(BColorModifierType aType
)
91 // no one should directly destroy it; all incarnations should be
92 // handled in a std::shared_ptr of type BColorModifierSharedPtr
93 virtual ~BColorModifier();
96 virtual bool operator==(const BColorModifier
& rCompare
) const
98 if (maType
!= rCompare
.maType
)
104 bool operator!=(const BColorModifier
& rCompare
) const
106 if (maType
!= rCompare
.maType
)
109 return !(operator==(rCompare
));
112 // compute modified color
113 virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const = 0;
115 virtual OUString
getModifierName() const = 0;
118 BColorModifierType
getBColorModifierType() const { return maType
; }
121 /** convert color to gray
123 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_gray final
: public BColorModifier
126 BColorModifier_gray()
127 : BColorModifier(basegfx::BColorModifierType::BCMType_gray
)
131 virtual ~BColorModifier_gray() override
;
133 // compute modified color
134 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
135 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
140 returns a color where red green and blue are inverted using 1.0 - n
142 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_invert final
: public BColorModifier
145 BColorModifier_invert()
146 : BColorModifier(basegfx::BColorModifierType::BCMType_invert
)
150 virtual ~BColorModifier_invert() override
;
152 // compute modified color
153 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
154 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
157 /** convert to alpha based on luminance
159 returns a color where red green and blue are first weighted and added
160 to build a luminance value which is then inverted and used for red,
161 green and blue. The weights are r * 0.2125 + g * 0.7154 + b * 0.0721.
162 This derivation is used for the svg importer and does exactly what SVG
163 defines for this needed case.
165 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_luminance_to_alpha final
: public BColorModifier
168 BColorModifier_luminance_to_alpha()
169 : BColorModifier(basegfx::BColorModifierType::BCMType_luminance_to_alpha
)
173 virtual ~BColorModifier_luminance_to_alpha() override
;
175 // compute modified color
176 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
177 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
182 does not use the source color at all, but always returns the
183 given color, replacing everything. Useful e.g. for unified shadow
186 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_replace final
: public BColorModifier
189 ::basegfx::BColor maBColor
;
192 BColorModifier_replace(const ::basegfx::BColor
& rBColor
)
193 : BColorModifier(basegfx::BColorModifierType::BCMType_replace
)
198 virtual ~BColorModifier_replace() override
;
201 const ::basegfx::BColor
& getBColor() const { return maBColor
; }
204 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
206 // compute modified color
207 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
208 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
211 /** interpolate color
213 returns an interpolated color mixed by the given value (f) in the range
214 [0.0 .. 1.0] and the given color (col) as follows:
216 col * (1 - f) + aSourceColor * f
218 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_interpolate final
: public BColorModifier
221 ::basegfx::BColor maBColor
;
225 BColorModifier_interpolate(const ::basegfx::BColor
& rBColor
, double fValue
)
226 : BColorModifier(basegfx::BColorModifierType::BCMType_interpolate
)
232 virtual ~BColorModifier_interpolate() override
;
235 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
237 // compute modified color
238 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
239 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
243 This derivation is used for the svg importer and does exactly what SVG
244 defines for this needed case.
247 https://www.w3.org/TR/filter-effects/#elementdef-fecolormatrix
249 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_saturate final
: public BColorModifier
252 basegfx::B3DHomMatrix maSatMatrix
;
255 BColorModifier_saturate(double fValue
);
257 virtual ~BColorModifier_saturate() override
;
260 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
262 // compute modified color
263 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
264 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
268 This derivation is used for the svg importer and does exactly what SVG
269 defines for this needed case.
272 https://www.w3.org/TR/filter-effects/#elementdef-fecolormatrix
274 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_matrix final
: public BColorModifier
277 std::vector
<double> maVector
;
280 BColorModifier_matrix(std::vector
<double> aVector
)
281 : BColorModifier(basegfx::BColorModifierType::BCMType_matrix
)
282 , maVector(std::move(aVector
))
286 virtual ~BColorModifier_matrix() override
;
289 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
290 // compute modified color
291 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
292 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
296 This derivation is used for the svg importer and does exactly what SVG
297 defines for this needed case.
300 https://www.w3.org/TR/filter-effects/#elementdef-fecolormatrix
302 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_hueRotate final
: public BColorModifier
305 basegfx::B3DHomMatrix maHueMatrix
;
308 BColorModifier_hueRotate(double fRad
);
310 virtual ~BColorModifier_hueRotate() override
;
313 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
315 // compute modified color
316 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
317 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
320 /** convert color to black and white
322 returns black when the luminance of the given color is less than
323 the given threshold value in the range [0.0 .. 1.0], else white
325 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_black_and_white final
: public BColorModifier
331 BColorModifier_black_and_white(double fValue
)
332 : BColorModifier(basegfx::BColorModifierType::BCMType_black_and_white
)
337 virtual ~BColorModifier_black_and_white() override
;
340 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
342 // compute modified color
343 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
344 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
349 Input is a gamma correction value in the range ]0.0 .. 10.0]; the
350 color values get corrected using
352 col(r,g,b) = clamp(pow(col(r,g,b), 1.0 / gamma), 0.0, 1.0)
354 class SAL_WARN_UNUSED
UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC
) BColorModifier_gamma final
: public BColorModifier
363 BColorModifier_gamma(double fValue
);
365 virtual ~BColorModifier_gamma() override
;
368 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
370 // compute modified color
371 virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
372 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
375 /** Red, Green, Blue, Luminance and Contrast correction
377 Input are percent values from [-1.0 .. 1-0] which correspond to -100% to 100%
378 correction of Red, Green, Blue, Luminance or Contrast. 0.0 means no change of
379 the corresponding channel. All these are combined (but can be used single) to
380 - be able to cover a bigger change range utilizing the combination
381 - allow execution by a small, common, precalculated table
383 class SAL_WARN_UNUSED
UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC
) BColorModifier_RGBLuminanceContrast final
: public BColorModifier
392 double mfContrastOff
;
400 BColorModifier_RGBLuminanceContrast(double fRed
, double fGreen
, double fBlue
, double fLuminance
, double fContrast
);
402 virtual ~BColorModifier_RGBLuminanceContrast() override
;
405 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
407 // compute modified color
408 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
409 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
412 /** mix a part of the original color with randomized color (mainly for debug visualizations)
414 class SAL_WARN_UNUSED
UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC
) BColorModifier_randomize final
: public BColorModifier
417 // [0.0 .. 1.0] where 0.0 is no randomize, 1.0 is all random and in-between
418 // describes the mixed part. Default is 0.1 which means to mix with 10% random color
422 BColorModifier_randomize(double fRandomPart
= 0.1);
424 virtual ~BColorModifier_randomize() override
;
427 SAL_DLLPRIVATE
virtual bool operator==(const BColorModifier
& rCompare
) const override
;
429 // compute modified color
430 SAL_DLLPRIVATE
virtual ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& aSourceColor
) const override
;
431 SAL_DLLPRIVATE
virtual OUString
getModifierName() const override
;
434 /// typedef to allow working with shared instances of BColorModifier
435 /// for the whole mechanism
436 typedef std::shared_ptr
< BColorModifier
> BColorModifierSharedPtr
;
438 /** Class to hold a stack of BColorModifierSharedPtrs and to get the modified color with
439 applying all existing entry changes as defined in the stack. Instances of BColorModifier
440 can be pushed and popped to change the stack.
442 All references to BColorModifier members use shared pointers, thus instances of
443 BColorModifierStack can be copied by the default mechanisms if needed.
445 class BASEGFX_DLLPUBLIC BColorModifierStack final
447 ::std::vector
< BColorModifierSharedPtr
> maBColorModifiers
;
450 sal_uInt32
count() const
452 return maBColorModifiers
.size();
455 const BColorModifierSharedPtr
& getBColorModifier(sal_uInt32 nIndex
) const
457 OSL_ENSURE(nIndex
< count(), "BColorModifierStack: Access out of range (!)");
458 return maBColorModifiers
[nIndex
];
461 // get the color in its modified form by applying all existing BColorModifiers,
462 // from back to front (the newest first)
463 ::basegfx::BColor
getModifiedColor(const ::basegfx::BColor
& rSource
) const;
465 void push(const BColorModifierSharedPtr
& rNew
)
467 maBColorModifiers
.push_back(rNew
);
472 maBColorModifiers
.pop_back();
475 bool operator==(const BColorModifierStack
& rComp
) const;
477 } // end of namespace basegfx
479 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */