android: Update app icon to new startcenter icon
[LibreOffice.git] / basegfx / source / color / bcolormodifier.cxx
blob75c06f5cb8f3ab081f83cb400e9ae2e36e29411d
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 #include <sal/config.h>
21 #include <algorithm>
22 #include <float.h>
23 #include <basegfx/color/bcolormodifier.hxx>
24 #include <comphelper/random.hxx>
26 namespace basegfx
28 BColorModifier::~BColorModifier()
32 BColorModifier_gray::~BColorModifier_gray()
36 bool BColorModifier_gray::operator==(const BColorModifier& rCompare) const
38 return dynamic_cast< const BColorModifier_gray* >(&rCompare) != nullptr;
41 ::basegfx::BColor BColorModifier_gray::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
43 const double fLuminance(aSourceColor.luminance());
45 return ::basegfx::BColor(fLuminance, fLuminance, fLuminance);
48 OUString BColorModifier_gray::getModifierName() const
50 return "gray";
53 BColorModifier_invert::~BColorModifier_invert()
57 bool BColorModifier_invert::operator==(const BColorModifier& rCompare) const
59 return dynamic_cast< const BColorModifier_invert* >(&rCompare) != nullptr;
62 ::basegfx::BColor BColorModifier_invert::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
64 return ::basegfx::BColor(1.0 - aSourceColor.getRed(), 1.0 - aSourceColor.getGreen(), 1.0 - aSourceColor.getBlue());
67 OUString BColorModifier_invert::getModifierName() const
69 return "invert";
72 BColorModifier_luminance_to_alpha::~BColorModifier_luminance_to_alpha()
76 bool BColorModifier_luminance_to_alpha::operator==(const BColorModifier& rCompare) const
78 return dynamic_cast< const BColorModifier_luminance_to_alpha* >(&rCompare) != nullptr;
81 ::basegfx::BColor BColorModifier_luminance_to_alpha::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
83 const double fAlpha(1.0 - ((aSourceColor.getRed() * 0.2125) + (aSourceColor.getGreen() * 0.7154) + (aSourceColor.getBlue() * 0.0721)));
85 return ::basegfx::BColor(fAlpha, fAlpha, fAlpha);
88 OUString BColorModifier_luminance_to_alpha::getModifierName() const
90 return "luminance_to_alpha";
93 BColorModifier_replace::~BColorModifier_replace()
97 bool BColorModifier_replace::operator==(const BColorModifier& rCompare) const
99 const BColorModifier_replace* pCompare = dynamic_cast< const BColorModifier_replace* >(&rCompare);
101 if(!pCompare)
103 return false;
106 return getBColor() == pCompare->getBColor();
109 ::basegfx::BColor BColorModifier_replace::getModifiedColor(const ::basegfx::BColor& /*aSourceColor*/) const
111 return maBColor;
114 OUString BColorModifier_replace::getModifierName() const
116 return "replace";
119 BColorModifier_interpolate::~BColorModifier_interpolate()
123 bool BColorModifier_interpolate::operator==(const BColorModifier& rCompare) const
125 const BColorModifier_interpolate* pCompare = dynamic_cast< const BColorModifier_interpolate* >(&rCompare);
127 if(!pCompare)
129 return false;
132 return maBColor == pCompare->maBColor && mfValue == pCompare->mfValue;
135 ::basegfx::BColor BColorModifier_interpolate::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
137 return interpolate(maBColor, aSourceColor, mfValue);
140 OUString BColorModifier_interpolate::getModifierName() const
142 return "interpolate";
145 BColorModifier_matrix::~BColorModifier_matrix()
149 bool BColorModifier_matrix::operator==(const BColorModifier& rCompare) const
151 const BColorModifier_matrix* pCompare = dynamic_cast< const BColorModifier_matrix* >(&rCompare);
153 if(!pCompare)
155 return false;
158 return maVector == pCompare->maVector;
161 ::basegfx::BColor BColorModifier_matrix::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
163 if (maVector.size() != 20)
164 return aSourceColor;
166 const double aRed = maVector[0] * aSourceColor.getRed()
167 + maVector[1] * aSourceColor.getGreen()
168 + maVector[2] * aSourceColor.getBlue()
169 + maVector[3] * 1.0
170 + maVector[4];
171 const double aGreen = maVector[5] * aSourceColor.getRed()
172 + maVector[6] * aSourceColor.getGreen()
173 + maVector[7] * aSourceColor.getBlue()
174 + maVector[8] * 1.0
175 + maVector[9];
176 const double aBlue = maVector[10] * aSourceColor.getRed()
177 + maVector[11] * aSourceColor.getGreen()
178 + maVector[12] * aSourceColor.getBlue()
179 + maVector[13] * 1.0
180 + maVector[14];
181 /*TODO: add support for alpha
182 const double aAlpha = maVector[15] * aSourceColor.getRed()
183 + maVector[16] * aSourceColor.getGreen()
184 + maVector[17] * aSourceColor.getBlue()
185 + maVector[18] * 1.0
186 + maVector[19]);
189 return ::basegfx::BColor(
190 std::clamp(aRed, 0.0, 1.0),
191 std::clamp(aGreen, 0.0, 1.0),
192 std::clamp(aBlue, 0.0, 1.0));
195 OUString BColorModifier_matrix::getModifierName() const
197 return "matrix";
200 BColorModifier_saturate::BColorModifier_saturate(double fValue)
202 maSatMatrix.set(0, 0, 0.213 + 0.787 * fValue);
203 maSatMatrix.set(0, 1, 0.715 - 0.715 * fValue);
204 maSatMatrix.set(0, 2, 0.072 - 0.072 * fValue);
205 maSatMatrix.set(1, 0, 0.213 - 0.213 * fValue);
206 maSatMatrix.set(1, 1, 0.715 + 0.285 * fValue);
207 maSatMatrix.set(1, 2, 0.072 - 0.072 * fValue);
208 maSatMatrix.set(2, 0, 0.213 - 0.213 * fValue);
209 maSatMatrix.set(2, 1, 0.715 - 0.715 * fValue);
210 maSatMatrix.set(2, 2, 0.072 + 0.928 * fValue);
213 BColorModifier_saturate::~BColorModifier_saturate()
217 bool BColorModifier_saturate::operator==(const BColorModifier& rCompare) const
219 const BColorModifier_saturate* pCompare = dynamic_cast< const BColorModifier_saturate* >(&rCompare);
221 if(!pCompare)
223 return false;
226 return maSatMatrix == pCompare->maSatMatrix;
229 ::basegfx::BColor BColorModifier_saturate::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
231 basegfx::B3DHomMatrix aColorMatrix;
232 aColorMatrix.set(0, 0, aSourceColor.getRed());
233 aColorMatrix.set(1, 0, aSourceColor.getGreen());
234 aColorMatrix.set(2, 0, aSourceColor.getBlue());
236 aColorMatrix = maSatMatrix * aColorMatrix;
237 return ::basegfx::BColor(aColorMatrix.get(0, 0), aColorMatrix.get(1, 0), aColorMatrix.get(2, 0));
240 OUString BColorModifier_saturate::getModifierName() const
242 return "saturate";
245 BColorModifier_hueRotate::BColorModifier_hueRotate(double fRad)
247 const double fCos = cos(fRad);
248 const double fSin = sin(fRad);
250 maHueMatrix.set(0, 0, 0.213 + fCos * 0.787 - fSin * 0.213);
251 maHueMatrix.set(0, 1, 0.715 - fCos * 0.715 - fSin * 0.715);
252 maHueMatrix.set(0, 2, 0.072 - fCos * 0.072 + fSin * 0.928);
253 maHueMatrix.set(1, 0, 0.213 - fCos * 0.213 + fSin * 0.143);
254 maHueMatrix.set(1, 1, 0.715 + fCos * 0.285 + fSin * 0.140);
255 maHueMatrix.set(1, 2, 0.072 - fCos * 0.072 - fSin * 0.283);
256 maHueMatrix.set(2, 0, 0.213 - fCos * 0.213 - fSin * 0.787);
257 maHueMatrix.set(2, 1, 0.715 - fCos * 0.715 + fSin * 0.715);
258 maHueMatrix.set(2, 2, 0.072 + fCos * 0.928 + fSin * 0.072);
261 BColorModifier_hueRotate::~BColorModifier_hueRotate()
265 bool BColorModifier_hueRotate::operator==(const BColorModifier& rCompare) const
267 const BColorModifier_hueRotate* pCompare = dynamic_cast< const BColorModifier_hueRotate* >(&rCompare);
269 if(!pCompare)
271 return false;
274 return maHueMatrix == pCompare->maHueMatrix;
277 ::basegfx::BColor BColorModifier_hueRotate::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
279 basegfx::B3DHomMatrix aColorMatrix;
280 aColorMatrix.set(0, 0, aSourceColor.getRed());
281 aColorMatrix.set(1, 0, aSourceColor.getGreen());
282 aColorMatrix.set(2, 0, aSourceColor.getBlue());
284 aColorMatrix = maHueMatrix * aColorMatrix;
285 return ::basegfx::BColor(
286 std::clamp(aColorMatrix.get(0, 0), 0.0, 1.0),
287 std::clamp(aColorMatrix.get(1, 0), 0.0, 1.0),
288 std::clamp(aColorMatrix.get(2, 0), 0.0, 1.0));
291 OUString BColorModifier_hueRotate::getModifierName() const
293 return "hueRotate";
296 BColorModifier_black_and_white::~BColorModifier_black_and_white()
300 bool BColorModifier_black_and_white::operator==(const BColorModifier& rCompare) const
302 const BColorModifier_black_and_white* pCompare = dynamic_cast< const BColorModifier_black_and_white* >(&rCompare);
304 if(!pCompare)
306 return false;
309 return mfValue == pCompare->mfValue;
312 ::basegfx::BColor BColorModifier_black_and_white::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
314 const double fLuminance(aSourceColor.luminance());
316 if(fLuminance < mfValue)
318 return ::basegfx::BColor::getEmptyBColor();
320 else
322 return ::basegfx::BColor(1.0, 1.0, 1.0);
326 OUString BColorModifier_black_and_white::getModifierName() const
328 return "black_and_white";
331 BColorModifier_gamma::BColorModifier_gamma(double fValue)
332 : mfValue(fValue),
333 mfInvValue(fValue),
334 mbUseIt(!basegfx::fTools::equal(fValue, 1.0) && basegfx::fTools::more(fValue, 0.0) && basegfx::fTools::lessOrEqual(fValue, 10.0))
336 if(mbUseIt)
338 mfInvValue = 1.0 / mfValue;
342 BColorModifier_gamma::~BColorModifier_gamma()
346 bool BColorModifier_gamma::operator==(const BColorModifier& rCompare) const
348 const BColorModifier_gamma* pCompare = dynamic_cast< const BColorModifier_gamma* >(&rCompare);
350 if(!pCompare)
352 return false;
355 // getValue is sufficient, mfInvValue and mbUseIt are only helper values
356 return mfValue == pCompare->mfValue;
359 ::basegfx::BColor BColorModifier_gamma::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
361 if(mbUseIt)
363 ::basegfx::BColor aRetval(
364 pow(aSourceColor.getRed(), mfInvValue),
365 pow(aSourceColor.getGreen(), mfInvValue),
366 pow(aSourceColor.getBlue(), mfInvValue));
368 aRetval.clamp();
369 return aRetval;
371 else
373 return aSourceColor;
377 OUString BColorModifier_gamma::getModifierName() const
379 return "gamma";
382 BColorModifier_RGBLuminanceContrast::BColorModifier_RGBLuminanceContrast(double fRed, double fGreen, double fBlue, double fLuminance, double fContrast)
383 : mfRed(std::clamp(fRed, -1.0, 1.0)),
384 mfGreen(std::clamp(fGreen, -1.0, 1.0)),
385 mfBlue(std::clamp(fBlue, -1.0, 1.0)),
386 mfLuminance(std::clamp(fLuminance, -1.0, 1.0)),
387 mfContrast(std::clamp(fContrast, -1.0, 1.0)),
388 mfContrastOff(1.0),
389 mfRedOff(0.0),
390 mfGreenOff(0.0),
391 mfBlueOff(0.0),
392 mbUseIt(false)
394 if(basegfx::fTools::equalZero(mfRed)
395 && basegfx::fTools::equalZero(mfGreen)
396 && basegfx::fTools::equalZero(mfBlue)
397 && basegfx::fTools::equalZero(mfLuminance)
398 && basegfx::fTools::equalZero(mfContrast))
399 return;
401 // calculate slope
402 if(mfContrast >= 0.0)
404 mfContrastOff = 128.0 / (128.0 - (mfContrast * 127.0));
406 else
408 mfContrastOff = ( 128.0 + (mfContrast * 127.0)) / 128.0;
411 // calculate unified contrast offset
412 const double fPreparedContrastOff((128.0 - mfContrastOff * 128.0) / 255.0);
413 const double fCombinedOffset(mfLuminance + fPreparedContrastOff);
415 // set full offsets
416 mfRedOff = mfRed + fCombinedOffset;
417 mfGreenOff = mfGreen + fCombinedOffset;
418 mfBlueOff = mfBlue + fCombinedOffset;
420 mbUseIt = true;
423 BColorModifier_RGBLuminanceContrast::~BColorModifier_RGBLuminanceContrast()
427 bool BColorModifier_RGBLuminanceContrast::operator==(const BColorModifier& rCompare) const
429 const BColorModifier_RGBLuminanceContrast* pCompare = dynamic_cast< const BColorModifier_RGBLuminanceContrast* >(&rCompare);
431 if(!pCompare)
433 return false;
436 // no need to compare other values, these are just helpers
437 return mfRed == pCompare->mfRed
438 && mfGreen == pCompare->mfGreen
439 && mfBlue == pCompare->mfBlue
440 && mfLuminance == pCompare->mfLuminance
441 && mfContrast == pCompare->mfContrast;
444 ::basegfx::BColor BColorModifier_RGBLuminanceContrast::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
446 if(mbUseIt)
448 return basegfx::BColor(
449 std::clamp(aSourceColor.getRed() * mfContrastOff + mfRedOff, 0.0, 1.0),
450 std::clamp(aSourceColor.getGreen() * mfContrastOff + mfGreenOff, 0.0, 1.0),
451 std::clamp(aSourceColor.getBlue() * mfContrastOff + mfBlueOff, 0.0, 1.0));
453 else
455 return aSourceColor;
459 OUString BColorModifier_RGBLuminanceContrast::getModifierName() const
461 return "RGBLuminanceContrast";
464 BColorModifier_randomize::BColorModifier_randomize(double fRandomPart)
465 : mfRandomPart(fRandomPart)
469 BColorModifier_randomize::~BColorModifier_randomize()
473 // compare operator
474 bool BColorModifier_randomize::operator==(const BColorModifier& rCompare) const
476 const BColorModifier_randomize* pCompare = dynamic_cast< const BColorModifier_randomize* >(&rCompare);
478 if(!pCompare)
480 return false;
483 return mfRandomPart == pCompare->mfRandomPart;
486 // compute modified color
487 ::basegfx::BColor BColorModifier_randomize::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
489 if(0.0 >= mfRandomPart)
491 // no randomizing, use orig color
492 return aSourceColor;
495 if(1.0 <= mfRandomPart)
497 // full randomized color
498 return basegfx::BColor(
499 comphelper::rng::uniform_real_distribution(0.0, nextafter(1.0, DBL_MAX)),
500 comphelper::rng::uniform_real_distribution(0.0, nextafter(1.0, DBL_MAX)),
501 comphelper::rng::uniform_real_distribution(0.0, nextafter(1.0, DBL_MAX)));
504 // mixed color
505 const double fMulA(1.0 - mfRandomPart);
506 return basegfx::BColor(
507 aSourceColor.getRed() * fMulA +
508 comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)),
509 aSourceColor.getGreen() * fMulA +
510 comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)),
511 aSourceColor.getBlue() * fMulA +
512 comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)));
515 OUString BColorModifier_randomize::getModifierName() const
517 return "randomize";
520 ::basegfx::BColor BColorModifierStack::getModifiedColor(const ::basegfx::BColor& rSource) const
522 if(maBColorModifiers.empty())
524 return rSource;
527 ::basegfx::BColor aRetval(rSource);
529 for(sal_uInt32 a(maBColorModifiers.size()); a;)
531 a--;
532 aRetval = maBColorModifiers[a]->getModifiedColor(aRetval);
535 return aRetval;
537 } // end of namespace basegfx
539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */