2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../../core/juce_StandardHeader.h"
30 #include "juce_Colours.h"
33 //==============================================================================
34 namespace ColourHelpers
36 uint8
floatAlphaToInt (const float alpha
) noexcept
38 return (uint8
) jlimit (0, 0xff, roundToInt (alpha
* 255.0f
));
41 void convertHSBtoRGB (float h
, float s
, float v
,
42 uint8
& r
, uint8
& g
, uint8
& b
) noexcept
44 v
= jlimit (0.0f
, 1.0f
, v
);
46 const uint8 intV
= (uint8
) roundToInt (v
);
57 h
= (h
- std::floor (h
)) * 6.0f
+ 0.00001f
; // need a small adjustment to compensate for rounding errors
58 const float f
= h
- std::floor (h
);
59 const uint8 x
= (uint8
) roundToInt (v
* (1.0f
- s
));
64 g
= (uint8
) roundToInt (v
* (1.0f
- (s
* (1.0f
- f
))));
69 r
= (uint8
) roundToInt (v
* (1.0f
- s
* f
));
77 b
= (uint8
) roundToInt (v
* (1.0f
- (s
* (1.0f
- f
))));
82 g
= (uint8
) roundToInt (v
* (1.0f
- s
* f
));
87 r
= (uint8
) roundToInt (v
* (1.0f
- (s
* (1.0f
- f
))));
95 b
= (uint8
) roundToInt (v
* (1.0f
- s
* f
));
101 //==============================================================================
102 Colour::Colour() noexcept
107 Colour::Colour (const Colour
& other
) noexcept
112 Colour
& Colour::operator= (const Colour
& other
) noexcept
118 bool Colour::operator== (const Colour
& other
) const noexcept
120 return argb
.getARGB() == other
.argb
.getARGB();
123 bool Colour::operator!= (const Colour
& other
) const noexcept
125 return argb
.getARGB() != other
.argb
.getARGB();
128 //==============================================================================
129 Colour::Colour (const uint32 argb_
) noexcept
134 Colour::Colour (const uint8 red
,
136 const uint8 blue
) noexcept
138 argb
.setARGB (0xff, red
, green
, blue
);
141 Colour
Colour::fromRGB (const uint8 red
,
143 const uint8 blue
) noexcept
145 return Colour (red
, green
, blue
);
148 Colour::Colour (const uint8 red
,
151 const uint8 alpha
) noexcept
153 argb
.setARGB (alpha
, red
, green
, blue
);
156 Colour
Colour::fromRGBA (const uint8 red
,
159 const uint8 alpha
) noexcept
161 return Colour (red
, green
, blue
, alpha
);
164 Colour::Colour (const uint8 red
,
167 const float alpha
) noexcept
169 argb
.setARGB (ColourHelpers::floatAlphaToInt (alpha
), red
, green
, blue
);
172 Colour
Colour::fromRGBAFloat (const uint8 red
,
175 const float alpha
) noexcept
177 return Colour (red
, green
, blue
, alpha
);
180 Colour::Colour (const float hue
,
181 const float saturation
,
182 const float brightness
,
183 const float alpha
) noexcept
186 ColourHelpers::convertHSBtoRGB (hue
, saturation
, brightness
, r
, g
, b
);
188 argb
.setARGB (ColourHelpers::floatAlphaToInt (alpha
), r
, g
, b
);
191 Colour
Colour::fromHSV (const float hue
,
192 const float saturation
,
193 const float brightness
,
194 const float alpha
) noexcept
196 return Colour (hue
, saturation
, brightness
, alpha
);
199 Colour::Colour (const float hue
,
200 const float saturation
,
201 const float brightness
,
202 const uint8 alpha
) noexcept
205 ColourHelpers::convertHSBtoRGB (hue
, saturation
, brightness
, r
, g
, b
);
207 argb
.setARGB (alpha
, r
, g
, b
);
210 Colour::~Colour() noexcept
214 //==============================================================================
215 const PixelARGB
Colour::getPixelARGB() const noexcept
222 uint32
Colour::getARGB() const noexcept
224 return argb
.getARGB();
227 //==============================================================================
228 bool Colour::isTransparent() const noexcept
230 return getAlpha() == 0;
233 bool Colour::isOpaque() const noexcept
235 return getAlpha() == 0xff;
238 Colour
Colour::withAlpha (const uint8 newAlpha
) const noexcept
240 PixelARGB
newCol (argb
);
241 newCol
.setAlpha (newAlpha
);
242 return Colour (newCol
.getARGB());
245 Colour
Colour::withAlpha (const float newAlpha
) const noexcept
247 jassert (newAlpha
>= 0 && newAlpha
<= 1.0f
);
249 PixelARGB
newCol (argb
);
250 newCol
.setAlpha (ColourHelpers::floatAlphaToInt (newAlpha
));
251 return Colour (newCol
.getARGB());
254 Colour
Colour::withMultipliedAlpha (const float alphaMultiplier
) const noexcept
256 jassert (alphaMultiplier
>= 0);
258 PixelARGB
newCol (argb
);
259 newCol
.setAlpha ((uint8
) jmin (0xff, roundToInt (alphaMultiplier
* newCol
.getAlpha())));
260 return Colour (newCol
.getARGB());
263 //==============================================================================
264 Colour
Colour::overlaidWith (const Colour
& src
) const noexcept
266 const int destAlpha
= getAlpha();
270 const int invA
= 0xff - (int) src
.getAlpha();
271 const int resA
= 0xff - (((0xff - destAlpha
) * invA
) >> 8);
275 const int da
= (invA
* destAlpha
) / resA
;
277 return Colour ((uint8
) (src
.getRed() + ((((int) getRed() - src
.getRed()) * da
) >> 8)),
278 (uint8
) (src
.getGreen() + ((((int) getGreen() - src
.getGreen()) * da
) >> 8)),
279 (uint8
) (src
.getBlue() + ((((int) getBlue() - src
.getBlue()) * da
) >> 8)),
291 Colour
Colour::interpolatedWith (const Colour
& other
, float proportionOfOther
) const noexcept
293 if (proportionOfOther
<= 0)
296 if (proportionOfOther
>= 1.0f
)
299 PixelARGB
c1 (getPixelARGB());
300 const PixelARGB
c2 (other
.getPixelARGB());
301 c1
.tween (c2
, roundToInt (proportionOfOther
* 255.0f
));
304 return Colour (c1
.getARGB());
307 //==============================================================================
308 float Colour::getFloatRed() const noexcept
310 return getRed() / 255.0f
;
313 float Colour::getFloatGreen() const noexcept
315 return getGreen() / 255.0f
;
318 float Colour::getFloatBlue() const noexcept
320 return getBlue() / 255.0f
;
323 float Colour::getFloatAlpha() const noexcept
325 return getAlpha() / 255.0f
;
328 //==============================================================================
329 void Colour::getHSB (float& h
, float& s
, float& v
) const noexcept
331 const int r
= getRed();
332 const int g
= getGreen();
333 const int b
= getBlue();
335 const int hi
= jmax (r
, g
, b
);
336 const int lo
= jmin (r
, g
, b
);
340 s
= (hi
- lo
) / (float) hi
;
344 const float invDiff
= 1.0f
/ (hi
- lo
);
346 const float red
= (hi
- r
) * invDiff
;
347 const float green
= (hi
- g
) * invDiff
;
348 const float blue
= (hi
- b
) * invDiff
;
353 h
= 2.0f
+ red
- blue
;
355 h
= 4.0f
+ green
- red
;
376 //==============================================================================
377 float Colour::getHue() const noexcept
384 Colour
Colour::withHue (const float hue
) const noexcept
389 return Colour (hue
, s
, b
, getAlpha());
392 Colour
Colour::withRotatedHue (const float amountToRotate
) const noexcept
397 return Colour (h
+ amountToRotate
, s
, b
, getAlpha());
400 //==============================================================================
401 float Colour::getSaturation() const noexcept
408 Colour
Colour::withSaturation (const float saturation
) const noexcept
413 return Colour (h
, saturation
, b
, getAlpha());
416 Colour
Colour::withMultipliedSaturation (const float amount
) const noexcept
421 return Colour (h
, jmin (1.0f
, s
* amount
), b
, getAlpha());
424 //==============================================================================
425 float Colour::getBrightness() const noexcept
432 Colour
Colour::withBrightness (const float brightness
) const noexcept
437 return Colour (h
, s
, brightness
, getAlpha());
440 Colour
Colour::withMultipliedBrightness (const float amount
) const noexcept
450 return Colour (h
, s
, b
, getAlpha());
453 //==============================================================================
454 Colour
Colour::brighter (float amount
) const noexcept
456 amount
= 1.0f
/ (1.0f
+ amount
);
458 return Colour ((uint8
) (255 - (amount
* (255 - getRed()))),
459 (uint8
) (255 - (amount
* (255 - getGreen()))),
460 (uint8
) (255 - (amount
* (255 - getBlue()))),
464 Colour
Colour::darker (float amount
) const noexcept
466 amount
= 1.0f
/ (1.0f
+ amount
);
468 return Colour ((uint8
) (amount
* getRed()),
469 (uint8
) (amount
* getGreen()),
470 (uint8
) (amount
* getBlue()),
474 //==============================================================================
475 Colour
Colour::greyLevel (const float brightness
) noexcept
478 = (uint8
) jlimit (0x00, 0xff, roundToInt (brightness
* 255.0f
));
480 return Colour (level
, level
, level
);
483 //==============================================================================
484 Colour
Colour::contrasting (const float amount
) const noexcept
486 return overlaidWith ((((int) getRed() + (int) getGreen() + (int) getBlue() >= 3 * 128)
488 : Colours::white
).withAlpha (amount
));
491 Colour
Colour::contrasting (const Colour
& colour1
,
492 const Colour
& colour2
) noexcept
494 const float b1
= colour1
.getBrightness();
495 const float b2
= colour2
.getBrightness();
497 float bestDist
= 0.0f
;
499 for (float i
= 0.0f
; i
< 1.0f
; i
+= 0.02f
)
501 const float d1
= std::abs (i
- b1
);
502 const float d2
= std::abs (i
- b2
);
503 const float dist
= jmin (d1
, d2
, 1.0f
- d1
, 1.0f
- d2
);
512 return colour1
.overlaidWith (colour2
.withMultipliedAlpha (0.5f
))
513 .withBrightness (best
);
516 //==============================================================================
517 String
Colour::toString() const
519 return String::toHexString ((int) argb
.getARGB());
522 Colour
Colour::fromString (const String
& encodedColourString
)
524 return Colour ((uint32
) encodedColourString
.getHexValue32());
527 String
Colour::toDisplayString (const bool includeAlphaValue
) const
529 return String::toHexString ((int) (argb
.getARGB() & (includeAlphaValue
? 0xffffffff : 0xffffff)))
530 .paddedLeft ('0', includeAlphaValue
? 8 : 6)