1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00
JUCE/modules/juce_graphics/colour/juce_Colour.cpp

771 lines
29 KiB
C++

/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
namespace juce
{
namespace ColourHelpers
{
static uint8 floatToUInt8 (float n) noexcept
{
return n <= 0.0f ? 0 : (n >= 1.0f ? 255 : (uint8) roundToInt (n * 255.0f));
}
static float getHue (Colour col)
{
auto r = (int) col.getRed();
auto g = (int) col.getGreen();
auto b = (int) col.getBlue();
auto hi = jmax (r, g, b);
auto lo = jmin (r, g, b);
float hue = 0.0f;
if (hi > 0 && ! exactlyEqual (hi, lo))
{
auto invDiff = 1.0f / (float) (hi - lo);
auto red = (float) (hi - r) * invDiff;
auto green = (float) (hi - g) * invDiff;
auto blue = (float) (hi - b) * invDiff;
if (r == hi) hue = blue - green;
else if (g == hi) hue = 2.0f + red - blue;
else hue = 4.0f + green - red;
hue *= 1.0f / 6.0f;
if (hue < 0.0f)
hue += 1.0f;
}
return hue;
}
//==============================================================================
struct HSL
{
HSL (Colour col) noexcept
{
auto r = (int) col.getRed();
auto g = (int) col.getGreen();
auto b = (int) col.getBlue();
auto hi = jmax (r, g, b);
auto lo = jmin (r, g, b);
if (hi < 0)
return;
lightness = ((float) (hi + lo) / 2.0f) / 255.0f;
if (lightness <= 0.0f)
return;
hue = getHue (col);
if (1.0f <= lightness)
return;
auto denominator = 1.0f - std::abs ((2.0f * lightness) - 1.0f);
saturation = ((float) (hi - lo) / 255.0f) / denominator;
}
Colour toColour (Colour original) const noexcept
{
return Colour::fromHSL (hue, saturation, lightness, original.getAlpha());
}
static PixelARGB toRGB (float h, float s, float l, uint8 alpha) noexcept
{
auto v = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
if (approximatelyEqual (v, 0.0f))
return PixelARGB (alpha, 0, 0, 0);
auto min = (2.0f * l) - v;
auto sv = (v - min) / v;
h = ((h - std::floor (h)) * 360.0f) / 60.0f;
auto f = h - std::floor (h);
auto vsf = v * sv * f;
auto mid1 = min + vsf;
auto mid2 = v - vsf;
if (h < 1.0f) return PixelARGB (alpha, floatToUInt8 (v), floatToUInt8 (mid1), floatToUInt8 (min));
else if (h < 2.0f) return PixelARGB (alpha, floatToUInt8 (mid2), floatToUInt8 (v), floatToUInt8 (min));
else if (h < 3.0f) return PixelARGB (alpha, floatToUInt8 (min), floatToUInt8 (v), floatToUInt8 (mid1));
else if (h < 4.0f) return PixelARGB (alpha, floatToUInt8 (min), floatToUInt8 (mid2), floatToUInt8 (v));
else if (h < 5.0f) return PixelARGB (alpha, floatToUInt8 (mid1), floatToUInt8 (min), floatToUInt8 (v));
else if (h < 6.0f) return PixelARGB (alpha, floatToUInt8 (v), floatToUInt8 (min), floatToUInt8 (mid2));
return PixelARGB (alpha, 0, 0, 0);
}
float hue = 0.0f, saturation = 0.0f, lightness = 0.0f;
};
//==============================================================================
struct HSB
{
HSB (Colour col) noexcept
{
auto r = (int) col.getRed();
auto g = (int) col.getGreen();
auto b = (int) col.getBlue();
auto hi = jmax (r, g, b);
auto lo = jmin (r, g, b);
if (hi > 0)
{
saturation = (float) (hi - lo) / (float) hi;
if (saturation > 0.0f)
hue = getHue (col);
brightness = (float) hi / 255.0f;
}
}
Colour toColour (Colour original) const noexcept
{
return Colour (hue, saturation, brightness, original.getAlpha());
}
static PixelARGB toRGB (float h, float s, float v, uint8 alpha) noexcept
{
v = jlimit (0.0f, 255.0f, v * 255.0f);
auto intV = (uint8) roundToInt (v);
if (s <= 0)
return PixelARGB (alpha, intV, intV, intV);
s = jmin (1.0f, s);
h = ((h - std::floor (h)) * 360.0f) / 60.0f;
auto f = h - std::floor (h);
auto x = (uint8) roundToInt (v * (1.0f - s));
if (h < 1.0f) return PixelARGB (alpha, intV, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))), x);
if (h < 2.0f) return PixelARGB (alpha, (uint8) roundToInt (v * (1.0f - s * f)), intV, x);
if (h < 3.0f) return PixelARGB (alpha, x, intV, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))));
if (h < 4.0f) return PixelARGB (alpha, x, (uint8) roundToInt (v * (1.0f - s * f)), intV);
if (h < 5.0f) return PixelARGB (alpha, (uint8) roundToInt (v * (1.0f - (s * (1.0f - f)))), x, intV);
return PixelARGB (alpha, intV, x, (uint8) roundToInt (v * (1.0f - s * f)));
}
float hue = 0.0f, saturation = 0.0f, brightness = 0.0f;
};
//==============================================================================
struct YIQ
{
YIQ (Colour c) noexcept
{
auto r = c.getFloatRed();
auto g = c.getFloatGreen();
auto b = c.getFloatBlue();
y = 0.2999f * r + 0.5870f * g + 0.1140f * b;
i = 0.5957f * r - 0.2744f * g - 0.3212f * b;
q = 0.2114f * r - 0.5225f * g - 0.3113f * b;
alpha = c.getFloatAlpha();
}
Colour toColour() const noexcept
{
return Colour::fromFloatRGBA (y + 0.9563f * i + 0.6210f * q,
y - 0.2721f * i - 0.6474f * q,
y - 1.1070f * i + 1.7046f * q,
alpha);
}
float y = 0.0f, i = 0.0f, q = 0.0f, alpha = 0.0f;
};
}
//==============================================================================
bool Colour::operator== (const Colour& other) const noexcept { return argb.getNativeARGB() == other.argb.getNativeARGB(); }
bool Colour::operator!= (const Colour& other) const noexcept { return argb.getNativeARGB() != other.argb.getNativeARGB(); }
//==============================================================================
Colour::Colour (uint32 col) noexcept
: argb (static_cast<uint8> ((col >> 24) & 0xff),
static_cast<uint8> ((col >> 16) & 0xff),
static_cast<uint8> ((col >> 8) & 0xff),
static_cast<uint8> (col & 0xff))
{
}
Colour::Colour (uint8 red, uint8 green, uint8 blue) noexcept
{
argb.setARGB (0xff, red, green, blue);
}
Colour Colour::fromRGB (uint8 red, uint8 green, uint8 blue) noexcept
{
return Colour (red, green, blue);
}
Colour::Colour (uint8 red, uint8 green, uint8 blue, uint8 alpha) noexcept
{
argb.setARGB (alpha, red, green, blue);
}
Colour Colour::fromRGBA (uint8 red, uint8 green, uint8 blue, uint8 alpha) noexcept
{
return Colour (red, green, blue, alpha);
}
Colour::Colour (uint8 red, uint8 green, uint8 blue, float alpha) noexcept
{
argb.setARGB (ColourHelpers::floatToUInt8 (alpha), red, green, blue);
}
Colour Colour::fromFloatRGBA (float red, float green, float blue, float alpha) noexcept
{
return Colour (ColourHelpers::floatToUInt8 (red),
ColourHelpers::floatToUInt8 (green),
ColourHelpers::floatToUInt8 (blue), alpha);
}
Colour::Colour (float hue, float saturation, float brightness, float alpha) noexcept
: argb (ColourHelpers::HSB::toRGB (hue, saturation, brightness, ColourHelpers::floatToUInt8 (alpha)))
{
}
Colour Colour::fromHSV (float hue, float saturation, float brightness, float alpha) noexcept
{
return Colour (hue, saturation, brightness, alpha);
}
Colour Colour::fromHSV (float hue, float saturation, float brightness, uint8 alpha) noexcept
{
return Colour (hue, saturation, brightness, alpha);
}
Colour Colour::fromHSL (float hue, float saturation, float lightness, float alpha) noexcept
{
return fromHSL (hue, saturation, lightness, ColourHelpers::floatToUInt8 (alpha));
}
Colour Colour::fromHSL (float hue, float saturation, float lightness, uint8 alpha) noexcept
{
Colour hslColour;
hslColour.argb = ColourHelpers::HSL::toRGB (hue, saturation, lightness, alpha);
return hslColour;
}
Colour::Colour (float hue, float saturation, float brightness, uint8 alpha) noexcept
: argb (ColourHelpers::HSB::toRGB (hue, saturation, brightness, alpha))
{
}
Colour::Colour (PixelARGB argb_) noexcept
: argb (argb_)
{
}
Colour::Colour (PixelRGB rgb) noexcept
: argb (Colour (rgb.getInARGBMaskOrder()).argb)
{
}
Colour::Colour (PixelAlpha alpha) noexcept
: argb (Colour (alpha.getInARGBMaskOrder()).argb)
{
}
//==============================================================================
PixelARGB Colour::getPixelARGB() const noexcept
{
PixelARGB p (argb);
p.premultiply();
return p;
}
PixelARGB Colour::getNonPremultipliedPixelARGB() const noexcept
{
return argb;
}
uint32 Colour::getARGB() const noexcept
{
return argb.getInARGBMaskOrder();
}
//==============================================================================
bool Colour::isTransparent() const noexcept
{
return getAlpha() == 0;
}
bool Colour::isOpaque() const noexcept
{
return getAlpha() == 0xff;
}
Colour Colour::withAlpha (uint8 newAlpha) const noexcept
{
PixelARGB newCol (argb);
newCol.setAlpha (newAlpha);
return Colour (newCol);
}
Colour Colour::withAlpha (float newAlpha) const noexcept
{
jassert (newAlpha >= 0 && newAlpha <= 1.0f);
PixelARGB newCol (argb);
newCol.setAlpha (ColourHelpers::floatToUInt8 (newAlpha));
return Colour (newCol);
}
Colour Colour::withMultipliedAlpha (float alphaMultiplier) const noexcept
{
jassert (alphaMultiplier >= 0);
PixelARGB newCol (argb);
newCol.setAlpha ((uint8) jmin (0xff, roundToInt (alphaMultiplier * newCol.getAlpha())));
return Colour (newCol);
}
//==============================================================================
Colour Colour::overlaidWith (Colour src) const noexcept
{
auto destAlpha = getAlpha();
if (destAlpha <= 0)
return src;
auto invA = 0xff - (int) src.getAlpha();
auto resA = 0xff - (((0xff - destAlpha) * invA) >> 8);
if (resA <= 0)
return *this;
auto da = (invA * destAlpha) / resA;
return Colour ((uint8) (src.getRed() + ((((int) getRed() - src.getRed()) * da) >> 8)),
(uint8) (src.getGreen() + ((((int) getGreen() - src.getGreen()) * da) >> 8)),
(uint8) (src.getBlue() + ((((int) getBlue() - src.getBlue()) * da) >> 8)),
(uint8) resA);
}
Colour Colour::interpolatedWith (Colour other, float proportionOfOther) const noexcept
{
if (proportionOfOther <= 0)
return *this;
if (proportionOfOther >= 1.0f)
return other;
PixelARGB c1 (getPixelARGB());
PixelARGB c2 (other.getPixelARGB());
c1.tween (c2, (uint32) roundToInt (proportionOfOther * 255.0f));
c1.unpremultiply();
return Colour (c1);
}
//==============================================================================
float Colour::getFloatRed() const noexcept { return getRed() / 255.0f; }
float Colour::getFloatGreen() const noexcept { return getGreen() / 255.0f; }
float Colour::getFloatBlue() const noexcept { return getBlue() / 255.0f; }
float Colour::getFloatAlpha() const noexcept { return getAlpha() / 255.0f; }
//==============================================================================
void Colour::getHSB (float& h, float& s, float& v) const noexcept
{
ColourHelpers::HSB hsb (*this);
h = hsb.hue;
s = hsb.saturation;
v = hsb.brightness;
}
void Colour::getHSL (float& h, float& s, float& l) const noexcept
{
ColourHelpers::HSL hsl (*this);
h = hsl.hue;
s = hsl.saturation;
l = hsl.lightness;
}
float Colour::getHue() const noexcept { return ColourHelpers::HSB (*this).hue; }
float Colour::getSaturation() const noexcept { return ColourHelpers::HSB (*this).saturation; }
float Colour::getBrightness() const noexcept { return ColourHelpers::HSB (*this).brightness; }
float Colour::getSaturationHSL() const noexcept { return ColourHelpers::HSL (*this).saturation; }
float Colour::getLightness() const noexcept { return ColourHelpers::HSL (*this).lightness; }
Colour Colour::withHue (float h) const noexcept { ColourHelpers::HSB hsb (*this); hsb.hue = h; return hsb.toColour (*this); }
Colour Colour::withSaturation (float s) const noexcept { ColourHelpers::HSB hsb (*this); hsb.saturation = s; return hsb.toColour (*this); }
Colour Colour::withBrightness (float v) const noexcept { ColourHelpers::HSB hsb (*this); hsb.brightness = v; return hsb.toColour (*this); }
Colour Colour::withSaturationHSL (float s) const noexcept { ColourHelpers::HSL hsl (*this); hsl.saturation = s; return hsl.toColour (*this); }
Colour Colour::withLightness (float l) const noexcept { ColourHelpers::HSL hsl (*this); hsl.lightness = l; return hsl.toColour (*this); }
float Colour::getPerceivedBrightness() const noexcept
{
return std::sqrt (0.241f * square (getFloatRed())
+ 0.691f * square (getFloatGreen())
+ 0.068f * square (getFloatBlue()));
}
//==============================================================================
Colour Colour::withRotatedHue (float amountToRotate) const noexcept
{
ColourHelpers::HSB hsb (*this);
hsb.hue += amountToRotate;
return hsb.toColour (*this);
}
Colour Colour::withMultipliedSaturation (float amount) const noexcept
{
ColourHelpers::HSB hsb (*this);
hsb.saturation = jmin (1.0f, hsb.saturation * amount);
return hsb.toColour (*this);
}
Colour Colour::withMultipliedSaturationHSL (float amount) const noexcept
{
ColourHelpers::HSL hsl (*this);
hsl.saturation = jmin (1.0f, hsl.saturation * amount);
return hsl.toColour (*this);
}
Colour Colour::withMultipliedBrightness (float amount) const noexcept
{
ColourHelpers::HSB hsb (*this);
hsb.brightness = jmin (1.0f, hsb.brightness * amount);
return hsb.toColour (*this);
}
Colour Colour::withMultipliedLightness (float amount) const noexcept
{
ColourHelpers::HSL hsl (*this);
hsl.lightness = jmin (1.0f, hsl.lightness * amount);
return hsl.toColour (*this);
}
//==============================================================================
Colour Colour::brighter (float amount) const noexcept
{
jassert (amount >= 0.0f);
amount = 1.0f / (1.0f + amount);
return Colour ((uint8) (255 - (amount * (255 - getRed()))),
(uint8) (255 - (amount * (255 - getGreen()))),
(uint8) (255 - (amount * (255 - getBlue()))),
getAlpha());
}
Colour Colour::darker (float amount) const noexcept
{
jassert (amount >= 0.0f);
amount = 1.0f / (1.0f + amount);
return Colour ((uint8) (amount * getRed()),
(uint8) (amount * getGreen()),
(uint8) (amount * getBlue()),
getAlpha());
}
//==============================================================================
Colour Colour::greyLevel (float brightness) noexcept
{
auto level = ColourHelpers::floatToUInt8 (brightness);
return Colour (level, level, level);
}
//==============================================================================
Colour Colour::contrasting (float amount) const noexcept
{
return overlaidWith ((getPerceivedBrightness() >= 0.5f
? Colours::black
: Colours::white).withAlpha (amount));
}
Colour Colour::contrasting (Colour target, float minContrast) const noexcept
{
ColourHelpers::YIQ bg (*this);
ColourHelpers::YIQ fg (target);
if (std::abs (bg.y - fg.y) >= minContrast)
return target;
auto y1 = jmax (0.0f, bg.y - minContrast);
auto y2 = jmin (1.0f, bg.y + minContrast);
fg.y = (std::abs (y1 - bg.y) > std::abs (y2 - bg.y)) ? y1 : y2;
return fg.toColour();
}
Colour Colour::contrasting (Colour colour1,
Colour colour2) noexcept
{
auto b1 = colour1.getPerceivedBrightness();
auto b2 = colour2.getPerceivedBrightness();
float best = 0.0f, bestDist = 0.0f;
for (float i = 0.0f; i < 1.0f; i += 0.02f)
{
auto d1 = std::abs (i - b1);
auto d2 = std::abs (i - b2);
auto dist = jmin (d1, d2, 1.0f - d1, 1.0f - d2);
if (dist > bestDist)
{
best = i;
bestDist = dist;
}
}
return colour1.overlaidWith (colour2.withMultipliedAlpha (0.5f))
.withBrightness (best);
}
//==============================================================================
String Colour::toString() const
{
return String::toHexString ((int) argb.getInARGBMaskOrder());
}
Colour Colour::fromString (StringRef encodedColourString)
{
return Colour (CharacterFunctions::HexParser<uint32>::parse (encodedColourString.text));
}
String Colour::toDisplayString (const bool includeAlphaValue) const
{
return String::toHexString ((int) (argb.getInARGBMaskOrder() & (includeAlphaValue ? 0xffffffff : 0xffffff)))
.paddedLeft ('0', includeAlphaValue ? 8 : 6)
.toUpperCase();
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class ColourTests final : public UnitTest
{
public:
ColourTests()
: UnitTest ("Colour", UnitTestCategories::graphics)
{}
void runTest() override
{
auto testColour = [this] (Colour colour,
uint8 expectedRed, uint8 expectedGreen, uint8 expectedBlue,
uint8 expectedAlpha = 255)
{
expectEquals (colour.getRed(), expectedRed);
expectEquals (colour.getGreen(), expectedGreen);
expectEquals (colour.getBlue(), expectedBlue);
expectEquals (colour.getAlpha(), expectedAlpha);
};
beginTest ("Constructors");
{
Colour c1;
testColour (c1, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0);
Colour c2 ((uint32) 0);
testColour (c2, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0);
Colour c3 ((uint32) 0xffffffff);
testColour (c3, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255);
Colour c4 (0, 0, 0);
testColour (c4, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 255);
Colour c5 (255, 255, 255);
testColour (c5, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255);
Colour c6 ((uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0);
testColour (c6, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0);
Colour c7 ((uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255);
testColour (c7, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255);
Colour c8 ((uint8) 0, (uint8) 0, (uint8) 0, 0.0f);
testColour (c8, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0);
Colour c9 ((uint8) 255, (uint8) 255, (uint8) 255, 1.0f);
testColour (c9, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255);
}
beginTest ("HSV");
{
// black
testColour (Colour::fromHSV (0.0f, 0.0f, 0.0f, 1.0f), 0, 0, 0);
testColour (Colour::fromHSV (0.0f, 0.0f, 0.0f, 0.5f), 0, 0, 0, 128);
// white
testColour (Colour::fromHSV (0.0f, 0.0f, 1.0f, 1.0f), 255, 255, 255);
testColour (Colour::fromHSV (0.0f, 0.0f, 1.0f, 0.5f), 255, 255, 255, 128);
// red
testColour (Colour::fromHSV (0.0f, 1.0f, 1.0f, 1.0f), 255, 0, 0);
testColour (Colour::fromHSV (0.0f, 1.0f, 1.0f, 0.5f), 255, 0, 0, 128);
testColour (Colour::fromHSV (1.0f, 1.0f, 1.0f, 1.0f), 255, 0, 0);
testColour (Colour::fromHSV (1.0f, 1.0f, 1.0f, 0.5f), 255, 0, 0, 128);
// lime
testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 255, 0);
testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 1.0f, 0.5f), 0, 255, 0, 128);
// blue
testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 0, 255);
testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 1.0f, 0.5f), 0, 0, 255, 128);
// yellow
testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 1.0f, 1.0f), 255, 255, 0);
testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 1.0f, 0.5f), 255, 255, 0, 128);
// cyan
testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 255, 255);
testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 1.0f, 0.5f), 0, 255, 255, 128);
// magenta
testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 1.0f, 1.0f), 255, 0, 255);
testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 1.0f, 0.5f), 255, 0, 255, 128);
// silver
testColour (Colour::fromHSV (0.0f, 0.0f, 0.75f, 1.0f), 191, 191, 191);
testColour (Colour::fromHSV (0.0f, 0.0f, 0.75f, 0.5f), 191, 191, 191, 128);
// grey
testColour (Colour::fromHSV (0.0f, 0.0f, 0.5f, 1.0f), 128, 128, 128);
testColour (Colour::fromHSV (0.0f, 0.0f, 0.5f, 0.5f), 128, 128, 128, 128);
// maroon
testColour (Colour::fromHSV (0.0f, 1.0f, 0.5f, 1.0f), 128, 0, 0);
testColour (Colour::fromHSV (0.0f, 1.0f, 0.5f, 0.5f), 128, 0, 0, 128);
// olive
testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 0.5f, 1.0f), 128, 128, 0);
testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 0.5f, 0.5f), 128, 128, 0, 128);
// green
testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 128, 0);
testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 0.5f, 0.5f), 0, 128, 0, 128);
// purple
testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 0.5f, 1.0f), 128, 0, 128);
testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 0.5f, 0.5f), 128, 0, 128, 128);
// teal
testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 128, 128);
testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 0.5f, 0.5f), 0, 128, 128, 128);
// navy
testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 0, 128);
testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 0.5f, 0.5f), 0, 0, 128, 128);
}
beginTest ("HSL");
{
// black
testColour (Colour::fromHSL (0.0f, 0.0f, 0.0f, 1.0f), 0, 0, 0);
testColour (Colour::fromHSL (0.0f, 0.0f, 0.0f, 0.5f), 0, 0, 0, 128);
// white
testColour (Colour::fromHSL (0.0f, 0.0f, 1.0f, 1.0f), 255, 255, 255);
testColour (Colour::fromHSL (0.0f, 0.0f, 1.0f, 0.5f), 255, 255, 255, 128);
// red
testColour (Colour::fromHSL (0.0f, 1.0f, 0.5f, 1.0f), 255, 0, 0);
testColour (Colour::fromHSL (0.0f, 1.0f, 0.5f, 0.5f), 255, 0, 0, 128);
testColour (Colour::fromHSL (1.0f, 1.0f, 0.5f, 1.0f), 255, 0, 0);
testColour (Colour::fromHSL (1.0f, 1.0f, 0.5f, 0.5f), 255, 0, 0, 128);
// lime
testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 255, 0);
testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.5f, 0.5f), 0, 255, 0, 128);
// blue
testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 0, 255);
testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.5f, 0.5f), 0, 0, 255, 128);
// yellow
testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.5f, 1.0f), 255, 255, 0);
testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.5f, 0.5f), 255, 255, 0, 128);
// cyan
testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 255, 255);
testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.5f, 0.5f), 0, 255, 255, 128);
// magenta
testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.5f, 1.0f), 255, 0, 255);
testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.5f, 0.5f), 255, 0, 255, 128);
// silver
testColour (Colour::fromHSL (0.0f, 0.0f, 0.75f, 1.0f), 191, 191, 191);
testColour (Colour::fromHSL (0.0f, 0.0f, 0.75f, 0.5f), 191, 191, 191, 128);
// grey
testColour (Colour::fromHSL (0.0f, 0.0f, 0.5f, 1.0f), 128, 128, 128);
testColour (Colour::fromHSL (0.0f, 0.0f, 0.5f, 0.5f), 128, 128, 128, 128);
// maroon
testColour (Colour::fromHSL (0.0f, 1.0f, 0.25f, 1.0f), 128, 0, 0);
testColour (Colour::fromHSL (0.0f, 1.0f, 0.25f, 0.5f), 128, 0, 0, 128);
// olive
testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.25f, 1.0f), 128, 128, 0);
testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.25f, 0.5f), 128, 128, 0, 128);
// green
testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 128, 0);
testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.25f, 0.5f), 0, 128, 0, 128);
// purple
testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.25f, 1.0f), 128, 0, 128);
testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.25f, 0.5f), 128, 0, 128, 128);
// teal
testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 128, 128);
testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.25f, 0.5f), 0, 128, 128, 128);
// navy
testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 0, 128);
testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.25f, 0.5f), 0, 0, 128, 128);
}
beginTest ("Modifiers");
{
Colour red (255, 0, 0);
testColour (red, 255, 0, 0);
testColour (red.withHue (120.0f / 360.0f), 0, 255, 0);
testColour (red.withSaturation (0.5f), 255, 128, 128);
testColour (red.withSaturationHSL (0.5f), 191, 64, 64);
testColour (red.withBrightness (0.5f), 128, 0, 0);
testColour (red.withLightness (1.0f), 255, 255, 255);
testColour (red.withRotatedHue (120.0f / 360.0f), 0, 255, 0);
testColour (red.withRotatedHue (480.0f / 360.0f), 0, 255, 0);
testColour (red.withRotatedHue (-240.0f / 360.0f), 0, 255, 0);
testColour (red.withRotatedHue (-600.0f / 360.0f), 0, 255, 0);
testColour (red.withMultipliedSaturation (0.0f), 255, 255, 255);
testColour (red.withMultipliedSaturationHSL (0.0f), 128, 128, 128);
testColour (red.withMultipliedBrightness (0.5f), 128, 0, 0);
testColour (red.withMultipliedLightness (2.0f), 255, 255, 255);
testColour (red.withMultipliedLightness (1.0f), 255, 0, 0);
testColour (red.withLightness (red.getLightness()), 255, 0, 0);
testColour (red.withAlpha ((uint8) 128), 255, 0, 0, 128);
testColour (red.withAlpha (0.5f), 255, 0, 0, 128);
}
}
};
static ColourTests colourTests;
#endif
} // namespace juce