git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
712
deps/juce/modules/juce_graphics/colour/juce_Colour.cpp
vendored
Normal file
712
deps/juce/modules/juce_graphics/colour/juce_Colour.cpp
vendored
Normal file
@ -0,0 +1,712 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR 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 && ! approximatelyEqual (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::fromHSL (float hue, float saturation, float lightness, float alpha) noexcept
|
||||
{
|
||||
Colour hslColour;
|
||||
hslColour.argb = ColourHelpers::HSL::toRGB (hue, saturation, lightness, ColourHelpers::floatToUInt8 (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)
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
const PixelARGB Colour::getPixelARGB() const noexcept
|
||||
{
|
||||
PixelARGB p (argb);
|
||||
p.premultiply();
|
||||
return p;
|
||||
}
|
||||
|
||||
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 ((uint32) CharacterFunctions::HexParser<int>::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 : 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, float expectedFloatAlpha = 1.0f)
|
||||
{
|
||||
expectEquals (colour.getRed(), expectedRed);
|
||||
expectEquals (colour.getGreen(), expectedGreen);
|
||||
expectEquals (colour.getBlue(), expectedBlue);
|
||||
expectEquals (colour.getAlpha(), expectedAlpha);
|
||||
expectEquals (colour.getFloatAlpha(), expectedFloatAlpha);
|
||||
};
|
||||
|
||||
beginTest ("Constructors");
|
||||
{
|
||||
Colour c1;
|
||||
testColour (c1, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f);
|
||||
|
||||
Colour c2 ((uint32) 0);
|
||||
testColour (c2, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f);
|
||||
|
||||
Colour c3 ((uint32) 0xffffffff);
|
||||
testColour (c3, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f);
|
||||
|
||||
Colour c4 (0, 0, 0);
|
||||
testColour (c4, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 255, 1.0f);
|
||||
|
||||
Colour c5 (255, 255, 255);
|
||||
testColour (c5, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f);
|
||||
|
||||
Colour c6 ((uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0);
|
||||
testColour (c6, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f);
|
||||
|
||||
Colour c7 ((uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255);
|
||||
testColour (c7, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f);
|
||||
|
||||
Colour c8 ((uint8) 0, (uint8) 0, (uint8) 0, 0.0f);
|
||||
testColour (c8, (uint8) 0, (uint8) 0, (uint8) 0, (uint8) 0, 0.0f);
|
||||
|
||||
Colour c9 ((uint8) 255, (uint8) 255, (uint8) 255, 1.0f);
|
||||
testColour (c9, (uint8) 255, (uint8) 255, (uint8) 255, (uint8) 255, 1.0f);
|
||||
}
|
||||
|
||||
beginTest ("HSV");
|
||||
{
|
||||
// black
|
||||
testColour (Colour::fromHSV (0.0f, 0.0f, 0.0f, 1.0f), 0, 0, 0);
|
||||
// white
|
||||
testColour (Colour::fromHSV (0.0f, 0.0f, 1.0f, 1.0f), 255, 255, 255);
|
||||
// red
|
||||
testColour (Colour::fromHSV (0.0f, 1.0f, 1.0f, 1.0f), 255, 0, 0);
|
||||
testColour (Colour::fromHSV (1.0f, 1.0f, 1.0f, 1.0f), 255, 0, 0);
|
||||
// lime
|
||||
testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 255, 0);
|
||||
// blue
|
||||
testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 0, 255);
|
||||
// yellow
|
||||
testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 1.0f, 1.0f), 255, 255, 0);
|
||||
// cyan
|
||||
testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 1.0f, 1.0f), 0, 255, 255);
|
||||
// magenta
|
||||
testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 1.0f, 1.0f), 255, 0, 255);
|
||||
// silver
|
||||
testColour (Colour::fromHSV (0.0f, 0.0f, 0.75f, 1.0f), 191, 191, 191);
|
||||
// grey
|
||||
testColour (Colour::fromHSV (0.0f, 0.0f, 0.5f, 1.0f), 128, 128, 128);
|
||||
// maroon
|
||||
testColour (Colour::fromHSV (0.0f, 1.0f, 0.5f, 1.0f), 128, 0, 0);
|
||||
// olive
|
||||
testColour (Colour::fromHSV (60 / 360.0f, 1.0f, 0.5f, 1.0f), 128, 128, 0);
|
||||
// green
|
||||
testColour (Colour::fromHSV (120 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 128, 0);
|
||||
// purple
|
||||
testColour (Colour::fromHSV (300 / 360.0f, 1.0f, 0.5f, 1.0f), 128, 0, 128);
|
||||
// teal
|
||||
testColour (Colour::fromHSV (180 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 128, 128);
|
||||
// navy
|
||||
testColour (Colour::fromHSV (240 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 0, 128);
|
||||
}
|
||||
|
||||
beginTest ("HSL");
|
||||
{
|
||||
// black
|
||||
testColour (Colour::fromHSL (0.0f, 0.0f, 0.0f, 1.0f), 0, 0, 0);
|
||||
// white
|
||||
testColour (Colour::fromHSL (0.0f, 0.0f, 1.0f, 1.0f), 255, 255, 255);
|
||||
// red
|
||||
testColour (Colour::fromHSL (0.0f, 1.0f, 0.5f, 1.0f), 255, 0, 0);
|
||||
testColour (Colour::fromHSL (1.0f, 1.0f, 0.5f, 1.0f), 255, 0, 0);
|
||||
// lime
|
||||
testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 255, 0);
|
||||
// blue
|
||||
testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 0, 255);
|
||||
// yellow
|
||||
testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.5f, 1.0f), 255, 255, 0);
|
||||
// cyan
|
||||
testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.5f, 1.0f), 0, 255, 255);
|
||||
// magenta
|
||||
testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.5f, 1.0f), 255, 0, 255);
|
||||
// silver
|
||||
testColour (Colour::fromHSL (0.0f, 0.0f, 0.75f, 1.0f), 191, 191, 191);
|
||||
// grey
|
||||
testColour (Colour::fromHSL (0.0f, 0.0f, 0.5f, 1.0f), 128, 128, 128);
|
||||
// maroon
|
||||
testColour (Colour::fromHSL (0.0f, 1.0f, 0.25f, 1.0f), 128, 0, 0);
|
||||
// olive
|
||||
testColour (Colour::fromHSL (60 / 360.0f, 1.0f, 0.25f, 1.0f), 128, 128, 0);
|
||||
// green
|
||||
testColour (Colour::fromHSL (120 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 128, 0);
|
||||
// purple
|
||||
testColour (Colour::fromHSL (300 / 360.0f, 1.0f, 0.25f, 1.0f), 128, 0, 128);
|
||||
// teal
|
||||
testColour (Colour::fromHSL (180 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 128, 128);
|
||||
// navy
|
||||
testColour (Colour::fromHSL (240 / 360.0f, 1.0f, 0.25f, 1.0f), 0, 0, 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ColourTests colourTests;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
416
deps/juce/modules/juce_graphics/colour/juce_Colour.h
vendored
Normal file
416
deps/juce/modules/juce_graphics/colour/juce_Colour.h
vendored
Normal file
@ -0,0 +1,416 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a colour, also including a transparency value.
|
||||
|
||||
The colour is stored internally as unsigned 8-bit red, green, blue and alpha values.
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API Colour final
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a transparent black colour. */
|
||||
Colour() = default;
|
||||
|
||||
/** Creates a copy of another Colour object. */
|
||||
Colour (const Colour&) = default;
|
||||
|
||||
/** Creates a colour from a 32-bit ARGB value.
|
||||
|
||||
The format of this number is:
|
||||
((alpha << 24) | (red << 16) | (green << 8) | blue).
|
||||
|
||||
All components in the range 0x00 to 0xff.
|
||||
An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
|
||||
|
||||
@see getPixelARGB
|
||||
*/
|
||||
explicit Colour (uint32 argb) noexcept;
|
||||
|
||||
/** Creates an opaque colour using 8-bit red, green and blue values */
|
||||
Colour (uint8 red,
|
||||
uint8 green,
|
||||
uint8 blue) noexcept;
|
||||
|
||||
/** Creates an opaque colour using 8-bit red, green and blue values */
|
||||
static Colour fromRGB (uint8 red,
|
||||
uint8 green,
|
||||
uint8 blue) noexcept;
|
||||
|
||||
/** Creates a colour using 8-bit red, green, blue and alpha values. */
|
||||
Colour (uint8 red,
|
||||
uint8 green,
|
||||
uint8 blue,
|
||||
uint8 alpha) noexcept;
|
||||
|
||||
/** Creates a colour using 8-bit red, green, blue and alpha values. */
|
||||
static Colour fromRGBA (uint8 red,
|
||||
uint8 green,
|
||||
uint8 blue,
|
||||
uint8 alpha) noexcept;
|
||||
|
||||
/** Creates a colour from 8-bit red, green, and blue values, and a floating-point alpha.
|
||||
|
||||
Alpha of 0.0 is transparent, alpha of 1.0f is opaque.
|
||||
Values outside the valid range will be clipped.
|
||||
*/
|
||||
Colour (uint8 red,
|
||||
uint8 green,
|
||||
uint8 blue,
|
||||
float alpha) noexcept;
|
||||
|
||||
/** Creates a colour using floating point red, green, blue and alpha values.
|
||||
Numbers outside the range 0..1 will be clipped.
|
||||
*/
|
||||
static Colour fromFloatRGBA (float red,
|
||||
float green,
|
||||
float blue,
|
||||
float alpha) noexcept;
|
||||
|
||||
/** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha.
|
||||
|
||||
The floating point values must be between 0.0 and 1.0.
|
||||
An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
|
||||
Values outside the valid range will be clipped.
|
||||
*/
|
||||
Colour (float hue,
|
||||
float saturation,
|
||||
float brightness,
|
||||
uint8 alpha) noexcept;
|
||||
|
||||
/** Creates a colour using floating point hue, saturation, brightness and alpha values.
|
||||
|
||||
All values must be between 0.0 and 1.0.
|
||||
Numbers outside the valid range will be clipped.
|
||||
*/
|
||||
Colour (float hue,
|
||||
float saturation,
|
||||
float brightness,
|
||||
float alpha) noexcept;
|
||||
|
||||
/** Creates a colour using floating point hue, saturation, brightness and alpha values.
|
||||
|
||||
All values must be between 0.0 and 1.0.
|
||||
Numbers outside the valid range will be clipped.
|
||||
*/
|
||||
static Colour fromHSV (float hue,
|
||||
float saturation,
|
||||
float brightness,
|
||||
float alpha) noexcept;
|
||||
|
||||
/** Creates a colour using floating point hue, saturation, lightness and alpha values.
|
||||
|
||||
All values must be between 0.0 and 1.0.
|
||||
Numbers outside the valid range will be clipped.
|
||||
*/
|
||||
static Colour fromHSL (float hue,
|
||||
float saturation,
|
||||
float lightness,
|
||||
float alpha) noexcept;
|
||||
|
||||
/** Creates a colour using a PixelARGB object. This function assumes that the argb pixel is
|
||||
not premultiplied.
|
||||
*/
|
||||
Colour (PixelARGB argb) noexcept;
|
||||
|
||||
/** Creates a colour using a PixelRGB object.
|
||||
*/
|
||||
Colour (PixelRGB rgb) noexcept;
|
||||
|
||||
/** Creates a colour using a PixelAlpha object.
|
||||
*/
|
||||
Colour (PixelAlpha alpha) noexcept;
|
||||
|
||||
/** Destructor. */
|
||||
~Colour() = default;
|
||||
|
||||
/** Copies another Colour object. */
|
||||
Colour& operator= (const Colour&) = default;
|
||||
|
||||
/** Compares two colours. */
|
||||
bool operator== (const Colour& other) const noexcept;
|
||||
/** Compares two colours. */
|
||||
bool operator!= (const Colour& other) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the red component of this colour.
|
||||
@returns a value between 0x00 and 0xff.
|
||||
*/
|
||||
uint8 getRed() const noexcept { return argb.getRed(); }
|
||||
|
||||
/** Returns the green component of this colour.
|
||||
@returns a value between 0x00 and 0xff.
|
||||
*/
|
||||
uint8 getGreen() const noexcept { return argb.getGreen(); }
|
||||
|
||||
/** Returns the blue component of this colour.
|
||||
@returns a value between 0x00 and 0xff.
|
||||
*/
|
||||
uint8 getBlue() const noexcept { return argb.getBlue(); }
|
||||
|
||||
/** Returns the red component of this colour as a floating point value.
|
||||
@returns a value between 0.0 and 1.0
|
||||
*/
|
||||
float getFloatRed() const noexcept;
|
||||
|
||||
/** Returns the green component of this colour as a floating point value.
|
||||
@returns a value between 0.0 and 1.0
|
||||
*/
|
||||
float getFloatGreen() const noexcept;
|
||||
|
||||
/** Returns the blue component of this colour as a floating point value.
|
||||
@returns a value between 0.0 and 1.0
|
||||
*/
|
||||
float getFloatBlue() const noexcept;
|
||||
|
||||
/** Returns a premultiplied ARGB pixel object that represents this colour.
|
||||
*/
|
||||
const PixelARGB getPixelARGB() const noexcept;
|
||||
|
||||
/** Returns a 32-bit integer that represents this colour.
|
||||
|
||||
The format of this number is:
|
||||
((alpha << 24) | (red << 16) | (green << 8) | blue).
|
||||
*/
|
||||
uint32 getARGB() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the colour's alpha (opacity).
|
||||
|
||||
Alpha of 0x00 is completely transparent, 0xff is completely opaque.
|
||||
*/
|
||||
uint8 getAlpha() const noexcept { return argb.getAlpha(); }
|
||||
|
||||
/** Returns the colour's alpha (opacity) as a floating point value.
|
||||
|
||||
Alpha of 0.0 is completely transparent, 1.0 is completely opaque.
|
||||
*/
|
||||
float getFloatAlpha() const noexcept;
|
||||
|
||||
/** Returns true if this colour is completely opaque.
|
||||
|
||||
Equivalent to (getAlpha() == 0xff).
|
||||
*/
|
||||
bool isOpaque() const noexcept;
|
||||
|
||||
/** Returns true if this colour is completely transparent.
|
||||
|
||||
Equivalent to (getAlpha() == 0x00).
|
||||
*/
|
||||
bool isTransparent() const noexcept;
|
||||
|
||||
/** Returns a colour that's the same colour as this one, but with a new alpha value. */
|
||||
Colour withAlpha (uint8 newAlpha) const noexcept;
|
||||
|
||||
/** Returns a colour that's the same colour as this one, but with a new alpha value. */
|
||||
Colour withAlpha (float newAlpha) const noexcept;
|
||||
|
||||
/** Returns a colour that's the same colour as this one, but with a modified alpha value.
|
||||
The new colour's alpha will be this object's alpha multiplied by the value passed-in.
|
||||
*/
|
||||
Colour withMultipliedAlpha (float alphaMultiplier) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a colour that is the result of alpha-compositing a new colour over this one.
|
||||
If the foreground colour is semi-transparent, it is blended onto this colour accordingly.
|
||||
*/
|
||||
Colour overlaidWith (Colour foregroundColour) const noexcept;
|
||||
|
||||
/** Returns a colour that lies somewhere between this one and another.
|
||||
If amountOfOther is zero, the result is 100% this colour, if amountOfOther
|
||||
is 1.0, the result is 100% of the other colour.
|
||||
*/
|
||||
Colour interpolatedWith (Colour other, float proportionOfOther) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the colour's hue component.
|
||||
The value returned is in the range 0.0 to 1.0
|
||||
*/
|
||||
float getHue() const noexcept;
|
||||
|
||||
/** Returns the colour's saturation component.
|
||||
The value returned is in the range 0.0 to 1.0
|
||||
*/
|
||||
float getSaturation() const noexcept;
|
||||
|
||||
/** Returns the colour's saturation component as represented in the HSL colour space.
|
||||
The value returned is in the range 0.0 to 1.0
|
||||
*/
|
||||
float getSaturationHSL() const noexcept;
|
||||
|
||||
/** Returns the colour's brightness component.
|
||||
The value returned is in the range 0.0 to 1.0
|
||||
*/
|
||||
float getBrightness() const noexcept;
|
||||
|
||||
/** Returns the colour's lightness component.
|
||||
The value returned is in the range 0.0 to 1.0
|
||||
*/
|
||||
float getLightness() const noexcept;
|
||||
|
||||
/** Returns a skewed brightness value, adjusted to better reflect the way the human
|
||||
eye responds to different colour channels. This makes it better than getBrightness()
|
||||
for comparing differences in brightness.
|
||||
*/
|
||||
float getPerceivedBrightness() const noexcept;
|
||||
|
||||
/** Returns the colour's hue, saturation and brightness components all at once.
|
||||
The values returned are in the range 0.0 to 1.0
|
||||
*/
|
||||
void getHSB (float& hue,
|
||||
float& saturation,
|
||||
float& brightness) const noexcept;
|
||||
|
||||
/** Returns the colour's hue, saturation and lightness components all at once.
|
||||
The values returned are in the range 0.0 to 1.0
|
||||
*/
|
||||
void getHSL (float& hue,
|
||||
float& saturation,
|
||||
float& lightness) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a copy of this colour with a different hue. */
|
||||
Colour withHue (float newHue) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with a different saturation. */
|
||||
Colour withSaturation (float newSaturation) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with a different saturation in the HSL colour space. */
|
||||
Colour withSaturationHSL (float newSaturation) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with a different brightness.
|
||||
@see brighter, darker, withMultipliedBrightness
|
||||
*/
|
||||
Colour withBrightness (float newBrightness) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with a different lightness.
|
||||
@see lighter, darker, withMultipliedLightness
|
||||
*/
|
||||
Colour withLightness (float newLightness) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with its hue rotated.
|
||||
The new colour's hue is ((this->getHue() + amountToRotate) % 1.0)
|
||||
@see brighter, darker, withMultipliedBrightness
|
||||
*/
|
||||
Colour withRotatedHue (float amountToRotate) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with its saturation multiplied by the given value.
|
||||
The new colour's saturation is (this->getSaturation() * multiplier)
|
||||
(the result is clipped to legal limits).
|
||||
*/
|
||||
Colour withMultipliedSaturation (float multiplier) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with its saturation multiplied by the given value.
|
||||
The new colour's saturation is (this->getSaturation() * multiplier)
|
||||
(the result is clipped to legal limits).
|
||||
|
||||
This will be in the HSL colour space.
|
||||
*/
|
||||
Colour withMultipliedSaturationHSL (float multiplier) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with its brightness multiplied by the given value.
|
||||
The new colour's brightness is (this->getBrightness() * multiplier)
|
||||
(the result is clipped to legal limits).
|
||||
*/
|
||||
Colour withMultipliedBrightness (float amount) const noexcept;
|
||||
|
||||
/** Returns a copy of this colour with its lightness multiplied by the given value.
|
||||
The new colour's lightness is (this->lightness() * multiplier)
|
||||
(the result is clipped to legal limits).
|
||||
*/
|
||||
Colour withMultipliedLightness (float amount) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a brighter version of this colour.
|
||||
@param amountBrighter how much brighter to make it - a value greater than or equal to 0,
|
||||
where 0 is unchanged, and higher values make it brighter
|
||||
@see withMultipliedBrightness
|
||||
*/
|
||||
Colour brighter (float amountBrighter = 0.4f) const noexcept;
|
||||
|
||||
/** Returns a darker version of this colour.
|
||||
@param amountDarker how much darker to make it - a value greater than or equal to 0,
|
||||
where 0 is unchanged, and higher values make it darker
|
||||
@see withMultipliedBrightness
|
||||
*/
|
||||
Colour darker (float amountDarker = 0.4f) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a colour that will be clearly visible against this colour.
|
||||
|
||||
The amount parameter indicates how contrasting the new colour should
|
||||
be, so e.g. Colours::black.contrasting (0.1f) will return a colour
|
||||
that's just a little bit lighter; Colours::black.contrasting (1.0f) will
|
||||
return white; Colours::white.contrasting (1.0f) will return black, etc.
|
||||
*/
|
||||
Colour contrasting (float amount = 1.0f) const noexcept;
|
||||
|
||||
/** Returns a colour that is as close as possible to a target colour whilst
|
||||
still being in contrast to this one.
|
||||
|
||||
The colour that is returned will be the targetColour, but with its luminosity
|
||||
nudged up or down so that it differs from the luminosity of this colour
|
||||
by at least the amount specified by minLuminosityDiff.
|
||||
*/
|
||||
Colour contrasting (Colour targetColour, float minLuminosityDiff) const noexcept;
|
||||
|
||||
/** Returns a colour that contrasts against two colours.
|
||||
Looks for a colour that contrasts with both of the colours passed-in.
|
||||
Handy for things like choosing a highlight colour in text editors, etc.
|
||||
*/
|
||||
static Colour contrasting (Colour colour1,
|
||||
Colour colour2) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns an opaque shade of grey.
|
||||
@param brightness the level of grey to return - 0 is black, 1.0 is white
|
||||
*/
|
||||
static Colour greyLevel (float brightness) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a stringified version of this colour.
|
||||
The string can be turned back into a colour using the fromString() method.
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Reads the colour from a string that was created with toString(). */
|
||||
static Colour fromString (StringRef encodedColourString);
|
||||
|
||||
/** Returns the colour as a hex string in the form RRGGBB or AARRGGBB. */
|
||||
String toDisplayString (bool includeAlphaValue) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
PixelARGB argb { 0, 0, 0, 0 };
|
||||
};
|
||||
|
||||
} // namespace juce
|
270
deps/juce/modules/juce_graphics/colour/juce_ColourGradient.cpp
vendored
Normal file
270
deps/juce/modules/juce_graphics/colour/juce_ColourGradient.cpp
vendored
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ColourGradient::ColourGradient() noexcept : isRadial (false)
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
point1.setX (987654.0f);
|
||||
#define JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED jassert (point1.x != 987654.0f);
|
||||
#else
|
||||
#define JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED
|
||||
#endif
|
||||
}
|
||||
|
||||
ColourGradient::ColourGradient (const ColourGradient& other)
|
||||
: point1 (other.point1), point2 (other.point2), isRadial (other.isRadial), colours (other.colours)
|
||||
{}
|
||||
|
||||
ColourGradient::ColourGradient (ColourGradient&& other) noexcept
|
||||
: point1 (other.point1), point2 (other.point2), isRadial (other.isRadial),
|
||||
colours (std::move (other.colours))
|
||||
{}
|
||||
|
||||
ColourGradient& ColourGradient::operator= (const ColourGradient& other)
|
||||
{
|
||||
point1 = other.point1;
|
||||
point2 = other.point2;
|
||||
isRadial = other.isRadial;
|
||||
colours = other.colours;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ColourGradient& ColourGradient::operator= (ColourGradient&& other) noexcept
|
||||
{
|
||||
point1 = other.point1;
|
||||
point2 = other.point2;
|
||||
isRadial = other.isRadial;
|
||||
colours = std::move (other.colours);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ColourGradient::ColourGradient (Colour colour1, float x1, float y1,
|
||||
Colour colour2, float x2, float y2, bool radial)
|
||||
: ColourGradient (colour1, Point<float> (x1, y1),
|
||||
colour2, Point<float> (x2, y2), radial)
|
||||
{
|
||||
}
|
||||
|
||||
ColourGradient::ColourGradient (Colour colour1, Point<float> p1,
|
||||
Colour colour2, Point<float> p2, bool radial)
|
||||
: point1 (p1),
|
||||
point2 (p2),
|
||||
isRadial (radial)
|
||||
{
|
||||
colours.add (ColourPoint { 0.0, colour1 },
|
||||
ColourPoint { 1.0, colour2 });
|
||||
}
|
||||
|
||||
ColourGradient::~ColourGradient() {}
|
||||
|
||||
ColourGradient ColourGradient::vertical (Colour c1, float y1, Colour c2, float y2)
|
||||
{
|
||||
return { c1, 0, y1, c2, 0, y2, false };
|
||||
}
|
||||
|
||||
ColourGradient ColourGradient::horizontal (Colour c1, float x1, Colour c2, float x2)
|
||||
{
|
||||
return { c1, x1, 0, c2, x2, 0, false };
|
||||
}
|
||||
|
||||
bool ColourGradient::operator== (const ColourGradient& other) const noexcept
|
||||
{
|
||||
return point1 == other.point1 && point2 == other.point2
|
||||
&& isRadial == other.isRadial
|
||||
&& colours == other.colours;
|
||||
}
|
||||
|
||||
bool ColourGradient::operator!= (const ColourGradient& other) const noexcept
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ColourGradient::clearColours()
|
||||
{
|
||||
colours.clear();
|
||||
}
|
||||
|
||||
int ColourGradient::addColour (const double proportionAlongGradient, Colour colour)
|
||||
{
|
||||
// must be within the two end-points
|
||||
jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0);
|
||||
|
||||
if (proportionAlongGradient <= 0)
|
||||
{
|
||||
colours.set (0, { 0.0, colour });
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto pos = jmin (1.0, proportionAlongGradient);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < colours.size(); ++i)
|
||||
if (colours.getReference(i).position > pos)
|
||||
break;
|
||||
|
||||
colours.insert (i, { pos, colour });
|
||||
return i;
|
||||
}
|
||||
|
||||
void ColourGradient::removeColour (int index)
|
||||
{
|
||||
jassert (index > 0 && index < colours.size() - 1);
|
||||
colours.remove (index);
|
||||
}
|
||||
|
||||
void ColourGradient::multiplyOpacity (const float multiplier) noexcept
|
||||
{
|
||||
for (auto& c : colours)
|
||||
c.colour = c.colour.withMultipliedAlpha (multiplier);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int ColourGradient::getNumColours() const noexcept
|
||||
{
|
||||
return colours.size();
|
||||
}
|
||||
|
||||
double ColourGradient::getColourPosition (int index) const noexcept
|
||||
{
|
||||
if (isPositiveAndBelow (index, colours.size()))
|
||||
return colours.getReference (index).position;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Colour ColourGradient::getColour (int index) const noexcept
|
||||
{
|
||||
if (isPositiveAndBelow (index, colours.size()))
|
||||
return colours.getReference (index).colour;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ColourGradient::setColour (int index, Colour newColour) noexcept
|
||||
{
|
||||
if (isPositiveAndBelow (index, colours.size()))
|
||||
colours.getReference (index).colour = newColour;
|
||||
}
|
||||
|
||||
Colour ColourGradient::getColourAtPosition (double position) const noexcept
|
||||
{
|
||||
jassert (colours.getReference(0).position == 0.0); // the first colour specified has to go at position 0
|
||||
|
||||
if (position <= 0 || colours.size() <= 1)
|
||||
return colours.getReference(0).colour;
|
||||
|
||||
int i = colours.size() - 1;
|
||||
while (position < colours.getReference(i).position)
|
||||
--i;
|
||||
|
||||
auto& p1 = colours.getReference (i);
|
||||
|
||||
if (i >= colours.size() - 1)
|
||||
return p1.colour;
|
||||
|
||||
auto& p2 = colours.getReference (i + 1);
|
||||
|
||||
return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position)));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ColourGradient::createLookupTable (PixelARGB* const lookupTable, const int numEntries) const noexcept
|
||||
{
|
||||
JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates?
|
||||
jassert (colours.size() >= 2);
|
||||
jassert (numEntries > 0);
|
||||
jassert (colours.getReference(0).position == 0.0); // The first colour specified has to go at position 0
|
||||
|
||||
auto pix1 = colours.getReference (0).colour.getPixelARGB();
|
||||
int index = 0;
|
||||
|
||||
for (int j = 1; j < colours.size(); ++j)
|
||||
{
|
||||
auto& p = colours.getReference (j);
|
||||
auto numToDo = roundToInt (p.position * (numEntries - 1)) - index;
|
||||
auto pix2 = p.colour.getPixelARGB();
|
||||
|
||||
for (int i = 0; i < numToDo; ++i)
|
||||
{
|
||||
jassert (index >= 0 && index < numEntries);
|
||||
|
||||
lookupTable[index] = pix1;
|
||||
lookupTable[index].tween (pix2, (uint32) ((i << 8) / numToDo));
|
||||
++index;
|
||||
}
|
||||
|
||||
pix1 = pix2;
|
||||
}
|
||||
|
||||
while (index < numEntries)
|
||||
lookupTable [index++] = pix1;
|
||||
}
|
||||
|
||||
int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock<PixelARGB>& lookupTable) const
|
||||
{
|
||||
JUCE_COLOURGRADIENT_CHECK_COORDS_INITIALISED // Trying to use this object without setting its coordinates?
|
||||
jassert (colours.size() >= 2);
|
||||
|
||||
auto numEntries = jlimit (1, jmax (1, (colours.size() - 1) << 8),
|
||||
3 * (int) point1.transformedBy (transform)
|
||||
.getDistanceFrom (point2.transformedBy (transform)));
|
||||
lookupTable.malloc (numEntries);
|
||||
createLookupTable (lookupTable, numEntries);
|
||||
return numEntries;
|
||||
}
|
||||
|
||||
bool ColourGradient::isOpaque() const noexcept
|
||||
{
|
||||
for (auto& c : colours)
|
||||
if (! c.colour.isOpaque())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ColourGradient::isInvisible() const noexcept
|
||||
{
|
||||
for (auto& c : colours)
|
||||
if (! c.colour.isTransparent())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ColourGradient::ColourPoint::operator== (ColourPoint other) const noexcept
|
||||
{
|
||||
return position == other.position && colour == other.colour;
|
||||
}
|
||||
|
||||
bool ColourGradient::ColourPoint::operator!= (ColourPoint other) const noexcept
|
||||
{
|
||||
return position != other.position || colour != other.colour;
|
||||
}
|
||||
|
||||
} // namespace juce
|
224
deps/juce/modules/juce_graphics/colour/juce_ColourGradient.h
vendored
Normal file
224
deps/juce/modules/juce_graphics/colour/juce_ColourGradient.h
vendored
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Describes the layout and colours that should be used to paint a colour gradient.
|
||||
|
||||
@see Graphics::setGradientFill
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API ColourGradient final
|
||||
{
|
||||
public:
|
||||
/** Creates an uninitialised gradient.
|
||||
|
||||
If you use this constructor instead of the other one, be sure to set all the
|
||||
object's public member variables before using it!
|
||||
*/
|
||||
ColourGradient() noexcept;
|
||||
|
||||
ColourGradient (const ColourGradient&);
|
||||
ColourGradient (ColourGradient&&) noexcept;
|
||||
ColourGradient& operator= (const ColourGradient&);
|
||||
ColourGradient& operator= (ColourGradient&&) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a gradient object.
|
||||
|
||||
(x1, y1) is the location to draw with colour1. Likewise (x2, y2) is where
|
||||
colour2 should be. In between them there's a gradient.
|
||||
|
||||
If isRadial is true, the colours form a circular gradient with (x1, y1) at
|
||||
its centre.
|
||||
|
||||
The alpha transparencies of the colours are used, so note that
|
||||
if you blend from transparent to a solid colour, the RGB of the transparent
|
||||
colour will become visible in parts of the gradient. e.g. blending
|
||||
from Colour::transparentBlack to Colours::white will produce a
|
||||
muddy grey colour midway, but Colour::transparentWhite to Colours::white
|
||||
will be white all the way across.
|
||||
|
||||
@see ColourGradient
|
||||
*/
|
||||
ColourGradient (Colour colour1, float x1, float y1,
|
||||
Colour colour2, float x2, float y2,
|
||||
bool isRadial);
|
||||
|
||||
/** Creates a gradient object.
|
||||
|
||||
point1 is the location to draw with colour1. Likewise point2 is where
|
||||
colour2 should be. In between them there's a gradient.
|
||||
|
||||
If isRadial is true, the colours form a circular gradient with point1 at
|
||||
its centre.
|
||||
|
||||
The alpha transparencies of the colours are used, so note that
|
||||
if you blend from transparent to a solid colour, the RGB of the transparent
|
||||
colour will become visible in parts of the gradient. e.g. blending
|
||||
from Colour::transparentBlack to Colours::white will produce a
|
||||
muddy grey colour midway, but Colour::transparentWhite to Colours::white
|
||||
will be white all the way across.
|
||||
|
||||
@see ColourGradient
|
||||
*/
|
||||
ColourGradient (Colour colour1, Point<float> point1,
|
||||
Colour colour2, Point<float> point2,
|
||||
bool isRadial);
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a vertical linear gradient between two Y coordinates */
|
||||
static ColourGradient vertical (Colour colour1, float y1,
|
||||
Colour colour2, float y2);
|
||||
|
||||
/** Creates a horizontal linear gradient between two X coordinates */
|
||||
static ColourGradient horizontal (Colour colour1, float x1,
|
||||
Colour colour2, float x2);
|
||||
|
||||
/** Creates a vertical linear gradient from top to bottom in a rectangle */
|
||||
template <typename Type>
|
||||
static ColourGradient vertical (Colour colourTop, Colour colourBottom, Rectangle<Type> area)
|
||||
{
|
||||
return vertical (colourTop, (float) area.getY(), colourBottom, (float) area.getBottom());
|
||||
}
|
||||
|
||||
/** Creates a horizontal linear gradient from right to left in a rectangle */
|
||||
template <typename Type>
|
||||
static ColourGradient horizontal (Colour colourLeft, Colour colourRight, Rectangle<Type> area)
|
||||
{
|
||||
return horizontal (colourLeft, (float) area.getX(), colourRight, (float) area.getRight());
|
||||
}
|
||||
|
||||
/** Destructor */
|
||||
~ColourGradient();
|
||||
|
||||
//==============================================================================
|
||||
/** Removes any colours that have been added.
|
||||
|
||||
This will also remove any start and end colours, so the gradient won't work. You'll
|
||||
need to add more colours with addColour().
|
||||
*/
|
||||
void clearColours();
|
||||
|
||||
/** Adds a colour at a point along the length of the gradient.
|
||||
|
||||
This allows the gradient to go through a spectrum of colours, instead of just a
|
||||
start and end colour.
|
||||
|
||||
@param proportionAlongGradient a value between 0 and 1.0, which is the proportion
|
||||
of the distance along the line between the two points
|
||||
at which the colour should occur.
|
||||
@param colour the colour that should be used at this point
|
||||
@returns the index at which the new point was added
|
||||
*/
|
||||
int addColour (double proportionAlongGradient, Colour colour);
|
||||
|
||||
/** Removes one of the colours from the gradient. */
|
||||
void removeColour (int index);
|
||||
|
||||
/** Multiplies the alpha value of all the colours by the given scale factor */
|
||||
void multiplyOpacity (float multiplier) noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of colour-stops that have been added. */
|
||||
int getNumColours() const noexcept;
|
||||
|
||||
/** Returns the position along the length of the gradient of the colour with this index.
|
||||
|
||||
The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
|
||||
*/
|
||||
double getColourPosition (int index) const noexcept;
|
||||
|
||||
/** Returns the colour that was added with a given index.
|
||||
The index is from 0 to getNumColours() - 1.
|
||||
*/
|
||||
Colour getColour (int index) const noexcept;
|
||||
|
||||
/** Changes the colour at a given index.
|
||||
The index is from 0 to getNumColours() - 1.
|
||||
*/
|
||||
void setColour (int index, Colour newColour) noexcept;
|
||||
|
||||
/** Returns the an interpolated colour at any position along the gradient.
|
||||
@param position the position along the gradient, between 0 and 1
|
||||
*/
|
||||
Colour getColourAtPosition (double position) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Creates a set of interpolated premultiplied ARGB values.
|
||||
This will resize the HeapBlock, fill it with the colours, and will return the number of
|
||||
colours that it added.
|
||||
When calling this, the ColourGradient must have at least 2 colour stops specified.
|
||||
*/
|
||||
int createLookupTable (const AffineTransform& transform, HeapBlock<PixelARGB>& resultLookupTable) const;
|
||||
|
||||
/** Creates a set of interpolated premultiplied ARGB values.
|
||||
This will fill an array of a user-specified size with the gradient, interpolating to fit.
|
||||
The numEntries argument specifies the size of the array, and this size must be greater than zero.
|
||||
When calling this, the ColourGradient must have at least 2 colour stops specified.
|
||||
*/
|
||||
void createLookupTable (PixelARGB* resultLookupTable, int numEntries) const noexcept;
|
||||
|
||||
/** Returns true if all colours are opaque. */
|
||||
bool isOpaque() const noexcept;
|
||||
|
||||
/** Returns true if all colours are completely transparent. */
|
||||
bool isInvisible() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
Point<float> point1, point2;
|
||||
|
||||
/** If true, the gradient should be filled circularly, centred around
|
||||
point1, with point2 defining a point on the circumference.
|
||||
|
||||
If false, the gradient is linear between the two points.
|
||||
*/
|
||||
bool isRadial;
|
||||
|
||||
bool operator== (const ColourGradient&) const noexcept;
|
||||
bool operator!= (const ColourGradient&) const noexcept;
|
||||
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
struct ColourPoint
|
||||
{
|
||||
bool operator== (ColourPoint) const noexcept;
|
||||
bool operator!= (ColourPoint) const noexcept;
|
||||
|
||||
double position;
|
||||
Colour colour;
|
||||
};
|
||||
|
||||
Array<ColourPoint> colours;
|
||||
|
||||
JUCE_LEAK_DETECTOR (ColourGradient)
|
||||
};
|
||||
|
||||
} // namespace juce
|
189
deps/juce/modules/juce_graphics/colour/juce_Colours.cpp
vendored
Normal file
189
deps/juce/modules/juce_graphics/colour/juce_Colours.cpp
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
Colour Colours::findColourForName (const String& colourName,
|
||||
Colour defaultColour)
|
||||
{
|
||||
struct StringHashAndColour { uint32 stringHash, colour; };
|
||||
|
||||
static const StringHashAndColour presets[]
|
||||
{
|
||||
{ 0x05978fff, 0xff000000 }, /* black */
|
||||
{ 0x06bdcc29, 0xffffffff }, /* white */
|
||||
{ 0x002e305a, 0xff0000ff }, /* blue */
|
||||
{ 0x00308adf, 0xff808080 }, /* grey */
|
||||
{ 0x05e0cf03, 0xff008000 }, /* green */
|
||||
{ 0x0001b891, 0xffff0000 }, /* red */
|
||||
{ 0xd43c6474, 0xffffff00 }, /* yellow */
|
||||
{ 0x620886da, 0xfff0f8ff }, /* aliceblue */
|
||||
{ 0x20a2676a, 0xfffaebd7 }, /* antiquewhite */
|
||||
{ 0x002dcebc, 0xff00ffff }, /* aqua */
|
||||
{ 0x46bb5f7e, 0xff7fffd4 }, /* aquamarine */
|
||||
{ 0x0590228f, 0xfff0ffff }, /* azure */
|
||||
{ 0x05947fe4, 0xfff5f5dc }, /* beige */
|
||||
{ 0xad388e35, 0xffffe4c4 }, /* bisque */
|
||||
{ 0x00674f7e, 0xffffebcd }, /* blanchedalmond */
|
||||
{ 0x39129959, 0xff8a2be2 }, /* blueviolet */
|
||||
{ 0x059a8136, 0xffa52a2a }, /* brown */
|
||||
{ 0x89cea8f9, 0xffdeb887 }, /* burlywood */
|
||||
{ 0x0fa260cf, 0xff5f9ea0 }, /* cadetblue */
|
||||
{ 0x6b748956, 0xff7fff00 }, /* chartreuse */
|
||||
{ 0x2903623c, 0xffd2691e }, /* chocolate */
|
||||
{ 0x05a74431, 0xffff7f50 }, /* coral */
|
||||
{ 0x618d42dd, 0xff6495ed }, /* cornflowerblue */
|
||||
{ 0xe4b479fd, 0xfffff8dc }, /* cornsilk */
|
||||
{ 0x3d8c4edf, 0xffdc143c }, /* crimson */
|
||||
{ 0x002ed323, 0xff00ffff }, /* cyan */
|
||||
{ 0x67cc74d0, 0xff00008b }, /* darkblue */
|
||||
{ 0x67cd1799, 0xff008b8b }, /* darkcyan */
|
||||
{ 0x31bbd168, 0xffb8860b }, /* darkgoldenrod */
|
||||
{ 0x67cecf55, 0xff555555 }, /* darkgrey */
|
||||
{ 0x920b194d, 0xff006400 }, /* darkgreen */
|
||||
{ 0x923edd4c, 0xffbdb76b }, /* darkkhaki */
|
||||
{ 0x5c293873, 0xff8b008b }, /* darkmagenta */
|
||||
{ 0x6b6671fe, 0xff556b2f }, /* darkolivegreen */
|
||||
{ 0xbcfd2524, 0xffff8c00 }, /* darkorange */
|
||||
{ 0xbcfdf799, 0xff9932cc }, /* darkorchid */
|
||||
{ 0x55ee0d5b, 0xff8b0000 }, /* darkred */
|
||||
{ 0xc2e5f564, 0xffe9967a }, /* darksalmon */
|
||||
{ 0x61be858a, 0xff8fbc8f }, /* darkseagreen */
|
||||
{ 0xc2b0f2bd, 0xff483d8b }, /* darkslateblue */
|
||||
{ 0xc2b34d42, 0xff2f4f4f }, /* darkslategrey */
|
||||
{ 0x7cf2b06b, 0xff00ced1 }, /* darkturquoise */
|
||||
{ 0xc8769375, 0xff9400d3 }, /* darkviolet */
|
||||
{ 0x25832862, 0xffff1493 }, /* deeppink */
|
||||
{ 0xfcad568f, 0xff00bfff }, /* deepskyblue */
|
||||
{ 0x634c8b67, 0xff696969 }, /* dimgrey */
|
||||
{ 0x45c1ce55, 0xff1e90ff }, /* dodgerblue */
|
||||
{ 0xef19e3cb, 0xffb22222 }, /* firebrick */
|
||||
{ 0xb852b195, 0xfffffaf0 }, /* floralwhite */
|
||||
{ 0xd086fd06, 0xff228b22 }, /* forestgreen */
|
||||
{ 0xe106b6d7, 0xffff00ff }, /* fuchsia */
|
||||
{ 0x7880d61e, 0xffdcdcdc }, /* gainsboro */
|
||||
{ 0x2018a2fa, 0xfff8f8ff }, /* ghostwhite */
|
||||
{ 0x00308060, 0xffffd700 }, /* gold */
|
||||
{ 0xb3b3bc1e, 0xffdaa520 }, /* goldenrod */
|
||||
{ 0xbab8a537, 0xffadff2f }, /* greenyellow */
|
||||
{ 0xe4cacafb, 0xfff0fff0 }, /* honeydew */
|
||||
{ 0x41892743, 0xffff69b4 }, /* hotpink */
|
||||
{ 0xd5796f1a, 0xffcd5c5c }, /* indianred */
|
||||
{ 0xb969fed2, 0xff4b0082 }, /* indigo */
|
||||
{ 0x05fef6a9, 0xfffffff0 }, /* ivory */
|
||||
{ 0x06149302, 0xfff0e68c }, /* khaki */
|
||||
{ 0xad5a05c7, 0xffe6e6fa }, /* lavender */
|
||||
{ 0x7c4d5b99, 0xfffff0f5 }, /* lavenderblush */
|
||||
{ 0x41cc4377, 0xff7cfc00 }, /* lawngreen */
|
||||
{ 0x195756f0, 0xfffffacd }, /* lemonchiffon */
|
||||
{ 0x28e4ea70, 0xffadd8e6 }, /* lightblue */
|
||||
{ 0xf3c7ccdb, 0xfff08080 }, /* lightcoral */
|
||||
{ 0x28e58d39, 0xffe0ffff }, /* lightcyan */
|
||||
{ 0x21234e3c, 0xfffafad2 }, /* lightgoldenrodyellow */
|
||||
{ 0xf40157ad, 0xff90ee90 }, /* lightgreen */
|
||||
{ 0x28e744f5, 0xffd3d3d3 }, /* lightgrey */
|
||||
{ 0x28eb3b8c, 0xffffb6c1 }, /* lightpink */
|
||||
{ 0x9fb78304, 0xffffa07a }, /* lightsalmon */
|
||||
{ 0x50632b2a, 0xff20b2aa }, /* lightseagreen */
|
||||
{ 0x68fb7b25, 0xff87cefa }, /* lightskyblue */
|
||||
{ 0xa8a35ba2, 0xff778899 }, /* lightslategrey */
|
||||
{ 0xa20d484f, 0xffb0c4de }, /* lightsteelblue */
|
||||
{ 0xaa2cf10a, 0xffffffe0 }, /* lightyellow */
|
||||
{ 0x0032afd5, 0xff00ff00 }, /* lime */
|
||||
{ 0x607bbc4e, 0xff32cd32 }, /* limegreen */
|
||||
{ 0x06234efa, 0xfffaf0e6 }, /* linen */
|
||||
{ 0x316858a9, 0xffff00ff }, /* magenta */
|
||||
{ 0xbf8ca470, 0xff800000 }, /* maroon */
|
||||
{ 0xbd58e0b3, 0xff66cdaa }, /* mediumaquamarine */
|
||||
{ 0x967dfd4f, 0xff0000cd }, /* mediumblue */
|
||||
{ 0x056f5c58, 0xffba55d3 }, /* mediumorchid */
|
||||
{ 0x07556b71, 0xff9370db }, /* mediumpurple */
|
||||
{ 0x5369b689, 0xff3cb371 }, /* mediumseagreen */
|
||||
{ 0x066be19e, 0xff7b68ee }, /* mediumslateblue */
|
||||
{ 0x3256b281, 0xff00fa9a }, /* mediumspringgreen */
|
||||
{ 0xc0ad9f4c, 0xff48d1cc }, /* mediumturquoise */
|
||||
{ 0x628e63dd, 0xffc71585 }, /* mediumvioletred */
|
||||
{ 0x168eb32a, 0xff191970 }, /* midnightblue */
|
||||
{ 0x4306b960, 0xfff5fffa }, /* mintcream */
|
||||
{ 0x4cbc0e6b, 0xffffe4e1 }, /* mistyrose */
|
||||
{ 0xd9447d59, 0xffffe4b5 }, /* moccasin */
|
||||
{ 0xe97218a6, 0xffffdead }, /* navajowhite */
|
||||
{ 0x00337bb6, 0xff000080 }, /* navy */
|
||||
{ 0xadd2d33e, 0xfffdf5e6 }, /* oldlace */
|
||||
{ 0x064ee1db, 0xff808000 }, /* olive */
|
||||
{ 0x9e33a98a, 0xff6b8e23 }, /* olivedrab */
|
||||
{ 0xc3de262e, 0xffffa500 }, /* orange */
|
||||
{ 0x58bebba3, 0xffff4500 }, /* orangered */
|
||||
{ 0xc3def8a3, 0xffda70d6 }, /* orchid */
|
||||
{ 0x28cb4834, 0xffeee8aa }, /* palegoldenrod */
|
||||
{ 0x3d9dd619, 0xff98fb98 }, /* palegreen */
|
||||
{ 0x74022737, 0xffafeeee }, /* paleturquoise */
|
||||
{ 0x15e2ebc8, 0xffdb7093 }, /* palevioletred */
|
||||
{ 0x5fd898e2, 0xffffefd5 }, /* papayawhip */
|
||||
{ 0x93e1b776, 0xffffdab9 }, /* peachpuff */
|
||||
{ 0x003472f8, 0xffcd853f }, /* peru */
|
||||
{ 0x00348176, 0xffffc0cb }, /* pink */
|
||||
{ 0x00348d94, 0xffdda0dd }, /* plum */
|
||||
{ 0xd036be93, 0xffb0e0e6 }, /* powderblue */
|
||||
{ 0xc5c507bc, 0xff800080 }, /* purple */
|
||||
{ 0xf381f607, 0xff663399 }, /* rebeccapurple */
|
||||
{ 0xa89d65b3, 0xffbc8f8f }, /* rosybrown */
|
||||
{ 0xbd9413e1, 0xff4169e1 }, /* royalblue */
|
||||
{ 0xf456044f, 0xff8b4513 }, /* saddlebrown */
|
||||
{ 0xc9c6f66e, 0xfffa8072 }, /* salmon */
|
||||
{ 0x0bb131e1, 0xfff4a460 }, /* sandybrown */
|
||||
{ 0x34636c14, 0xff2e8b57 }, /* seagreen */
|
||||
{ 0x3507fb41, 0xfffff5ee }, /* seashell */
|
||||
{ 0xca348772, 0xffa0522d }, /* sienna */
|
||||
{ 0xca37d30d, 0xffc0c0c0 }, /* silver */
|
||||
{ 0x80da74fb, 0xff87ceeb }, /* skyblue */
|
||||
{ 0x44a8dd73, 0xff6a5acd }, /* slateblue */
|
||||
{ 0x44ab37f8, 0xff708090 }, /* slategrey */
|
||||
{ 0x0035f183, 0xfffffafa }, /* snow */
|
||||
{ 0xd5440d16, 0xff00ff7f }, /* springgreen */
|
||||
{ 0x3e1524a5, 0xff4682b4 }, /* steelblue */
|
||||
{ 0x0001bfa1, 0xffd2b48c }, /* tan */
|
||||
{ 0x0036425c, 0xff008080 }, /* teal */
|
||||
{ 0xafc8858f, 0xffd8bfd8 }, /* thistle */
|
||||
{ 0xcc41600a, 0xffff6347 }, /* tomato */
|
||||
{ 0xfeea9b21, 0xff40e0d0 }, /* turquoise */
|
||||
{ 0xcf57947f, 0xffee82ee }, /* violet */
|
||||
{ 0x06bdbae7, 0xfff5deb3 }, /* wheat */
|
||||
{ 0x10802ee6, 0xfff5f5f5 }, /* whitesmoke */
|
||||
{ 0xe1b5130f, 0xff9acd32 }, /* yellowgreen */
|
||||
};
|
||||
|
||||
const auto hash = (uint32) colourName.trim().toLowerCase().hashCode();
|
||||
|
||||
for (auto entry : presets)
|
||||
if (entry.stringHash == hash)
|
||||
return Colour (entry.colour);
|
||||
|
||||
return defaultColour;
|
||||
}
|
||||
|
||||
} // namespace juce
|
196
deps/juce/modules/juce_graphics/colour/juce_Colours.h
vendored
Normal file
196
deps/juce/modules/juce_graphics/colour/juce_Colours.h
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Contains a set of predefined named colours (mostly standard HTML colours)
|
||||
|
||||
@see Colour
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
namespace Colours
|
||||
{
|
||||
|
||||
const Colour transparentBlack { 0 };
|
||||
const Colour transparentWhite { 0x00ffffff };
|
||||
|
||||
const Colour aliceblue { 0xfff0f8ff };
|
||||
const Colour antiquewhite { 0xfffaebd7 };
|
||||
const Colour aqua { 0xff00ffff };
|
||||
const Colour aquamarine { 0xff7fffd4 };
|
||||
const Colour azure { 0xfff0ffff };
|
||||
const Colour beige { 0xfff5f5dc };
|
||||
const Colour bisque { 0xffffe4c4 };
|
||||
const Colour black { 0xff000000 };
|
||||
const Colour blanchedalmond { 0xffffebcd };
|
||||
const Colour blue { 0xff0000ff };
|
||||
const Colour blueviolet { 0xff8a2be2 };
|
||||
const Colour brown { 0xffa52a2a };
|
||||
const Colour burlywood { 0xffdeb887 };
|
||||
const Colour cadetblue { 0xff5f9ea0 };
|
||||
const Colour chartreuse { 0xff7fff00 };
|
||||
const Colour chocolate { 0xffd2691e };
|
||||
const Colour coral { 0xffff7f50 };
|
||||
const Colour cornflowerblue { 0xff6495ed };
|
||||
const Colour cornsilk { 0xfffff8dc };
|
||||
const Colour crimson { 0xffdc143c };
|
||||
const Colour cyan { 0xff00ffff };
|
||||
const Colour darkblue { 0xff00008b };
|
||||
const Colour darkcyan { 0xff008b8b };
|
||||
const Colour darkgoldenrod { 0xffb8860b };
|
||||
const Colour darkgrey { 0xff555555 };
|
||||
const Colour darkgreen { 0xff006400 };
|
||||
const Colour darkkhaki { 0xffbdb76b };
|
||||
const Colour darkmagenta { 0xff8b008b };
|
||||
const Colour darkolivegreen { 0xff556b2f };
|
||||
const Colour darkorange { 0xffff8c00 };
|
||||
const Colour darkorchid { 0xff9932cc };
|
||||
const Colour darkred { 0xff8b0000 };
|
||||
const Colour darksalmon { 0xffe9967a };
|
||||
const Colour darkseagreen { 0xff8fbc8f };
|
||||
const Colour darkslateblue { 0xff483d8b };
|
||||
const Colour darkslategrey { 0xff2f4f4f };
|
||||
const Colour darkturquoise { 0xff00ced1 };
|
||||
const Colour darkviolet { 0xff9400d3 };
|
||||
const Colour deeppink { 0xffff1493 };
|
||||
const Colour deepskyblue { 0xff00bfff };
|
||||
const Colour dimgrey { 0xff696969 };
|
||||
const Colour dodgerblue { 0xff1e90ff };
|
||||
const Colour firebrick { 0xffb22222 };
|
||||
const Colour floralwhite { 0xfffffaf0 };
|
||||
const Colour forestgreen { 0xff228b22 };
|
||||
const Colour fuchsia { 0xffff00ff };
|
||||
const Colour gainsboro { 0xffdcdcdc };
|
||||
const Colour ghostwhite { 0xfff8f8ff };
|
||||
const Colour gold { 0xffffd700 };
|
||||
const Colour goldenrod { 0xffdaa520 };
|
||||
const Colour grey { 0xff808080 };
|
||||
const Colour green { 0xff008000 };
|
||||
const Colour greenyellow { 0xffadff2f };
|
||||
const Colour honeydew { 0xfff0fff0 };
|
||||
const Colour hotpink { 0xffff69b4 };
|
||||
const Colour indianred { 0xffcd5c5c };
|
||||
const Colour indigo { 0xff4b0082 };
|
||||
const Colour ivory { 0xfffffff0 };
|
||||
const Colour khaki { 0xfff0e68c };
|
||||
const Colour lavender { 0xffe6e6fa };
|
||||
const Colour lavenderblush { 0xfffff0f5 };
|
||||
const Colour lawngreen { 0xff7cfc00 };
|
||||
const Colour lemonchiffon { 0xfffffacd };
|
||||
const Colour lightblue { 0xffadd8e6 };
|
||||
const Colour lightcoral { 0xfff08080 };
|
||||
const Colour lightcyan { 0xffe0ffff };
|
||||
const Colour lightgoldenrodyellow { 0xfffafad2 };
|
||||
const Colour lightgreen { 0xff90ee90 };
|
||||
const Colour lightgrey { 0xffd3d3d3 };
|
||||
const Colour lightpink { 0xffffb6c1 };
|
||||
const Colour lightsalmon { 0xffffa07a };
|
||||
const Colour lightseagreen { 0xff20b2aa };
|
||||
const Colour lightskyblue { 0xff87cefa };
|
||||
const Colour lightslategrey { 0xff778899 };
|
||||
const Colour lightsteelblue { 0xffb0c4de };
|
||||
const Colour lightyellow { 0xffffffe0 };
|
||||
const Colour lime { 0xff00ff00 };
|
||||
const Colour limegreen { 0xff32cd32 };
|
||||
const Colour linen { 0xfffaf0e6 };
|
||||
const Colour magenta { 0xffff00ff };
|
||||
const Colour maroon { 0xff800000 };
|
||||
const Colour mediumaquamarine { 0xff66cdaa };
|
||||
const Colour mediumblue { 0xff0000cd };
|
||||
const Colour mediumorchid { 0xffba55d3 };
|
||||
const Colour mediumpurple { 0xff9370db };
|
||||
const Colour mediumseagreen { 0xff3cb371 };
|
||||
const Colour mediumslateblue { 0xff7b68ee };
|
||||
const Colour mediumspringgreen { 0xff00fa9a };
|
||||
const Colour mediumturquoise { 0xff48d1cc };
|
||||
const Colour mediumvioletred { 0xffc71585 };
|
||||
const Colour midnightblue { 0xff191970 };
|
||||
const Colour mintcream { 0xfff5fffa };
|
||||
const Colour mistyrose { 0xffffe4e1 };
|
||||
const Colour moccasin { 0xffffe4b5 };
|
||||
const Colour navajowhite { 0xffffdead };
|
||||
const Colour navy { 0xff000080 };
|
||||
const Colour oldlace { 0xfffdf5e6 };
|
||||
const Colour olive { 0xff808000 };
|
||||
const Colour olivedrab { 0xff6b8e23 };
|
||||
const Colour orange { 0xffffa500 };
|
||||
const Colour orangered { 0xffff4500 };
|
||||
const Colour orchid { 0xffda70d6 };
|
||||
const Colour palegoldenrod { 0xffeee8aa };
|
||||
const Colour palegreen { 0xff98fb98 };
|
||||
const Colour paleturquoise { 0xffafeeee };
|
||||
const Colour palevioletred { 0xffdb7093 };
|
||||
const Colour papayawhip { 0xffffefd5 };
|
||||
const Colour peachpuff { 0xffffdab9 };
|
||||
const Colour peru { 0xffcd853f };
|
||||
const Colour pink { 0xffffc0cb };
|
||||
const Colour plum { 0xffdda0dd };
|
||||
const Colour powderblue { 0xffb0e0e6 };
|
||||
const Colour purple { 0xff800080 };
|
||||
const Colour rebeccapurple { 0xff663399 };
|
||||
const Colour red { 0xffff0000 };
|
||||
const Colour rosybrown { 0xffbc8f8f };
|
||||
const Colour royalblue { 0xff4169e1 };
|
||||
const Colour saddlebrown { 0xff8b4513 };
|
||||
const Colour salmon { 0xfffa8072 };
|
||||
const Colour sandybrown { 0xfff4a460 };
|
||||
const Colour seagreen { 0xff2e8b57 };
|
||||
const Colour seashell { 0xfffff5ee };
|
||||
const Colour sienna { 0xffa0522d };
|
||||
const Colour silver { 0xffc0c0c0 };
|
||||
const Colour skyblue { 0xff87ceeb };
|
||||
const Colour slateblue { 0xff6a5acd };
|
||||
const Colour slategrey { 0xff708090 };
|
||||
const Colour snow { 0xfffffafa };
|
||||
const Colour springgreen { 0xff00ff7f };
|
||||
const Colour steelblue { 0xff4682b4 };
|
||||
const Colour tan { 0xffd2b48c };
|
||||
const Colour teal { 0xff008080 };
|
||||
const Colour thistle { 0xffd8bfd8 };
|
||||
const Colour tomato { 0xffff6347 };
|
||||
const Colour turquoise { 0xff40e0d0 };
|
||||
const Colour violet { 0xffee82ee };
|
||||
const Colour wheat { 0xfff5deb3 };
|
||||
const Colour white { 0xffffffff };
|
||||
const Colour whitesmoke { 0xfff5f5f5 };
|
||||
const Colour yellow { 0xffffff00 };
|
||||
const Colour yellowgreen { 0xff9acd32 };
|
||||
|
||||
/** Attempts to look up a string in the list of known colour names, and return
|
||||
the appropriate colour.
|
||||
|
||||
A non-case-sensitive search is made of the list of predefined colours, and
|
||||
if a match is found, that colour is returned. If no match is found, the
|
||||
colour passed in as the defaultColour parameter is returned.
|
||||
*/
|
||||
JUCE_API Colour findColourForName (const String& colourName,
|
||||
Colour defaultColour);
|
||||
} // namespace Colours
|
||||
|
||||
} // namespace juce
|
157
deps/juce/modules/juce_graphics/colour/juce_FillType.cpp
vendored
Normal file
157
deps/juce/modules/juce_graphics/colour/juce_FillType.cpp
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
FillType::FillType() noexcept
|
||||
: colour (0xff000000)
|
||||
{
|
||||
}
|
||||
|
||||
FillType::FillType (Colour c) noexcept
|
||||
: colour (c)
|
||||
{
|
||||
}
|
||||
|
||||
FillType::FillType (const ColourGradient& g)
|
||||
: colour (0xff000000), gradient (new ColourGradient (g))
|
||||
{
|
||||
}
|
||||
|
||||
FillType::FillType (ColourGradient&& g)
|
||||
: colour (0xff000000), gradient (new ColourGradient (std::move (g)))
|
||||
{
|
||||
}
|
||||
|
||||
FillType::FillType (const Image& im, const AffineTransform& t) noexcept
|
||||
: colour (0xff000000), image (im), transform (t)
|
||||
{
|
||||
}
|
||||
|
||||
FillType::FillType (const FillType& other)
|
||||
: colour (other.colour),
|
||||
gradient (createCopyIfNotNull (other.gradient.get())),
|
||||
image (other.image),
|
||||
transform (other.transform)
|
||||
{
|
||||
}
|
||||
|
||||
FillType& FillType::operator= (const FillType& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
colour = other.colour;
|
||||
gradient.reset (createCopyIfNotNull (other.gradient.get()));
|
||||
image = other.image;
|
||||
transform = other.transform;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FillType::FillType (FillType&& other) noexcept
|
||||
: colour (other.colour),
|
||||
gradient (std::move (other.gradient)),
|
||||
image (std::move (other.image)),
|
||||
transform (other.transform)
|
||||
{
|
||||
}
|
||||
|
||||
FillType& FillType::operator= (FillType&& other) noexcept
|
||||
{
|
||||
jassert (this != &other); // hopefully the compiler should make this situation impossible!
|
||||
|
||||
colour = other.colour;
|
||||
gradient = std::move (other.gradient);
|
||||
image = std::move (other.image);
|
||||
transform = other.transform;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FillType::~FillType() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
bool FillType::operator== (const FillType& other) const
|
||||
{
|
||||
return colour == other.colour && image == other.image
|
||||
&& transform == other.transform
|
||||
&& (gradient == other.gradient
|
||||
|| (gradient != nullptr && other.gradient != nullptr && *gradient == *other.gradient));
|
||||
}
|
||||
|
||||
bool FillType::operator!= (const FillType& other) const
|
||||
{
|
||||
return ! operator== (other);
|
||||
}
|
||||
|
||||
void FillType::setColour (Colour newColour) noexcept
|
||||
{
|
||||
gradient.reset();
|
||||
image = {};
|
||||
colour = newColour;
|
||||
}
|
||||
|
||||
void FillType::setGradient (const ColourGradient& newGradient)
|
||||
{
|
||||
if (gradient != nullptr)
|
||||
{
|
||||
*gradient = newGradient;
|
||||
}
|
||||
else
|
||||
{
|
||||
image = {};
|
||||
gradient.reset (new ColourGradient (newGradient));
|
||||
colour = Colours::black;
|
||||
}
|
||||
}
|
||||
|
||||
void FillType::setTiledImage (const Image& newImage, const AffineTransform& newTransform) noexcept
|
||||
{
|
||||
gradient.reset();
|
||||
image = newImage;
|
||||
transform = newTransform;
|
||||
colour = Colours::black;
|
||||
}
|
||||
|
||||
void FillType::setOpacity (const float newOpacity) noexcept
|
||||
{
|
||||
colour = colour.withAlpha (newOpacity);
|
||||
}
|
||||
|
||||
bool FillType::isInvisible() const noexcept
|
||||
{
|
||||
return colour.isTransparent() || (gradient != nullptr && gradient->isInvisible());
|
||||
}
|
||||
|
||||
FillType FillType::transformed (const AffineTransform& t) const
|
||||
{
|
||||
FillType f (*this);
|
||||
f.transform = f.transform.followedBy (t);
|
||||
return f;
|
||||
}
|
||||
|
||||
} // namespace juce
|
156
deps/juce/modules/juce_graphics/colour/juce_FillType.h
vendored
Normal file
156
deps/juce/modules/juce_graphics/colour/juce_FillType.h
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a colour or fill pattern to use for rendering paths.
|
||||
|
||||
This is used by the Graphics and DrawablePath classes as a way to encapsulate
|
||||
a brush type. It can either be a solid colour, a gradient, or a tiled image.
|
||||
|
||||
@see Graphics::setFillType, DrawablePath::setFill
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API FillType final
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a default fill type, of solid black. */
|
||||
FillType() noexcept;
|
||||
|
||||
/** Creates a fill type of a solid colour.
|
||||
@see setColour
|
||||
*/
|
||||
FillType (Colour colour) noexcept;
|
||||
|
||||
/** Creates a gradient fill type.
|
||||
@see setGradient
|
||||
*/
|
||||
FillType (const ColourGradient& gradient);
|
||||
|
||||
/** Creates a gradient fill type.
|
||||
@see setGradient
|
||||
*/
|
||||
FillType (ColourGradient&& gradient);
|
||||
|
||||
/** Creates a tiled image fill type. The transform allows you to set the scaling, offset
|
||||
and rotation of the pattern.
|
||||
@see setTiledImage
|
||||
*/
|
||||
FillType (const Image& image, const AffineTransform& transform) noexcept;
|
||||
|
||||
/** Creates a copy of another FillType. */
|
||||
FillType (const FillType&);
|
||||
|
||||
/** Makes a copy of another FillType. */
|
||||
FillType& operator= (const FillType&);
|
||||
|
||||
/** Move constructor */
|
||||
FillType (FillType&&) noexcept;
|
||||
|
||||
/** Move assignment operator */
|
||||
FillType& operator= (FillType&&) noexcept;
|
||||
|
||||
/** Destructor. */
|
||||
~FillType() noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if this is a solid colour fill, and not a gradient or image. */
|
||||
bool isColour() const noexcept { return gradient == nullptr && image.isNull(); }
|
||||
|
||||
/** Returns true if this is a gradient fill. */
|
||||
bool isGradient() const noexcept { return gradient != nullptr; }
|
||||
|
||||
/** Returns true if this is a tiled image pattern fill. */
|
||||
bool isTiledImage() const noexcept { return image.isValid(); }
|
||||
|
||||
/** Turns this object into a solid colour fill.
|
||||
If the object was an image or gradient, those fields will no longer be valid. */
|
||||
void setColour (Colour newColour) noexcept;
|
||||
|
||||
/** Turns this object into a gradient fill. */
|
||||
void setGradient (const ColourGradient& newGradient);
|
||||
|
||||
/** Turns this object into a tiled image fill type. The transform allows you to set
|
||||
the scaling, offset and rotation of the pattern.
|
||||
*/
|
||||
void setTiledImage (const Image& image, const AffineTransform& transform) noexcept;
|
||||
|
||||
/** Changes the opacity that should be used.
|
||||
If the fill is a solid colour, this just changes the opacity of that colour. For
|
||||
gradients and image tiles, it changes the opacity that will be used for them.
|
||||
*/
|
||||
void setOpacity (float newOpacity) noexcept;
|
||||
|
||||
/** Returns the current opacity to be applied to the colour, gradient, or image.
|
||||
@see setOpacity
|
||||
*/
|
||||
float getOpacity() const noexcept { return colour.getFloatAlpha(); }
|
||||
|
||||
/** Returns true if this fill type is completely transparent. */
|
||||
bool isInvisible() const noexcept;
|
||||
|
||||
/** Returns a copy of this fill, adding the specified transform applied to the
|
||||
existing transform.
|
||||
*/
|
||||
FillType transformed (const AffineTransform& transform) const;
|
||||
|
||||
//==============================================================================
|
||||
/** The solid colour being used.
|
||||
|
||||
If the fill type is not a solid colour, the alpha channel of this colour indicates
|
||||
the opacity that should be used for the fill, and the RGB channels are ignored.
|
||||
*/
|
||||
Colour colour;
|
||||
|
||||
/** Returns the gradient that should be used for filling.
|
||||
This will be nullptr if the object is some other type of fill.
|
||||
If a gradient is active, the overall opacity with which it should be applied
|
||||
is indicated by the alpha channel of the colour variable.
|
||||
*/
|
||||
std::unique_ptr<ColourGradient> gradient;
|
||||
|
||||
/** The image that should be used for tiling.
|
||||
If an image fill is active, the overall opacity with which it should be applied
|
||||
is indicated by the alpha channel of the colour variable.
|
||||
*/
|
||||
Image image;
|
||||
|
||||
/** The transform that should be applied to the image or gradient that's being drawn. */
|
||||
AffineTransform transform;
|
||||
|
||||
//==============================================================================
|
||||
bool operator== (const FillType&) const;
|
||||
bool operator!= (const FillType&) const;
|
||||
|
||||
private:
|
||||
JUCE_LEAK_DETECTOR (FillType)
|
||||
};
|
||||
|
||||
} // namespace juce
|
740
deps/juce/modules/juce_graphics/colour/juce_PixelFormats.h
vendored
Normal file
740
deps/juce/modules/juce_graphics/colour/juce_PixelFormats.h
vendored
Normal file
@ -0,0 +1,740 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_MSVC
|
||||
#pragma pack (push, 1)
|
||||
#endif
|
||||
|
||||
class PixelRGB;
|
||||
class PixelAlpha;
|
||||
|
||||
inline uint32 maskPixelComponents (uint32 x) noexcept
|
||||
{
|
||||
return (x >> 8) & 0x00ff00ff;
|
||||
}
|
||||
|
||||
inline uint32 clampPixelComponents (uint32 x) noexcept
|
||||
{
|
||||
return (x | (0x01000100 - maskPixelComponents (x))) & 0x00ff00ff;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a 32-bit INTERNAL pixel with premultiplied alpha, and can perform compositing
|
||||
operations with it.
|
||||
|
||||
This is used internally by the imaging classes.
|
||||
|
||||
@see PixelRGB
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API PixelARGB
|
||||
{
|
||||
public:
|
||||
/** Creates a pixel without defining its colour. */
|
||||
PixelARGB() noexcept = default;
|
||||
|
||||
PixelARGB (uint8 a, uint8 r, uint8 g, uint8 b) noexcept
|
||||
{
|
||||
components.b = b;
|
||||
components.g = g;
|
||||
components.r = r;
|
||||
components.a = a;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a uint32 which represents the pixel in a platform dependent format. */
|
||||
forcedinline uint32 getNativeARGB() const noexcept { return internal; }
|
||||
|
||||
/** Returns a uint32 which will be in argb order as if constructed with the following mask operation
|
||||
((alpha << 24) | (red << 16) | (green << 8) | blue). */
|
||||
forcedinline uint32 getInARGBMaskOrder() const noexcept
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
return (uint32) ((components.a << 24) | (components.r << 16) | (components.g << 8) | (components.b << 0));
|
||||
#else
|
||||
return getNativeARGB();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
|
||||
if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
|
||||
inline uint32 getInARGBMemoryOrder() const noexcept
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return getInARGBMaskOrder();
|
||||
#else
|
||||
return (uint32) ((components.b << 24) | (components.g << 16) | (components.r << 8) | components.a);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return channels with an even index and insert zero bytes between them. This is useful for blending
|
||||
operations. The exact channels which are returned is platform dependent. */
|
||||
forcedinline uint32 getEvenBytes() const noexcept { return 0x00ff00ff & internal; }
|
||||
|
||||
/** Return channels with an odd index and insert zero bytes between them. This is useful for blending
|
||||
operations. The exact channels which are returned is platform dependent. */
|
||||
forcedinline uint32 getOddBytes() const noexcept { return 0x00ff00ff & (internal >> 8); }
|
||||
|
||||
//==============================================================================
|
||||
forcedinline uint8 getAlpha() const noexcept { return components.a; }
|
||||
forcedinline uint8 getRed() const noexcept { return components.r; }
|
||||
forcedinline uint8 getGreen() const noexcept { return components.g; }
|
||||
forcedinline uint8 getBlue() const noexcept { return components.b; }
|
||||
|
||||
//==============================================================================
|
||||
/** Copies another pixel colour over this one.
|
||||
|
||||
This doesn't blend it - this colour is simply replaced by the other one.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void set (const Pixel& src) noexcept
|
||||
{
|
||||
internal = src.getNativeARGB();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the pixel's colour from individual components. */
|
||||
void setARGB (uint8 a, uint8 r, uint8 g, uint8 b) noexcept
|
||||
{
|
||||
components.b = b;
|
||||
components.g = g;
|
||||
components.r = r;
|
||||
components.a = a;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Blends another pixel onto this one.
|
||||
|
||||
This takes into account the opacity of the pixel being overlaid, and blends
|
||||
it accordingly.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void blend (const Pixel& src) noexcept
|
||||
{
|
||||
auto rb = src.getEvenBytes();
|
||||
auto ag = src.getOddBytes();
|
||||
|
||||
const auto alpha = 0x100 - (ag >> 16);
|
||||
|
||||
rb += maskPixelComponents (getEvenBytes() * alpha);
|
||||
ag += maskPixelComponents (getOddBytes() * alpha);
|
||||
|
||||
internal = clampPixelComponents (rb) | (clampPixelComponents (ag) << 8);
|
||||
}
|
||||
|
||||
/** Blends another pixel onto this one.
|
||||
|
||||
This takes into account the opacity of the pixel being overlaid, and blends
|
||||
it accordingly.
|
||||
*/
|
||||
forcedinline void blend (PixelRGB src) noexcept;
|
||||
|
||||
|
||||
/** Blends another pixel onto this one, applying an extra multiplier to its opacity.
|
||||
|
||||
The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
|
||||
being used, so this can blend semi-transparently from a PixelRGB argument.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
|
||||
{
|
||||
auto rb = maskPixelComponents (extraAlpha * src.getEvenBytes());
|
||||
auto ag = maskPixelComponents (extraAlpha * src.getOddBytes());
|
||||
|
||||
const auto alpha = 0x100 - (ag >> 16);
|
||||
|
||||
rb += maskPixelComponents (getEvenBytes() * alpha);
|
||||
ag += maskPixelComponents (getOddBytes() * alpha);
|
||||
|
||||
internal = clampPixelComponents (rb) | (clampPixelComponents (ag) << 8);
|
||||
}
|
||||
|
||||
/** Blends another pixel with this one, creating a colour that is somewhere
|
||||
between the two, as specified by the amount.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void tween (const Pixel& src, uint32 amount) noexcept
|
||||
{
|
||||
auto dEvenBytes = getEvenBytes();
|
||||
dEvenBytes += (((src.getEvenBytes() - dEvenBytes) * amount) >> 8);
|
||||
dEvenBytes &= 0x00ff00ff;
|
||||
|
||||
auto dOddBytes = getOddBytes();
|
||||
dOddBytes += (((src.getOddBytes() - dOddBytes) * amount) >> 8);
|
||||
dOddBytes &= 0x00ff00ff;
|
||||
dOddBytes <<= 8;
|
||||
|
||||
dOddBytes |= dEvenBytes;
|
||||
internal = dOddBytes;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Replaces the colour's alpha value with another one. */
|
||||
forcedinline void setAlpha (uint8 newAlpha) noexcept
|
||||
{
|
||||
components.a = newAlpha;
|
||||
}
|
||||
|
||||
/** Multiplies the colour's alpha value with another one. */
|
||||
forcedinline void multiplyAlpha (int multiplier) noexcept
|
||||
{
|
||||
// increment alpha by 1, so that if multiplier == 255 (full alpha),
|
||||
// this function will not change the values.
|
||||
++multiplier;
|
||||
|
||||
internal = ((((uint32) multiplier) * getOddBytes()) & 0xff00ff00)
|
||||
| (((((uint32) multiplier) * getEvenBytes()) >> 8) & 0x00ff00ff);
|
||||
}
|
||||
|
||||
forcedinline void multiplyAlpha (float multiplier) noexcept
|
||||
{
|
||||
multiplyAlpha ((int) (multiplier * 255.0f));
|
||||
}
|
||||
|
||||
|
||||
inline PixelARGB getUnpremultiplied() const noexcept
|
||||
{
|
||||
PixelARGB p (internal);
|
||||
p.unpremultiply();
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Premultiplies the pixel's RGB values by its alpha. */
|
||||
forcedinline void premultiply() noexcept
|
||||
{
|
||||
const auto alpha = components.a;
|
||||
|
||||
if (alpha < 0xff)
|
||||
{
|
||||
if (alpha == 0)
|
||||
{
|
||||
components.b = 0;
|
||||
components.g = 0;
|
||||
components.r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
components.b = (uint8) ((components.b * alpha + 0x7f) >> 8);
|
||||
components.g = (uint8) ((components.g * alpha + 0x7f) >> 8);
|
||||
components.r = (uint8) ((components.r * alpha + 0x7f) >> 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Unpremultiplies the pixel's RGB values. */
|
||||
forcedinline void unpremultiply() noexcept
|
||||
{
|
||||
const auto alpha = components.a;
|
||||
|
||||
if (alpha < 0xff)
|
||||
{
|
||||
if (alpha == 0)
|
||||
{
|
||||
components.b = 0;
|
||||
components.g = 0;
|
||||
components.r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
components.b = (uint8) jmin ((uint32) 0xffu, (components.b * 0xffu) / alpha);
|
||||
components.g = (uint8) jmin ((uint32) 0xffu, (components.g * 0xffu) / alpha);
|
||||
components.r = (uint8) jmin ((uint32) 0xffu, (components.r * 0xffu) / alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forcedinline void desaturate() noexcept
|
||||
{
|
||||
if (components.a < 0xff && components.a > 0)
|
||||
{
|
||||
const auto newUnpremultipliedLevel = (0xff * ((int) components.r + (int) components.g + (int) components.b) / (3 * components.a));
|
||||
|
||||
components.r = components.g = components.b
|
||||
= (uint8) ((newUnpremultipliedLevel * components.a + 0x7f) >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
components.r = components.g = components.b
|
||||
= (uint8) (((int) components.r + (int) components.g + (int) components.b) / 3);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** The indexes of the different components in the byte layout of this type of colour. */
|
||||
#if JUCE_ANDROID
|
||||
#if JUCE_BIG_ENDIAN
|
||||
enum { indexA = 0, indexR = 3, indexG = 2, indexB = 1 };
|
||||
#else
|
||||
enum { indexA = 3, indexR = 0, indexG = 1, indexB = 2 };
|
||||
#endif
|
||||
#else
|
||||
#if JUCE_BIG_ENDIAN
|
||||
enum { indexA = 0, indexR = 1, indexG = 2, indexB = 3 };
|
||||
#else
|
||||
enum { indexA = 3, indexR = 2, indexG = 1, indexB = 0 };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
PixelARGB (uint32 internalValue) noexcept
|
||||
: internal (internalValue)
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
struct Components
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
#if JUCE_BIG_ENDIAN
|
||||
uint8 a, b, g, r;
|
||||
#else
|
||||
uint8 r, g, b, a;
|
||||
#endif
|
||||
#else
|
||||
#if JUCE_BIG_ENDIAN
|
||||
uint8 a, r, g, b;
|
||||
#else
|
||||
uint8 b, g, r, a;
|
||||
#endif
|
||||
#endif
|
||||
} JUCE_PACKED;
|
||||
|
||||
union
|
||||
{
|
||||
uint32 internal;
|
||||
Components components;
|
||||
};
|
||||
}
|
||||
#ifndef DOXYGEN
|
||||
JUCE_PACKED
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents a 24-bit RGB pixel, and can perform compositing operations on it.
|
||||
|
||||
This is used internally by the imaging classes.
|
||||
|
||||
@see PixelARGB
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API PixelRGB
|
||||
{
|
||||
public:
|
||||
/** Creates a pixel without defining its colour. */
|
||||
PixelRGB() noexcept = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
|
||||
with the native format of a PixelARGB.
|
||||
|
||||
@see PixelARGB::getNativeARGB */
|
||||
forcedinline uint32 getNativeARGB() const noexcept
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
return (uint32) ((0xffu << 24) | r | ((uint32) g << 8) | ((uint32) b << 16));
|
||||
#else
|
||||
return (uint32) ((0xffu << 24) | b | ((uint32) g << 8) | ((uint32) r << 16));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns a uint32 which will be in argb order as if constructed with the following mask operation
|
||||
((alpha << 24) | (red << 16) | (green << 8) | blue). */
|
||||
forcedinline uint32 getInARGBMaskOrder() const noexcept
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
return (uint32) ((0xffu << 24) | b | ((uint32) g << 8) | ((uint32) r << 16));
|
||||
#else
|
||||
return getNativeARGB();
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
|
||||
if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
|
||||
inline uint32 getInARGBMemoryOrder() const noexcept
|
||||
{
|
||||
#if JUCE_BIG_ENDIAN
|
||||
return getInARGBMaskOrder();
|
||||
#else
|
||||
return (uint32) ((b << 24) | (g << 16) | (r << 8) | 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return channels with an even index and insert zero bytes between them. This is useful for blending
|
||||
operations. The exact channels which are returned is platform dependent but compatible with the
|
||||
return value of getEvenBytes of the PixelARGB class.
|
||||
|
||||
@see PixelARGB::getEvenBytes */
|
||||
forcedinline uint32 getEvenBytes() const noexcept
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
return (uint32) (r | (b << 16));
|
||||
#else
|
||||
return (uint32) (b | (r << 16));
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return channels with an odd index and insert zero bytes between them. This is useful for blending
|
||||
operations. The exact channels which are returned is platform dependent but compatible with the
|
||||
return value of getOddBytes of the PixelARGB class.
|
||||
|
||||
@see PixelARGB::getOddBytes */
|
||||
forcedinline uint32 getOddBytes() const noexcept { return (uint32) 0xff0000 | g; }
|
||||
|
||||
//==============================================================================
|
||||
forcedinline uint8 getAlpha() const noexcept { return 0xff; }
|
||||
forcedinline uint8 getRed() const noexcept { return r; }
|
||||
forcedinline uint8 getGreen() const noexcept { return g; }
|
||||
forcedinline uint8 getBlue() const noexcept { return b; }
|
||||
|
||||
//==============================================================================
|
||||
/** Copies another pixel colour over this one.
|
||||
|
||||
This doesn't blend it - this colour is simply replaced by the other one.
|
||||
Because PixelRGB has no alpha channel, any alpha value in the source pixel
|
||||
is thrown away.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void set (const Pixel& src) noexcept
|
||||
{
|
||||
b = src.getBlue();
|
||||
g = src.getGreen();
|
||||
r = src.getRed();
|
||||
}
|
||||
|
||||
/** Sets the pixel's colour from individual components. */
|
||||
void setARGB (uint8, uint8 red, uint8 green, uint8 blue) noexcept
|
||||
{
|
||||
r = red;
|
||||
g = green;
|
||||
b = blue;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Blends another pixel onto this one.
|
||||
|
||||
This takes into account the opacity of the pixel being overlaid, and blends
|
||||
it accordingly.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void blend (const Pixel& src) noexcept
|
||||
{
|
||||
const auto alpha = (uint32) (0x100 - src.getAlpha());
|
||||
|
||||
// getEvenBytes returns 0x00rr00bb on non-android
|
||||
const auto rb = clampPixelComponents (src.getEvenBytes() + maskPixelComponents (getEvenBytes() * alpha));
|
||||
// getOddBytes returns 0x00aa00gg on non-android
|
||||
const auto ag = clampPixelComponents (src.getOddBytes() + ((g * alpha) >> 8));
|
||||
|
||||
g = (uint8) (ag & 0xff);
|
||||
|
||||
#if JUCE_ANDROID
|
||||
b = (uint8) (rb >> 16);
|
||||
r = (uint8) (rb & 0xff);
|
||||
#else
|
||||
r = (uint8) (rb >> 16);
|
||||
b = (uint8) (rb & 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
forcedinline void blend (PixelRGB src) noexcept
|
||||
{
|
||||
set (src);
|
||||
}
|
||||
|
||||
/** Blends another pixel onto this one, applying an extra multiplier to its opacity.
|
||||
|
||||
The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
|
||||
being used, so this can blend semi-transparently from a PixelRGB argument.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
|
||||
{
|
||||
auto ag = maskPixelComponents (extraAlpha * src.getOddBytes());
|
||||
auto rb = maskPixelComponents (extraAlpha * src.getEvenBytes());
|
||||
|
||||
const auto alpha = 0x100 - (ag >> 16);
|
||||
|
||||
ag = clampPixelComponents (ag + (g * alpha >> 8));
|
||||
rb = clampPixelComponents (rb + maskPixelComponents (getEvenBytes() * alpha));
|
||||
|
||||
g = (uint8) (ag & 0xff);
|
||||
|
||||
#if JUCE_ANDROID
|
||||
b = (uint8) (rb >> 16);
|
||||
r = (uint8) (rb & 0xff);
|
||||
#else
|
||||
r = (uint8) (rb >> 16);
|
||||
b = (uint8) (rb & 0xff);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Blends another pixel with this one, creating a colour that is somewhere
|
||||
between the two, as specified by the amount.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void tween (const Pixel& src, uint32 amount) noexcept
|
||||
{
|
||||
auto dEvenBytes = getEvenBytes();
|
||||
dEvenBytes += (((src.getEvenBytes() - dEvenBytes) * amount) >> 8);
|
||||
|
||||
auto dOddBytes = getOddBytes();
|
||||
dOddBytes += (((src.getOddBytes() - dOddBytes) * amount) >> 8);
|
||||
|
||||
g = (uint8) (dOddBytes & 0xff); // dOddBytes = 0x00aa00gg
|
||||
|
||||
#if JUCE_ANDROID
|
||||
r = (uint8) (dEvenBytes & 0xff); // dEvenBytes = 0x00bb00rr
|
||||
b = (uint8) (dEvenBytes >> 16);
|
||||
#else
|
||||
b = (uint8) (dEvenBytes & 0xff); // dEvenBytes = 0x00rr00bb
|
||||
r = (uint8) (dEvenBytes >> 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** This method is included for compatibility with the PixelARGB class. */
|
||||
forcedinline void setAlpha (uint8) noexcept {}
|
||||
|
||||
/** Multiplies the colour's alpha value with another one. */
|
||||
forcedinline void multiplyAlpha (int) noexcept {}
|
||||
|
||||
/** Multiplies the colour's alpha value with another one. */
|
||||
forcedinline void multiplyAlpha (float) noexcept {}
|
||||
|
||||
/** Premultiplies the pixel's RGB values by its alpha. */
|
||||
forcedinline void premultiply() noexcept {}
|
||||
|
||||
/** Unpremultiplies the pixel's RGB values. */
|
||||
forcedinline void unpremultiply() noexcept {}
|
||||
|
||||
forcedinline void desaturate() noexcept
|
||||
{
|
||||
r = g = b = (uint8) (((int) r + (int) g + (int) b) / 3);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** The indexes of the different components in the byte layout of this type of colour. */
|
||||
#if JUCE_MAC
|
||||
enum { indexR = 0, indexG = 1, indexB = 2 };
|
||||
#else
|
||||
enum { indexR = 2, indexG = 1, indexB = 0 };
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
PixelRGB (uint32 internal) noexcept
|
||||
{
|
||||
#if JUCE_ANDROID
|
||||
b = (uint8) (internal >> 16);
|
||||
g = (uint8) (internal >> 8);
|
||||
r = (uint8) (internal);
|
||||
#else
|
||||
r = (uint8) (internal >> 16);
|
||||
g = (uint8) (internal >> 8);
|
||||
b = (uint8) (internal);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_MAC
|
||||
uint8 r, g, b;
|
||||
#else
|
||||
uint8 b, g, r;
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifndef DOXYGEN
|
||||
JUCE_PACKED
|
||||
#endif
|
||||
;
|
||||
|
||||
forcedinline void PixelARGB::blend (PixelRGB src) noexcept
|
||||
{
|
||||
set (src);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Represents an 8-bit single-channel pixel, and can perform compositing operations on it.
|
||||
|
||||
This is used internally by the imaging classes.
|
||||
|
||||
@see PixelARGB, PixelRGB
|
||||
|
||||
@tags{Graphics}
|
||||
*/
|
||||
class JUCE_API PixelAlpha
|
||||
{
|
||||
public:
|
||||
/** Creates a pixel without defining its colour. */
|
||||
PixelAlpha() noexcept = default;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
|
||||
with the native format of a PixelARGB.
|
||||
|
||||
@see PixelARGB::getNativeARGB */
|
||||
forcedinline uint32 getNativeARGB() const noexcept { return (uint32) ((a << 24) | (a << 16) | (a << 8) | a); }
|
||||
|
||||
/** Returns a uint32 which will be in argb order as if constructed with the following mask operation
|
||||
((alpha << 24) | (red << 16) | (green << 8) | blue). */
|
||||
forcedinline uint32 getInARGBMaskOrder() const noexcept { return getNativeARGB(); }
|
||||
|
||||
/** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
|
||||
if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
|
||||
inline uint32 getInARGBMemoryOrder() const noexcept { return getNativeARGB(); }
|
||||
|
||||
/** Return channels with an even index and insert zero bytes between them. This is useful for blending
|
||||
operations. The exact channels which are returned is platform dependent but compatible with the
|
||||
return value of getEvenBytes of the PixelARGB class.
|
||||
|
||||
@see PixelARGB::getEvenBytes */
|
||||
forcedinline uint32 getEvenBytes() const noexcept { return (uint32) ((a << 16) | a); }
|
||||
|
||||
/** Return channels with an odd index and insert zero bytes between them. This is useful for blending
|
||||
operations. The exact channels which are returned is platform dependent but compatible with the
|
||||
return value of getOddBytes of the PixelARGB class.
|
||||
|
||||
@see PixelARGB::getOddBytes */
|
||||
forcedinline uint32 getOddBytes() const noexcept { return (uint32) ((a << 16) | a); }
|
||||
|
||||
//==============================================================================
|
||||
forcedinline uint8 getAlpha() const noexcept { return a; }
|
||||
forcedinline uint8 getRed() const noexcept { return 0; }
|
||||
forcedinline uint8 getGreen() const noexcept { return 0; }
|
||||
forcedinline uint8 getBlue() const noexcept { return 0; }
|
||||
|
||||
//==============================================================================
|
||||
/** Copies another pixel colour over this one.
|
||||
|
||||
This doesn't blend it - this colour is simply replaced by the other one.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void set (const Pixel& src) noexcept
|
||||
{
|
||||
a = src.getAlpha();
|
||||
}
|
||||
|
||||
/** Sets the pixel's colour from individual components. */
|
||||
forcedinline void setARGB (uint8 a_, uint8, uint8, uint8) noexcept
|
||||
{
|
||||
a = a_;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Blends another pixel onto this one.
|
||||
|
||||
This takes into account the opacity of the pixel being overlaid, and blends
|
||||
it accordingly.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void blend (const Pixel& src) noexcept
|
||||
{
|
||||
const auto srcA = src.getAlpha();
|
||||
a = (uint8) ((a * (0x100 - srcA) >> 8) + srcA);
|
||||
}
|
||||
|
||||
/** Blends another pixel onto this one, applying an extra multiplier to its opacity.
|
||||
|
||||
The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
|
||||
being used, so this can blend semi-transparently from a PixelRGB argument.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
|
||||
{
|
||||
++extraAlpha;
|
||||
const auto srcAlpha = (int) ((extraAlpha * src.getAlpha()) >> 8);
|
||||
a = (uint8) ((a * (0x100 - srcAlpha) >> 8) + srcAlpha);
|
||||
}
|
||||
|
||||
/** Blends another pixel with this one, creating a colour that is somewhere
|
||||
between the two, as specified by the amount.
|
||||
*/
|
||||
template <class Pixel>
|
||||
forcedinline void tween (const Pixel& src, uint32 amount) noexcept
|
||||
{
|
||||
a += ((src.getAlpha() - a) * amount) >> 8;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Replaces the colour's alpha value with another one. */
|
||||
forcedinline void setAlpha (uint8 newAlpha) noexcept
|
||||
{
|
||||
a = newAlpha;
|
||||
}
|
||||
|
||||
/** Multiplies the colour's alpha value with another one. */
|
||||
forcedinline void multiplyAlpha (int multiplier) noexcept
|
||||
{
|
||||
++multiplier;
|
||||
a = (uint8) ((a * multiplier) >> 8);
|
||||
}
|
||||
|
||||
forcedinline void multiplyAlpha (float multiplier) noexcept
|
||||
{
|
||||
a = (uint8) (a * multiplier);
|
||||
}
|
||||
|
||||
/** Premultiplies the pixel's RGB values by its alpha. */
|
||||
forcedinline void premultiply() noexcept {}
|
||||
|
||||
/** Unpremultiplies the pixel's RGB values. */
|
||||
forcedinline void unpremultiply() noexcept {}
|
||||
|
||||
forcedinline void desaturate() noexcept {}
|
||||
|
||||
//==============================================================================
|
||||
/** The indexes of the different components in the byte layout of this type of colour. */
|
||||
enum { indexA = 0 };
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
PixelAlpha (uint32 internal) noexcept
|
||||
: a ((uint8) (internal >> 24)) { }
|
||||
|
||||
//==============================================================================
|
||||
uint8 a;
|
||||
}
|
||||
#ifndef DOXYGEN
|
||||
JUCE_PACKED
|
||||
#endif
|
||||
;
|
||||
|
||||
#if JUCE_MSVC
|
||||
#pragma pack (pop)
|
||||
#endif
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user