Browse Source

Rework some color code

gh-pages
falkTX 10 years ago
parent
commit
ac9c0067fb
2 changed files with 159 additions and 42 deletions
  1. +15
    -7
      dgl/Color.hpp
  2. +144
    -35
      dgl/src/Color.cpp

+ 15
- 7
dgl/Color.hpp View File

@@ -48,13 +48,13 @@ struct Color {
Create a color from red, green, blue and alpha numeric values. Create a color from red, green, blue and alpha numeric values.
Values must be in [0..255] range. Values must be in [0..255] range.
*/ */
Color(const int red, const int green, const int blue, const int alpha = 255) noexcept;
Color(int red, int green, int blue, int alpha = 255) noexcept;


/** /**
Create a color from red, green, blue and alpha floating-point values. Create a color from red, green, blue and alpha floating-point values.
Values must in [0..1] range. Values must in [0..1] range.
*/ */
Color(const float red, const float green, const float blue, const float alpha = 1.0f) noexcept;
Color(float red, float green, float blue, float alpha = 1.0f) noexcept;


/** /**
Create a color by copying another color. Create a color by copying another color.
@@ -65,25 +65,33 @@ struct Color {
/** /**
Create a color by linearly interpolating two other colors. Create a color by linearly interpolating two other colors.
*/ */
Color(const Color& color1, const Color& color2, const float u) noexcept;
Color(const Color& color1, const Color& color2, float u) noexcept;


/** /**
Create a color specified by hue, saturation, lightness and alpha.
HSL values are all in [0..1] range, alpha in [0..255] range.
Create a color specified by hue, saturation and lightness.
Values must in [0..1] range.
*/ */
static Color HSL(const float hue, const float saturation, const float lightness, const int alpha = 255);
static Color fromHSL(float hue, float saturation, float lightness, float alpha = 1.0f);


/** /**
Linearly interpolate this color against another. Linearly interpolate this color against another.
*/ */
void interpolate(const Color& other, const float u) noexcept;
void interpolate(const Color& other, float u) noexcept;


/** /**
Check if this color matches another. Check if this color matches another.
@note: Comparison is forced within 8-bit color values.
*/ */
bool isEqual(const Color& color, bool withAlpha = true) noexcept;
bool isNotEqual(const Color& color, bool withAlpha = true) noexcept;
bool operator==(const Color& color) noexcept; bool operator==(const Color& color) noexcept;
bool operator!=(const Color& color) noexcept; bool operator!=(const Color& color) noexcept;


/**
Fix color bounds if needed.
*/
void fixBounds() noexcept;

/** /**
@internal @internal
Needed for NanoVG compatibility. Needed for NanoVG compatibility.


+ 144
- 35
dgl/src/Color.cpp View File

@@ -22,51 +22,66 @@ START_NAMESPACE_DGL


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


Color::Color() noexcept
: red(1.0f), green(1.0f), blue(1.0f), alpha(1.0f) {}

Color::Color(const int r, const int g, const int b, const int a) noexcept
: red(static_cast<float>(r)/255.0f), green(static_cast<float>(g)/255.0f), blue(static_cast<float>(b)/255.0f), alpha(static_cast<float>(a)/255.0f) {}

Color::Color(const float r, const float g, const float b, const float a) noexcept
: red(r), green(g), blue(b), alpha(a) {}

Color::Color(const Color& color) noexcept
: red(color.red), green(color.green), blue(color.blue), alpha(color.alpha) {}

Color::Color(const Color& color1, const Color& color2, const float u) noexcept
: red(color1.red), green(color1.green), blue(color1.blue), alpha(color1.alpha)
static void fixRange(float& value)
{ {
interpolate(color2, u);
/**/ if (value < 0.0f)
value = 0.0f;
else if (value > 1.0f)
value = 1.0f;
} }


void Color::interpolate(const Color& other, const float u) noexcept
static float getFixedRange(const float& value)
{ {
const float u2 = (u < 0.0f) ? 0.0f : ((u > 1.0f) ? 1.0f : u);
const float oneMinusU = 1.0f - u;
if (value <= 0.0f)
return 0.0f;
if (value >= 1.0f)
return 1.0f;
return value;
}


red = red * oneMinusU + other.red * u2;
green = green * oneMinusU + other.green * u2;
blue = blue * oneMinusU + other.blue * u2;
alpha = alpha * oneMinusU + other.alpha * u2;
static uchar getFixedRange2(const float& value)
{
const float value2(getFixedRange(value)*255.0f);
if (value2 <= 0.0f)
return 0;
if (value2 >= 255.0f)
return 255;
return static_cast<uchar>(value2);
} }


Color Color::HSL(const float hue, const float saturation, const float lightness, const int alpha)
// -----------------------------------------------------------------------

Color::Color() noexcept
: red(1.0f),
green(1.0f),
blue(1.0f),
alpha(1.0f) {}

Color::Color(int r, int g, int b, int a) noexcept
: red(static_cast<float>(r)/255.0f),
green(static_cast<float>(g)/255.0f),
blue(static_cast<float>(b)/255.0f),
alpha(static_cast<float>(a)/255.0f)
{ {
return nvgHSLA(hue, saturation, lightness, alpha);
fixBounds();
} }


Color::Color(const NVGcolor& c) noexcept
: red(c.r), green(c.g), blue(c.b), alpha(c.a) {}
Color::Color(float r, float g, float b, float a) noexcept
: red(r),
green(g),
blue(b),
alpha(a)
{
fixBounds();
}


Color::operator NVGcolor() const noexcept
Color::Color(const Color& color) noexcept
: red(color.red),
green(color.green),
blue(color.blue),
alpha(color.alpha)
{ {
NVGcolor nc;
nc.r = red;
nc.g = green;
nc.b = blue;
nc.a = alpha;
return nc;
fixBounds();
} }


Color& Color::operator=(const Color& color) noexcept Color& Color::operator=(const Color& color) noexcept
@@ -75,17 +90,111 @@ Color& Color::operator=(const Color& color) noexcept
green = color.green; green = color.green;
blue = color.blue; blue = color.blue;
alpha = color.alpha; alpha = color.alpha;
fixBounds();
return *this; return *this;
} }


Color::Color(const Color& color1, const Color& color2, float u) noexcept
: red(color1.red),
green(color1.green),
blue(color1.blue),
alpha(color1.alpha)
{
interpolate(color2, u);
}

Color Color::fromHSL(float hue, float saturation, float lightness, float alpha)
{
return nvgHSLA(hue, saturation, lightness, static_cast<uchar>(getFixedRange(alpha)*255.0f));
}

void Color::interpolate(const Color& other, float u) noexcept
{
fixRange(u);
const float oneMinusU(1.0f - u);

red = red * oneMinusU + other.red * u;
green = green * oneMinusU + other.green * u;
blue = blue * oneMinusU + other.blue * u;
alpha = alpha * oneMinusU + other.alpha * u;

fixBounds();
}

// -----------------------------------------------------------------------

bool Color::isEqual(const Color& color, bool withAlpha) noexcept
{
const uchar r1 = getFixedRange2(rgba[0]);
const uchar g1 = getFixedRange2(rgba[1]);
const uchar b1 = getFixedRange2(rgba[2]);
const uchar a1 = getFixedRange2(rgba[3]);

const uchar r2 = getFixedRange2(color.rgba[0]);
const uchar g2 = getFixedRange2(color.rgba[1]);
const uchar b2 = getFixedRange2(color.rgba[2]);
const uchar a2 = getFixedRange2(color.rgba[3]);

if (withAlpha)
return (r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2);
else
return (r1 == r2 && g1 == g2 && b1 == b2);
}

bool Color::isNotEqual(const Color& color, bool withAlpha) noexcept
{
const uchar r1 = getFixedRange2(rgba[0]);
const uchar g1 = getFixedRange2(rgba[1]);
const uchar b1 = getFixedRange2(rgba[2]);
const uchar a1 = getFixedRange2(rgba[3]);

const uchar r2 = getFixedRange2(color.rgba[0]);
const uchar g2 = getFixedRange2(color.rgba[1]);
const uchar b2 = getFixedRange2(color.rgba[2]);
const uchar a2 = getFixedRange2(color.rgba[3]);

if (withAlpha)
return (r1 != r2 || g1 != g2 || b1 != b2 || a1 != a2);
else
return (r1 != r2 || g1 != g2 || b1 != b2);
}

bool Color::operator==(const Color& color) noexcept bool Color::operator==(const Color& color) noexcept
{ {
return (red == color.red && green == color.green && blue == color.blue && alpha == color.alpha);
return isEqual(color, true);
} }


bool Color::operator!=(const Color& color) noexcept bool Color::operator!=(const Color& color) noexcept
{ {
return (red != color.red || green != color.green || blue != color.blue || alpha != color.alpha);
return isNotEqual(color, true);
}

// -----------------------------------------------------------------------

void Color::fixBounds() noexcept
{
fixRange(red);
fixRange(green);
fixRange(blue);
fixRange(alpha);
}

// -----------------------------------------------------------------------

Color::Color(const NVGcolor& c) noexcept
: red(c.r), green(c.g), blue(c.b), alpha(c.a)
{
fixBounds();
}

Color::operator NVGcolor() const noexcept
{
NVGcolor nc;
nc.r = red;
nc.g = green;
nc.b = blue;
nc.a = alpha;
return nc;
} }


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


Loading…
Cancel
Save