diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Brushes/Gradients/LinearGradient.cs
index c8f9227..535fe5d 100644
--- a/RGB.NET.Brushes/Gradients/LinearGradient.cs
+++ b/RGB.NET.Brushes/Gradients/LinearGradient.cs
@@ -97,10 +97,10 @@ namespace RGB.NET.Brushes.Gradients
if (!gsBefore.Offset.Equals(gsAfter.Offset))
blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));
- byte colA = (byte)(((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A);
- byte colR = (byte)(((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R);
- byte colG = (byte)(((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G);
- byte colB = (byte)(((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B);
+ double colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A;
+ double colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R;
+ double colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G;
+ double colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B;
return new Color(colA, colR, colG, colB);
}
diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Brushes/Gradients/RainbowGradient.cs
index b99a87a..01946d0 100644
--- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs
+++ b/RGB.NET.Brushes/Gradients/RainbowGradient.cs
@@ -73,10 +73,8 @@ namespace RGB.NET.Brushes.Gradients
public Color GetColor(double offset)
{
double range = EndHue - StartHue;
- double hue = (StartHue + (range * offset)) % 360f;
- if (hue < 0)
- hue += 360;
- return Color.FromHSV(hue, 1, 1);
+ double hue = StartHue + (range * offset);
+ return HSVColor.Create(hue, 1, 1);
}
///
@@ -87,7 +85,7 @@ namespace RGB.NET.Brushes.Gradients
StartHue += offset;
EndHue += offset;
-
+
while ((StartHue > 360) && (EndHue > 360))
{
StartHue -= 360;
diff --git a/RGB.NET.Core/Brushes/AbstractBrush.cs b/RGB.NET.Core/Brushes/AbstractBrush.cs
index 716cc4a..0c6591a 100644
--- a/RGB.NET.Core/Brushes/AbstractBrush.cs
+++ b/RGB.NET.Core/Brushes/AbstractBrush.cs
@@ -115,7 +115,7 @@ namespace RGB.NET.Core
// Since we use HSV to calculate there is no way to make a color 'brighter' than 100%
// Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness'
// THIS IS NOT A HSB CALCULATION!!!
- return color.MultiplyValue(Brightness.Clamp(0, 1))
+ return color.MultiplyHSV(value: Brightness.Clamp(0, 1))
.MultiplyA(Opacity.Clamp(0, 1));
}
diff --git a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs
new file mode 100644
index 0000000..e666f6f
--- /dev/null
+++ b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs
@@ -0,0 +1,80 @@
+namespace RGB.NET.Core
+{
+ public class DefaultColorBehavior : IColorBehavior
+ {
+ #region Properties & Fields
+
+ private static DefaultColorBehavior _instance = new DefaultColorBehavior();
+ ///
+ /// Gets the singleton instance of .
+ ///
+ public static DefaultColorBehavior Instance { get; } = _instance;
+
+ #endregion
+
+ #region Constructors
+
+ private DefaultColorBehavior()
+ { }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Converts the individual byte values of this to a human-readable string.
+ ///
+ /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]".
+ public virtual string ToString(Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]";
+
+ ///
+ /// Tests whether the specified object is a and is equivalent to this .
+ ///
+ /// The object to test.
+ /// true if is a equivalent to this ; otherwise, false.
+ public virtual bool Equals(Color color, object obj)
+ {
+ if (!(obj is Color)) return false;
+
+ (double a, double r, double g, double b) = ((Color)obj).GetRGB();
+ return color.A.EqualsInTolerance(a) && color.R.EqualsInTolerance(r) && color.G.EqualsInTolerance(g) && color.B.EqualsInTolerance(b);
+ }
+
+ ///
+ /// Returns a hash code for this .
+ ///
+ /// An integer value that specifies the hash code for this .
+ public virtual int GetHashCode(Color color)
+ {
+ unchecked
+ {
+ int hashCode = color.A.GetHashCode();
+ hashCode = (hashCode * 397) ^ color.R.GetHashCode();
+ hashCode = (hashCode * 397) ^ color.G.GetHashCode();
+ hashCode = (hashCode * 397) ^ color.B.GetHashCode();
+ return hashCode;
+ }
+ }
+
+ ///
+ /// Blends a over this color.
+ ///
+ /// The to blend.
+ public virtual Color Blend(Color baseColor, Color blendColor)
+ {
+ if (blendColor.A.EqualsInTolerance(0)) return baseColor;
+
+ if (blendColor.A.EqualsInTolerance(1))
+ return blendColor;
+
+ double resultA = (1.0 - ((1.0 - blendColor.A) * (1.0 - baseColor.A)));
+ double resultR = (((blendColor.R * blendColor.A) / resultA) + ((baseColor.R * baseColor.A * (1.0 - blendColor.A)) / resultA));
+ double resultG = (((blendColor.G * blendColor.A) / resultA) + ((baseColor.G * baseColor.A * (1.0 - blendColor.A)) / resultA));
+ double resultB = (((blendColor.B * blendColor.A) / resultA) + ((baseColor.B * baseColor.A * (1.0 - blendColor.A)) / resultA));
+
+ return new Color(resultA, resultR, resultG, resultB);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs
new file mode 100644
index 0000000..630aca5
--- /dev/null
+++ b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs
@@ -0,0 +1,13 @@
+namespace RGB.NET.Core
+{
+ public interface IColorBehavior
+ {
+ string ToString(Color color);
+
+ bool Equals(Color color, object obj);
+
+ int GetHashCode(Color color);
+
+ Color Blend(Color baseColor, Color blendColor);
+ }
+}
diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs
new file mode 100644
index 0000000..81a3a33
--- /dev/null
+++ b/RGB.NET.Core/Color/Color.cs
@@ -0,0 +1,288 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+// ReSharper disable UnusedMethodReturnValue.Global
+
+using System;
+using System.Diagnostics;
+
+namespace RGB.NET.Core
+{
+ ///
+ ///
+ /// Represents an ARGB (alpha, red, green, blue) color.
+ ///
+ [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")]
+ public struct Color
+ {
+ #region Constants
+
+ ///
+ /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0]
+ ///
+ public static Color Transparent => new Color(0, 0, 0, 0);
+
+ #endregion
+
+ #region Properties & Fields
+
+ private static IColorBehavior _behavior = DefaultColorBehavior.Instance;
+ ///
+ /// Gets or sets the used to perform operations on colors.
+ ///
+ public static IColorBehavior Behavior
+ {
+ get => _behavior;
+ set => _behavior = value ?? DefaultColorBehavior.Instance;
+ }
+
+ ///
+ /// Gets the alpha component value of this as percentage in the range [0..1].
+ ///
+ public double A { get; }
+
+ ///
+ /// Gets the red component value of this as percentage in the range [0..1].
+ ///
+ public double R { get; }
+
+ ///
+ /// Gets the green component value of this as percentage in the range [0..1].
+ ///
+ public double G { get; }
+
+ ///
+ /// Gets the blue component value of this as percentage in the range [0..1].
+ ///
+ public double B { get; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ ///
+ /// Initializes a new instance of the struct using RGB-Values.
+ /// Alpha defaults to 255.
+ ///
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(byte r, byte g, byte b)
+ : this(byte.MaxValue, r, g, b)
+ { }
+
+ ///
+ ///
+ /// Initializes a new instance of the struct using RGB-Values.
+ /// Alpha defaults to 255.
+ ///
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(int r, int g, int b)
+ : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(byte a, byte r, byte g, byte b)
+ : this(a.GetPercentageFromByteValue(), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue())
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(int a, int r, int g, int b)
+ : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using RGB-percent values.
+ /// Alpha defaults to 1.0.
+ ///
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(double r, double g, double b)
+ : this(1.0, r, g, b)
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB-percent values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(double a, byte r, byte g, byte b)
+ : this(a, r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue())
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB-percent values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(double a, int r, int g, int b)
+ : this(a, (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB-percent values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(int a, double r, double g, double b)
+ : this((byte)a.Clamp(0, byte.MaxValue), r, g, b)
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB-percent values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(byte a, double r, double g, double b)
+ : this(a.GetPercentageFromByteValue(), r, g, b)
+ { }
+
+ ///
+ /// Initializes a new instance of the struct using ARGB-percent values.
+ ///
+ /// The alpha component value of this .
+ /// The red component value of this .
+ /// The green component value of this .
+ /// The blue component value of this .
+ public Color(double a, double r, double g, double b)
+ {
+ A = a.Clamp(0, 1);
+ R = r.Clamp(0, 1);
+ G = g.Clamp(0, 1);
+ B = b.Clamp(0, 1);
+ }
+
+ ///
+ ///
+ /// Initializes a new instance of the struct by cloning a existing .
+ ///
+ /// The the values are copied from.
+ public Color(Color color)
+ : this(color.A, color.R, color.G, color.B)
+ { }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Gets a human-readable string, as defined by the current .
+ ///
+ /// A string that contains the individual byte values of this . Default format: "[A: 255, R: 255, G: 0, B: 0]".
+ public override string ToString() => Behavior.ToString(this);
+
+ ///
+ /// Tests whether the specified object is a and is equivalent to this , as defined by the current .
+ ///
+ /// The object to test.
+ /// true if is a equivalent to this ; otherwise, false.
+ public override bool Equals(object obj) => Behavior.Equals(this, obj);
+
+ ///
+ /// Returns a hash code for this , as defined by the current .
+ ///
+ /// An integer value that specifies the hash code for this .
+ public override int GetHashCode() => Behavior.GetHashCode(this);
+
+ ///
+ /// Blends a over this color, as defined by the current .
+ ///
+ /// The to blend.
+ public Color Blend(Color color) => Behavior.Blend(this, color);
+
+ #endregion
+
+ #region Operators
+
+ ///
+ /// Blends the provided colors as if would've been called on .
+ ///
+ /// The base color.
+ /// The color to blend.
+ /// The blended color.
+ public static Color operator +(Color color1, Color color2) => color1.Blend(color2);
+
+ ///
+ /// Returns a value that indicates whether two specified are equal.
+ ///
+ /// The first to compare.
+ /// The second to compare.
+ /// true if and are equal; otherwise, false.
+ public static bool operator ==(Color color1, Color color2) => color1.Equals(color2);
+
+ ///
+ /// Returns a value that indicates whether two specified are equal.
+ ///
+ /// The first to compare.
+ /// The second to compare.
+ /// true if and are not equal; otherwise, false.
+ public static bool operator !=(Color color1, Color color2) => !(color1 == color2);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((byte r, byte g, byte b) components) => new Color(components.r, components.g, components.b);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((int r, int g, int b) components) => new Color(components.r, components.g, components.b);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((int a, int r, int g, int b) components) => new Color(components.a, components.r, components.g, components.b);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((double r, double g, double b) components) => new Color(components.r, components.g, components.b);
+
+ ///
+ /// Converts a of ARGB-components to a .
+ ///
+ /// The containing the components.
+ /// The color.
+ public static implicit operator Color((double a, double r, double g, double b) components) => new Color(components.a, components.r, components.g, components.b);
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs
new file mode 100644
index 0000000..f99581c
--- /dev/null
+++ b/RGB.NET.Core/Color/HSVColor.cs
@@ -0,0 +1,227 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+using System;
+
+namespace RGB.NET.Core
+{
+ public static class HSVColor
+ {
+ #region Getter
+
+ ///
+ /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360].
+ ///
+ ///
+ ///
+ public static double GetHue(this Color color) => color.GetHSV().hue;
+
+ ///
+ /// Gets the saturation component value (HSV-color space) of this in the range [0..1].
+ ///
+ ///
+ ///
+ public static double GetSaturation(this Color color) => color.GetHSV().saturation;
+
+ ///
+ /// Gets the value component value (HSV-color space) of this in the range [0..1].
+ ///
+ ///
+ ///
+ public static double GetValue(this Color color) => color.GetHSV().value;
+
+ ///
+ /// Gets the hue, saturation and value component values (HSV-color space) of this .
+ /// Hue as degree in the range [0..1].
+ /// Saturation in the range [0..1].
+ /// Value in the range [0..1].
+ ///
+ ///
+ ///
+ public static (double hue, double saturation, double value) GetHSV(this Color color)
+ => CaclulateHSVFromRGB(color.R, color.G, color.B);
+
+ #endregion
+
+ #region Manipulation
+
+ ///
+ /// Adds the given HSV values to this color.
+ ///
+ /// The hue value to add.
+ /// The saturation value to add.
+ /// The value value to add.
+ /// The new color after the modification.
+ public static Color AddHSV(this Color color, double hue = 0, double saturation = 0, double value = 0)
+ {
+ (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ return Create(color.A, cHue + hue, cSaturation + saturation, cValue + value);
+ }
+
+ ///
+ /// Subtracts the given HSV values to this color.
+ ///
+ /// The hue value to subtract.
+ /// The saturation value to subtract.
+ /// The value value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractHSV(this Color color, double hue = 0, double saturation = 0, double value = 0)
+ {
+ (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ return Create(color.A, cHue - hue, cSaturation - saturation, cValue - value);
+ }
+
+ ///
+ /// Multiplies the given HSV values to this color.
+ ///
+ /// The hue value to multiply.
+ /// The saturation value to multiply.
+ /// The value value to multiply.
+ /// The new color after the modification.
+ public static Color MultiplyHSV(this Color color, double hue = 1, double saturation = 1, double value = 1)
+ {
+ (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value);
+ }
+
+ ///
+ /// Divides the given HSV values to this color.
+ ///
+ /// The hue value to divide.
+ /// The saturation value to divide.
+ /// The value value to divide.
+ /// The new color after the modification.
+ public static Color DivideHSV(this Color color, double hue = 1, double saturation = 1, double value = 1)
+ {
+ (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ return Create(color.A, cHue / hue, cSaturation / saturation, cValue / value);
+ }
+
+ ///
+ /// Sets the given hue value of this color.
+ ///
+ /// The hue value to set.
+ /// The saturation value to set.
+ /// The value value to set.
+ /// The new color after the modification.
+ public static Color SetHSV(this Color color, double? hue = null, double? saturation = null, double? value = null)
+ {
+ (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ return Create(color.A, hue ?? cHue, saturation ?? cSaturation, value ?? cValue);
+ }
+
+ #endregion
+
+ #region Factory
+
+ ///
+ /// Creates a new instance of the struct using HSV-Values.
+ ///
+ /// The hue component value of this .
+ /// The saturation component value of this .
+ /// The value component value of this .
+ /// The color created from the values.
+ public static Color Create(double hue, double saturation, double value)
+ => Create(1.0, hue, saturation, value);
+
+ ///
+ /// Creates a new instance of the struct using AHSV-Values.
+ ///
+ /// The alpha component value of this .
+ /// The hue component value of this .
+ /// The saturation component value of this .
+ /// The value component value of this .
+ /// The color created from the values.
+ public static Color Create(byte a, double hue, double saturation, double value)
+ => Create((double)a / byte.MaxValue, hue, saturation, value);
+
+ ///
+ /// Creates a new instance of the struct using AHSV-Values.
+ ///
+ /// The alpha component value of this .
+ /// The hue component value of this .
+ /// The saturation component value of this .
+ /// The value component value of this .
+ /// The color created from the values.
+ public static Color Create(int a, double hue, double saturation, double value)
+ => Create((double)a / byte.MaxValue, hue, saturation, value);
+
+ ///
+ /// Creates a new instance of the struct using AHSV-Values.
+ ///
+ /// The alpha component value of this .
+ /// The hue component value of this .
+ /// The saturation component value of this .
+ /// The value component value of this .
+ /// The color created from the values.
+ public static Color Create(double a, double hue, double saturation, double value)
+ {
+ (double r, double g, double b) = CalculateRGBFromHSV(hue, saturation, value);
+ return new Color(a, r, g, b);
+ }
+
+ #endregion
+
+ #region Helper
+
+ private static (double h, double s, double v) CaclulateHSVFromRGB(double r, double g, double b)
+ {
+ if (r.EqualsInTolerance(g) && g.EqualsInTolerance(b)) return (0, 0, r);
+
+ double min = Math.Min(Math.Min(r, g), b);
+ double max = Math.Max(Math.Max(r, g), b);
+
+ double hue;
+ if (max.EqualsInTolerance(min))
+ hue = 0;
+ else if (max.EqualsInTolerance(r)) // r is max
+ hue = (g - b) / (max - min);
+ else if (max.EqualsInTolerance(g)) // g is max
+ hue = 2.0 + ((b - r) / (max - min));
+ else // b is max
+ hue = 4.0 + ((r - g) / (max - min));
+
+ hue = hue * 60.0;
+ hue = hue.Wrap(0, 360);
+
+ double saturation = max.EqualsInTolerance(0) ? 0 : 1.0 - (min / max);
+ double value = Math.Max(r, Math.Max(g, b));
+
+ return (hue, saturation, value);
+ }
+
+ private static (double r, double g, double b) CalculateRGBFromHSV(double h, double s, double v)
+ {
+ h = h.Wrap(0, 360);
+ s = s.Clamp(0, 1);
+ v = v.Clamp(0, 1);
+
+ if (s <= 0.0)
+ return (v, v, v);
+
+ double hh = h / 60.0;
+ int i = (int)hh;
+ double ff = hh - i;
+ double p = v * (1.0 - s);
+ double q = v * (1.0 - (s * ff));
+ double t = v * (1.0 - (s * (1.0 - ff)));
+
+ switch (i)
+ {
+ case 0:
+ return (v, t, p);
+ case 1:
+ return (q, v, p);
+ case 2:
+ return (p, v, t);
+ case 3:
+ return (p, q, v);
+ case 4:
+ return (t, p, v);
+ default:
+ return (v, p, q);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs
new file mode 100644
index 0000000..b196076
--- /dev/null
+++ b/RGB.NET.Core/Color/RGBColor.cs
@@ -0,0 +1,275 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+using System;
+
+namespace RGB.NET.Core
+{
+ public static class RGBColor
+ {
+ #region Getter
+
+ ///
+ /// Gets the A component value of this as byte in the range [0..255].
+ ///
+ ///
+ ///
+ public static byte GetA(this Color color) => color.A.GetByteValueFromPercentage();
+
+ ///
+ /// Gets the R component value of this as byte in the range [0..255].
+ ///
+ ///
+ ///
+ public static byte GetR(this Color color) => color.R.GetByteValueFromPercentage();
+
+ ///
+ /// Gets the G component value of this as byte in the range [0..255].
+ ///
+ ///
+ ///
+ public static byte GetG(this Color color) => color.G.GetByteValueFromPercentage();
+
+ ///
+ /// Gets the B component value of this as byte in the range [0..255].
+ ///
+ ///
+ ///
+ public static byte GetB(this Color color) => color.B.GetByteValueFromPercentage();
+
+ ///
+ /// Gets the A, R, G and B component value of this as byte in the range [0..255].
+ ///
+ ///
+ ///
+ public static (byte a, byte r, byte g, byte b) GetRGBBytes(this Color color)
+ => (color.GetA(), color.GetR(), color.GetG(), color.GetB());
+
+ ///
+ /// Gets the A, R, G and B component value of this as percentage in the range [0..1].
+ ///
+ ///
+ ///
+ public static (double a, double r, double g, double b) GetRGB(this Color color)
+ => (color.A, color.R, color.G, color.B);
+
+ #endregion
+
+ #region Manipulation
+
+ #region Add
+
+ ///
+ /// Adds the given RGB values to this color.
+ ///
+ /// The red value to add.
+ /// The green value to add.
+ /// The blue value to add.
+ /// The new color after the modification.
+ public static Color AddRGB(this Color color, int r = 0, int g = 0, int b = 0)
+ => new Color(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b);
+
+ ///
+ /// Adds the given RGB-percent values to this color.
+ ///
+ /// The red value to add.
+ /// The green value to add.
+ /// The blue value to add.
+ /// The new color after the modification.
+ public static Color AddRGB(this Color color, double r = 0, double g = 0, double b = 0)
+ => new Color(color.A, color.R + r, color.G + g, color.B + b);
+
+ ///
+ /// Adds the given alpha value to this color.
+ ///
+ /// The alpha value to add.
+ /// The new color after the modification.
+ public static Color AddA(this Color color, int a)
+ => new Color(color.GetA() + a, color.R, color.G, color.B);
+
+ ///
+ /// Adds the given alpha-percent value to this color.
+ ///
+ /// The alpha value to add.
+ /// The new color after the modification.
+ public static Color AddA(this Color color, double a)
+ => new Color(color.A + a, color.R, color.G, color.B);
+
+ #endregion
+
+ #region Subtract
+
+ ///
+ /// Subtracts the given RGB values to this color.
+ ///
+ /// The red value to subtract.
+ /// The green value to subtract.
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractRGB(this Color color, int r = 0, int g = 0, int b = 0)
+ => new Color(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b);
+
+ ///
+ /// Subtracts the given RGB values to this color.
+ ///
+ /// The red value to subtract.
+ /// The green value to subtract.
+ /// The blue value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractRGB(this Color color, double r = 0, double g = 0, double b = 0)
+ => new Color(color.A, color.R - r, color.G - g, color.B - b);
+
+ ///
+ /// Subtracts the given alpha value to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractA(this Color color, int a)
+ => new Color(color.GetA() - a, color.R, color.G, color.B);
+
+ ///
+ /// Subtracts the given alpha-percent value to this color.
+ ///
+ /// The alpha value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractA(this Color color, double aPercent)
+ => new Color(color.A - aPercent, color.R, color.G, color.B);
+
+ #endregion
+
+ #region Multiply
+
+ ///
+ /// Multiplies the given RGB values to this color.
+ ///
+ /// The red value to multiply.
+ /// The green value to multiply.
+ /// The blue value to multiply.
+ /// The new color after the modification.
+ public static Color MultiplyRGB(this Color color, double r = 1, double g = 1, double b = 1)
+ => new Color(color.A, color.R * r, color.G * g, color.B * b);
+
+ ///
+ /// Multiplies the given alpha value to this color.
+ ///
+ /// The alpha value to multiply.
+ /// The new color after the modification.
+ public static Color MultiplyA(this Color color, double a)
+ => new Color(color.A * a, color.R, color.G, color.B);
+
+ #endregion
+
+ #region Divide
+
+ ///
+ /// Divides the given RGB values to this color.
+ ///
+ /// The red value to divide.
+ /// The green value to divide.
+ /// The blue value to divide.
+ /// The new color after the modification.
+ public static Color DivideRGB(this Color color, double r = 1, double g = 1, double b = 1)
+ => new Color(color.A, color.R / r, color.G / g, color.B / b);
+
+ ///
+ /// Divides the given alpha value to this color.
+ ///
+ /// The alpha value to divide.
+ /// The new color after the modification.
+ public static Color DivideA(this Color color, double a)
+ => new Color(color.A / a, color.R, color.G, color.B);
+
+ #endregion
+
+ #region Set
+
+ ///
+ /// Sets the given RGB value of this color.
+ ///
+ /// The red value to set.
+ /// The green value to set.
+ /// The blue value to set.
+ /// The new color after the modification.
+ public static Color SetRGB(this Color color, byte? r = null, byte? g = null, byte? b = null)
+ => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB());
+
+ ///
+ /// Sets the given RGB value of this color.
+ ///
+ /// The red value to set.
+ /// The green value to set.
+ /// The blue value to set.
+ /// The new color after the modification.
+ public static Color SetRGB(this Color color, int? r = null, int? g = null, int? b = null)
+ => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB());
+
+ ///
+ /// Sets the given RGB value of this color.
+ ///
+ /// The red value to set.
+ /// The green value to set.
+ /// The blue value to set.
+ /// The new color after the modification.
+ public static Color SetRGB(this Color color, double? r = null, double? g = null, double? b = null)
+ => new Color(color.A, r ?? color.R, g ?? color.G, b ?? color.B);
+
+ ///
+ /// Sets the given alpha value of this color.
+ ///
+ /// The alpha value to set.
+ /// The new color after the modification.
+ public static Color SetA(this Color color, int a) => new Color(a, color.R, color.G, color.B);
+
+ ///
+ /// Sets the given alpha value of this color.
+ ///
+ /// The alpha value to set.
+ /// The new color after the modification.
+ public static Color SetA(this Color color, double a) => new Color(a, color.R, color.G, color.B);
+
+ #endregion
+
+ #endregion
+
+ #region Conversion
+
+ ///
+ /// Gets the current color as a RGB-HEX-string.
+ ///
+ /// The RGB-HEX-string.
+ public static string AsRGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetR(), color.GetG(), color.GetB());
+
+ ///
+ /// Gets the current color as a ARGB-HEX-string.
+ ///
+ /// The ARGB-HEX-string.
+ public static string AsARGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetA(), color.GetR(), color.GetG(), color.GetB());
+
+ #endregion
+
+ #region Factory
+
+ ///
+ /// Creates a new instance of the struct using a HEX-string.
+ ///
+ /// The HEX-representation of the color.
+ /// The color created from the HEX-string.
+ public static Color FromHexString(string hexString)
+ {
+ if ((hexString == null) || (hexString.Length < 6))
+ throw new ArgumentException("Invalid hex string", nameof(hexString));
+
+ if (hexString[0] == '#')
+ hexString = hexString.Substring(1);
+
+ byte[] data = ConversionHelper.HexToBytes(hexString);
+ if (data.Length == 3)
+ return new Color(data[0], data[1], data[2]);
+ if (data.Length == 4)
+ return new Color(data[0], data[1], data[2], data[3]);
+
+ throw new ArgumentException("Invalid hex string", nameof(hexString));
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Extensions/MathExtensions.cs b/RGB.NET.Core/Extensions/MathExtensions.cs
index 415a53c..0a9fb88 100644
--- a/RGB.NET.Core/Extensions/MathExtensions.cs
+++ b/RGB.NET.Core/Extensions/MathExtensions.cs
@@ -36,7 +36,14 @@ namespace RGB.NET.Core
/// The higher value of the range the value is clamped to.
/// The clamped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double Clamp(this double value, double min, double max) => Math.Max(min, Math.Min(max, value));
+ public static double Clamp(this double value, double min, double max)
+ {
+ // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10%
+ if (value < min) return min;
+ if (value > max) return max;
+ return value;
+ // ReSharper restore ConvertIfStatementToReturnStatement
+ }
///
/// Clamps the provided value to be bigger or equal min and smaller or equal max.
@@ -46,7 +53,14 @@ namespace RGB.NET.Core
/// The higher value of the range the value is clamped to.
/// The clamped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static int Clamp(this int value, int min, int max) => Math.Max(min, Math.Min(max, value));
+ public static int Clamp(this int value, int min, int max)
+ {
+ // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10%
+ if (value < min) return min;
+ if (value > max) return max;
+ return value;
+ // ReSharper restore ConvertIfStatementToReturnStatement
+ }
///
/// Enforces the provided value to be in the specified range by wrapping it around the edges if it exceeds them.
@@ -68,16 +82,20 @@ namespace RGB.NET.Core
return value;
}
-
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte GetByteValueFromPercentage(this double percentage)
{
if (double.IsNaN(percentage)) return 0;
percentage = percentage.Clamp(0, 1.0);
- return (byte)(percentage.Equals(1.0) ? 255 : percentage * 256.0);
+ return (byte)(percentage >= 1.0 ? 255 : percentage * 256.0);
}
-
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double GetPercentageFromByteValue(this byte value)
+ => ((double)value) / byte.MaxValue;
+
#endregion
}
}
diff --git a/RGB.NET.Core/Leds/Color.cs b/RGB.NET.Core/Leds/Color.cs
deleted file mode 100644
index cc2208d..0000000
--- a/RGB.NET.Core/Leds/Color.cs
+++ /dev/null
@@ -1,1124 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-// ReSharper disable UnusedMember.Global
-// ReSharper disable UnusedMethodReturnValue.Global
-
-using System;
-using System.Diagnostics;
-
-namespace RGB.NET.Core
-{
- ///
- ///
- /// Represents an ARGB (alpha, red, green, blue) color.
- ///
- [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]")]
- public struct Color
- {
- #region Constants
-
- ///
- /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0]
- ///
- public static Color Transparent => new Color(0, 0, 0, 0);
-
- #endregion
-
- #region Properties & Fields
-
- #region RGB
-
- ///
- /// Gets the alpha component value of this as byte in the range [0..255].
- ///
- public byte A { get; }
-
- ///
- /// Gets the alpha component value of this as percentage in the range [0..1].
- ///
- public double APercent => A / (double)byte.MaxValue;
-
- ///
- /// Gets the red component value of this as byte in the range [0..255].
- ///
- public byte R { get; }
-
- ///
- /// Gets the red component value of this as percentage in the range [0..1].
- ///
- public double RPercent => R / (double)byte.MaxValue;
-
- ///
- /// Gets the green component value of this as byte in the range [0..255].
- ///
- public byte G { get; }
-
- ///
- /// Gets the green component value of this as percentage in the range [0..1].
- ///
- public double GPercent => G / (double)byte.MaxValue;
-
- ///
- /// Gets the blue component value of this as byte in the range [0..255].
- ///
- public byte B { get; }
-
- ///
- /// Gets the blue component value of this as percentage in the range [0..1].
- ///
- public double BPercent => B / (double)byte.MaxValue;
-
- #endregion
-
- #region HSV
-
- ///
- /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360].
- ///
- public double Hue { get; }
-
- ///
- /// Gets the saturation component value (HSV-color space) of this as degree in the range [0..1].
- ///
- public double Saturation { get; }
-
- ///
- /// Gets the value component value (HSV-color space) of this as degree in the range [0..1].
- ///
- public double Value { get; }
-
- #endregion
-
- #endregion
-
- #region Constructors
-
- ///
- ///
- /// Initializes a new instance of the struct using RGB-Values.
- /// Alpha defaults to 255.
- ///
- /// The red component value of this .
- /// The green component value of this .
- /// The blue component value of this .
- public Color(byte r, byte g, byte b)
- : this(byte.MaxValue, r, g, b)
- { }
-
- ///
- ///
- /// Initializes a new instance of the struct using RGB-Values.
- /// Alpha defaults to 255.
- ///
- /// The red component value of this .
- /// The green component value of this .
- /// The blue component value of this .
- public Color(int r, int g, int b)
- : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
- { }
-
- ///
- /// Initializes a new instance of the struct using ARGB values.
- ///
- /// The alpha component value of this .
- /// The red component value of this .
- /// The green component value of this .
- /// The blue component value of this .
- public Color(byte a, byte r, byte g, byte b)
- {
- this.A = a;
- this.R = r;
- this.G = g;
- this.B = b;
-
- (double h, double s, double v) = CaclulateHSVFromRGB(r, g, b);
- Hue = h;
- Saturation = s;
- Value = v;
- }
-
- ///
- /// Initializes a new instance of the struct using ARGB values.
- ///
- /// The alpha component value of this .
- /// The red component value of this .
- /// The green component value of this .
- /// The blue component value of this .
- public Color(int a, int r, int g, int b)
- : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
- { }
-
- ///
- /// Initializes a new instance of the struct using RGB-percent values.
- ///
- /// The red component value of this .
- /// The green component value of this .
- /// The blue component value of this .
- public Color(double r, double g, double b)
- : this(byte.MaxValue,
- r.GetByteValueFromPercentage(),
- g.GetByteValueFromPercentage(),
- b.GetByteValueFromPercentage())
- { }
-
- ///
- /// Initializes a new instance of the struct using ARGB-percent values.
- ///
- /// The alpha component value of this .
- /// The red component value of this .
- /// The green component value of this .
- /// The blue component value of this .
- public Color(double a, double r, double g, double b)
- : this(a.GetByteValueFromPercentage(),
- r.GetByteValueFromPercentage(),
- g.GetByteValueFromPercentage(),
- b.GetByteValueFromPercentage())
- { }
-
- ///
- ///
- /// Initializes a new instance of the struct by cloning a existing .
- ///
- /// The the values are copied from.
- public Color(Color color)
- : this(color.A, color.R, color.G, color.B) { }
-
- #endregion
-
- #region Methods
-
- #region Factory
-
- ///
- /// Creates a new instance of the struct using HSV-Values.
- ///
- /// The hue component value of this .
- /// The saturation component value of this .
- /// The value component value of this .
- /// The color created from the values.
- public static Color FromHSV(double hue, double saturation, double value)
- {
- (byte r, byte g, byte b) = CalculateRGBFromHSV(hue, saturation, value);
- return new Color(r, g, b);
- }
-
- ///
- /// Creates a new instance of the struct using AHSV-Values.
- ///
- /// The alpha component value of this .
- /// The hue component value of this .
- /// The saturation component value of this .
- /// The value component value of this .
- /// The color created from the values.
- public static Color FromHSV(int a, double hue, double saturation, double value)
- {
- (byte r, byte g, byte b) = CalculateRGBFromHSV(hue, saturation, value);
- return new Color(a, r, g, b);
- }
-
- ///
- /// Creates a new instance of the struct using a HEX-string.
- ///
- /// The HEX-representation of the color.
- /// The color created from the HEX-string.
- public static Color FromHexString(string hexString)
- {
- if ((hexString == null) || (hexString.Length < 6))
- throw new ArgumentException("Invalid hex string", nameof(hexString));
-
- if (hexString[0] == '#')
- hexString = hexString.Substring(1);
-
- byte[] data = ConversionHelper.HexToBytes(hexString);
- if (data.Length == 3)
- return new Color(data[0], data[1], data[2]);
- if (data.Length == 4)
- return new Color(data[0], data[1], data[2], data[3]);
-
- throw new ArgumentException("Invalid hex string", nameof(hexString));
- }
-
- #endregion
-
- private static (double h, double s, double v) CaclulateHSVFromRGB(byte r, byte g, byte b)
- {
- if ((r == g) && (g == b)) return (0, 0, r / 255.0);
-
- int min = Math.Min(Math.Min(r, g), b);
- int max = Math.Max(Math.Max(r, g), b);
-
- double hue;
- if (max == min)
- hue = 0;
- else if (max == r) // r is max
- hue = (g - b) / (double)(max - min);
- else if (max == g) // g is max
- hue = 2.0 + ((b - r) / (double)(max - min));
- else // b is max
- hue = 4.0 + ((r - g) / (double)(max - min));
-
- hue = hue * 60.0;
- if (hue < 0.0)
- hue += 360.0;
-
- double saturation = (max == 0) ? 0 : 1.0 - (min / (double)max);
- double value = Math.Max(r, Math.Max(g, b)) / 255.0;
-
- return (hue, saturation, value);
- }
-
- private static (byte r, byte g, byte b) CalculateRGBFromHSV(double h, double s, double v)
- {
- h = h.Wrap(0, 360);
- s = s.Clamp(0, 1);
- v = v.Clamp(0, 1);
-
- if (s <= 0.0)
- {
- byte val = v.GetByteValueFromPercentage();
- return (val, val, val);
- }
-
- double hh = h / 60.0;
- int i = (int)hh;
- double ff = hh - i;
- double p = v * (1.0 - s);
- double q = v * (1.0 - (s * ff));
- double t = v * (1.0 - (s * (1.0 - ff)));
-
- switch (i)
- {
- case 0:
- return (v.GetByteValueFromPercentage(),
- t.GetByteValueFromPercentage(),
- p.GetByteValueFromPercentage());
- case 1:
- return (q.GetByteValueFromPercentage(),
- v.GetByteValueFromPercentage(),
- p.GetByteValueFromPercentage());
- case 2:
- return (p.GetByteValueFromPercentage(),
- v.GetByteValueFromPercentage(),
- t.GetByteValueFromPercentage());
- case 3:
- return (p.GetByteValueFromPercentage(),
- q.GetByteValueFromPercentage(),
- v.GetByteValueFromPercentage());
- case 4:
- return (t.GetByteValueFromPercentage(),
- p.GetByteValueFromPercentage(),
- v.GetByteValueFromPercentage());
- default:
- return (v.GetByteValueFromPercentage(),
- p.GetByteValueFromPercentage(),
- q.GetByteValueFromPercentage());
- }
- }
-
- ///
- /// Converts the individual byte values of this to a human-readable string.
- ///
- /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]".
- public override string ToString() => $"[A: {A}, R: {R}, G: {G}, B: {B}, H: {Hue}, S: {Saturation}, V: {Value}]";
-
- ///
- /// Tests whether the specified object is a and is equivalent to this .
- ///
- /// The object to test.
- /// true if is a equivalent to this ; otherwise, false.
- public override bool Equals(object obj)
- {
- if (!(obj is Color)) return false;
-
- Color compareColor = (Color)obj;
- return (compareColor.A == A) && (compareColor.R == R) && (compareColor.G == G) && (compareColor.B == B);
- }
-
- ///
- /// Returns a hash code for this .
- ///
- /// An integer value that specifies the hash code for this .
- public override int GetHashCode()
- {
- unchecked
- {
- int hashCode = A.GetHashCode();
- hashCode = (hashCode * 397) ^ R.GetHashCode();
- hashCode = (hashCode * 397) ^ G.GetHashCode();
- hashCode = (hashCode * 397) ^ B.GetHashCode();
- return hashCode;
- }
- }
-
- ///
- /// Gets the current color as a RGB-HEX-string.
- ///
- /// The RGB-HEX-string.
- public string AsRGBHexString() => ConversionHelper.ToHex(R, G, B);
-
- ///
- /// Gets the current color as a ARGB-HEX-string.
- ///
- /// The ARGB-HEX-string.
- public string AsARGBHexString() => ConversionHelper.ToHex(A, R, G, B);
-
- #region Deconstruction
-
- ///
- /// Deconstructs the Color into it's components.
- ///
- /// The alpha component of this color.
- /// The red component of this color.
- /// The green component of this color.
- /// The blue component of this color.
- /// The hue component of this color.
- /// The saturation component of this color.
- /// The value component of this color.
- public void Deconstruct(out byte a, out byte r, out byte g, out byte b, out double hue, out double saturation, out double value)
- {
- Deconstruct(out a, out r, out g, out b);
- Deconstruct(out hue, out saturation, out value);
- }
-
- ///
- /// Deconstructs the Color into it's ARGB-components.
- ///
- /// The alpha component of this color.
- /// The red component of this color.
- /// The green component of this color.
- /// The blue component of this color.
- public void Deconstruct(out byte a, out byte r, out byte g, out byte b)
- {
- a = A;
- r = R;
- g = G;
- b = B;
- }
-
- ///
- /// Deconstructs the Color into it's HSV-components.
- ///
- /// The hue component of this color.
- /// The saturation component of this color.
- /// The value component of this color.
- public void Deconstruct(out double hue, out double saturation, out double value)
- {
- hue = Hue;
- saturation = Saturation;
- value = Value;
- }
-
- #endregion
-
- #region Manipulation
-
- ///
- /// Blends a over this color.
- ///
- /// The to blend.
- public Color Blend(Color color)
- {
- if (color.A == 0) return this;
-
- if (color.A == 255)
- return color;
-
- double resultA = (1.0 - ((1.0 - color.APercent) * (1.0 - APercent)));
- double resultR = (((color.RPercent * color.APercent) / resultA) + ((RPercent * APercent * (1.0 - color.APercent)) / resultA));
- double resultG = (((color.GPercent * color.APercent) / resultA) + ((GPercent * APercent * (1.0 - color.APercent)) / resultA));
- double resultB = (((color.BPercent * color.APercent) / resultA) + ((BPercent * APercent * (1.0 - color.APercent)) / resultA));
-
- return new Color(resultA, resultR, resultG, resultB);
- }
-
- #region Add
-
- ///
- /// Adds the given RGB values to this color.
- ///
- /// The red value to add.
- /// The green value to add.
- /// The blue value to add.
- /// The new color after the modification.
- public Color AddRGB(int r, int g, int b) => AddRGB(0, r, g, b);
-
- ///
- /// Adds the given RGB values to this color.
- ///
- /// The alpha value to add.
- /// The red value to add.
- /// The green value to add.
- /// The blue value to add.
- /// The new color after the modification.
- public Color AddRGB(int a, int r, int g, int b)
- => new Color(A + a, R + r, G + g, B + b);
-
- ///
- /// Adds the given RGB-percent values to this color.
- ///
- /// The red value to add.
- /// The green value to add.
- /// The blue value to add.
- /// The new color after the modification.
- public Color AddPercent(double rPercent, double gPercent, double bPercent) => AddPercent(0, rPercent, gPercent, bPercent);
-
- ///
- /// Adds the given RGB-percent values to this color.
- ///
- /// The alpha value to add.
- /// The red value to add.
- /// The green value to add.
- /// The blue value to add.
- /// The new color after the modification.
- public Color AddPercent(double aPercent, double rPercent, double gPercent, double bPercent)
- => new Color(APercent + aPercent, RPercent + rPercent, GPercent + gPercent, BPercent + bPercent);
-
- ///
- /// Adds the given HSV values to this color.
- ///
- /// The hue value to add.
- /// The saturation value to add.
- /// The value value to add.
- /// The new color after the modification.
- public Color AddHSV(double hue, double saturation, double value) => AddHSV(0, hue, saturation, value);
-
- ///
- /// Adds the given HSV values to this color.
- ///
- /// The alpha value to add.
- /// The hue value to add.
- /// The saturation value to add.
- /// The value value to add.
- /// The new color after the modification.
- public Color AddHSV(int a, double hue, double saturation, double value)
- => FromHSV(A + a, Hue + hue, Saturation + saturation, Value + value);
-
- ///
- /// Adds the given alpha value to this color.
- ///
- /// The alpha value to add.
- /// The new color after the modification.
- public Color AddA(int a) => new Color(A + a, R, G, B);
-
- ///
- /// Adds the given alpha-percent value to this color.
- ///
- /// The alpha value to add.
- /// The new color after the modification.
- public Color AddAPercent(double aPercent) => new Color(APercent + aPercent, RPercent, GPercent, BPercent);
-
- ///
- /// Adds the given red value to this color.
- ///
- /// The red value to add.
- /// The new color after the modification.
- public Color AddR(int r) => new Color(A, R + r, G, B);
-
- ///
- /// Adds the given red-percent value to this color.
- ///
- /// The red value to add.
- /// The new color after the modification.
- public Color AddRPercent(double rPercent) => new Color(APercent, RPercent + rPercent, GPercent, BPercent);
-
- ///
- /// Adds the given green value to this color.
- ///
- /// The green value to add.
- /// The new color after the modification.
- public Color AddG(int g) => new Color(A, R, G + g, B);
-
- ///
- /// Adds the given green-percent value to this color.
- ///
- /// The green value to add.
- /// The new color after the modification.
- public Color AddGPercent(double gPercent) => new Color(APercent, RPercent, GPercent + gPercent, BPercent);
-
- ///
- /// Adds the given blue value to this color.
- ///
- /// The blue value to add.
- /// The new color after the modification.
- public Color AddB(int b) => new Color(A, R, G, B + b);
-
- ///
- /// Adds the given blue-percent value to this color.
- ///
- /// The blue value to add.
- /// The new color after the modification.
- public Color AddBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent + bPercent);
-
- ///
- /// Adds the given hue value to this color.
- ///
- /// The hue value to add.
- /// The new color after the modification.
- public Color AddHue(double hue) => FromHSV(A, Hue + hue, Saturation, Value);
-
- ///
- /// Adds the given saturation value to this color.
- ///
- /// The saturation value to add.
- /// The new color after the modification.
- public Color AddSaturation(double saturation) => FromHSV(A, Hue, Saturation + saturation, Value);
-
- ///
- /// Adds the given value value to this color.
- ///
- /// The value value to add.
- /// The new color after the modification.
- public Color AddValue(double value) => FromHSV(A, Hue, Saturation, Value + value);
-
- #endregion
-
- #region Subtract
-
- ///
- /// Subtracts the given RGB values to this color.
- ///
- /// The red value to subtract.
- /// The green value to subtract.
- /// The blue value to subtract.
- /// The new color after the modification.
- public Color SubtractRGB(int r, int g, int b) => SubtractRGB(0, r, g, b);
-
- ///
- /// Subtracts the given RGB values to this color.
- ///
- /// The alpha value to subtract.
- /// The red value to subtract.
- /// The green value to subtract.
- /// The blue value to subtract.
- /// The new color after the modification.
- public Color SubtractRGB(int a, int r, int g, int b)
- => new Color(A - a, R - r, G - g, B - b);
-
- ///
- /// Subtracts the given RGB-percent values to this color.
- ///
- /// The red value to subtract.
- /// The green value to subtract.
- /// The blue value to subtract.
- /// The new color after the modification.
- public Color SubtractPercent(double rPercent, double gPercent, double bPercent) => SubtractPercent(0, rPercent, gPercent, bPercent);
-
- ///
- /// Subtracts the given RGB-percent values to this color.
- ///
- /// The alpha value to subtract.
- /// The red value to subtract.
- /// The green value to subtract.
- /// The blue value to subtract.
- /// The new color after the modification.
- public Color SubtractPercent(double aPercent, double rPercent, double gPercent, double bPercent)
- => new Color(APercent - aPercent, RPercent - rPercent, GPercent - gPercent, BPercent - bPercent);
-
- ///
- /// Subtracts the given HSV values to this color.
- ///
- /// The hue value to subtract.
- /// The saturation value to subtract.
- /// The value value to subtract.
- /// The new color after the modification.
- public Color SubtractHSV(double hue, double saturation, double value) => SubtractHSV(0, hue, saturation, value);
-
- ///
- /// Subtracts the given HSV values to this color.
- ///
- /// The alpha value to subtract.
- /// The hue value to subtract.
- /// The saturation value to subtract.
- /// The value value to subtract.
- /// The new color after the modification.
- public Color SubtractHSV(int a, double hue, double saturation, double value)
- => FromHSV(A - a, Hue - hue, Saturation - saturation, Value - value);
-
- ///
- /// Subtracts the given alpha value to this color.
- ///
- /// The alpha value to subtract.
- /// The new color after the modification.
- public Color SubtractA(int a) => new Color(A - a, R, G, B);
-
- ///
- /// Subtracts the given alpha-percent value to this color.
- ///
- /// The alpha value to subtract.
- /// The new color after the modification.
- public Color SubtractAPercent(double aPercent) => new Color(APercent - aPercent, RPercent, GPercent, BPercent);
-
- ///
- /// Subtracts the given red value to this color.
- ///
- /// The red value to subtract.
- /// The new color after the modification.
- public Color SubtractR(int r) => new Color(A, R - r, G, B);
-
- ///
- /// Subtracts the given red-percent value to this color.
- ///
- /// The red value to subtract.
- /// The new color after the modification.
- public Color SubtractRPercent(double rPercent) => new Color(APercent, RPercent - rPercent, GPercent, BPercent);
-
- ///
- /// Subtracts the given green value to this color.
- ///
- /// The green value to subtract.
- /// The new color after the modification.
- public Color SubtractG(int g) => new Color(A, R, G - g, B);
-
- ///
- /// Subtracts the given green-percent value to this color.
- ///
- /// The green value to subtract.
- /// The new color after the modification.
- public Color SubtractGPercent(double gPercent) => new Color(APercent, RPercent, GPercent - gPercent, BPercent);
-
- ///
- /// Subtracts the given blue value to this color.
- ///
- /// The blue value to subtract.
- /// The new color after the modification.
- public Color SubtractB(int b) => new Color(A, R, G, B - b);
-
- ///
- /// Subtracts the given blue-percent value to this color.
- ///
- /// The blue value to subtract.
- /// The new color after the modification.
- public Color SubtractBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent - bPercent);
-
- ///
- /// Subtracts the given hue value to this color.
- ///
- /// The hue value to subtract.
- /// The new color after the modification.
- public Color SubtractHue(double hue) => FromHSV(A, Hue - hue, Saturation, Value);
-
- ///
- /// Subtracts the given saturation value to this color.
- ///
- /// The saturation value to subtract.
- /// The new color after the modification.
- public Color SubtractSaturation(double saturation) => FromHSV(A, Hue, Saturation - saturation, Value);
-
- ///
- /// Subtracts the given value value to this color.
- ///
- /// The value value to subtract.
- /// The new color after the modification.
- public Color SubtractValue(double value) => FromHSV(A, Hue, Saturation, Value - value);
-
- #endregion
-
- #region Multiply
-
- ///
- /// Multiplies the given RGB values to this color.
- ///
- /// The red value to multiply.
- /// The green value to multiply.
- /// The blue value to multiply.
- /// The new color after the modification.
- public Color MultiplyRGB(double r, double g, double b) => MultiplyRGB(1, r, g, b);
-
- ///
- /// Multiplies the given RGB values to this color.
- ///
- /// The alpha value to multiply.
- /// The red value to multiply.
- /// The green value to multiply.
- /// The blue value to multiply.
- /// The new color after the modification.
- public Color MultiplyRGB(double a, double r, double g, double b)
- => new Color((int)Math.Round(A * a), (int)Math.Round(R * r), (int)Math.Round(G * g), (int)Math.Round(B * b));
-
- ///
- /// Multiplies the given RGB-percent values to this color.
- ///
- /// The red value to multiply.
- /// The green value to multiply.
- /// The blue value to multiply.
- /// The new color after the modification.
- public Color MultiplyPercent(double rPercent, double gPercent, double bPercent) => MultiplyPercent(1, rPercent, gPercent, bPercent);
-
- ///
- /// Multiplies the given RGB-percent values to this color.
- ///
- /// The alpha value to multiply.
- /// The red value to multiply.
- /// The green value to multiply.
- /// The blue value to multiply.
- /// The new color after the modification.
- public Color MultiplyPercent(double aPercent, double rPercent, double gPercent, double bPercent)
- => new Color(APercent * aPercent, RPercent * rPercent, GPercent * gPercent, BPercent * bPercent);
-
- ///
- /// Multiplies the given HSV values to this color.
- ///
- /// The hue value to multiply.
- /// The saturation value to multiply.
- /// The value value to multiply.
- /// The new color after the modification.
- public Color MultiplyHSV(double hue, double saturation, double value) => MultiplyHSV(1, hue, saturation, value);
-
- ///
- /// Multiplies the given HSV values to this color.
- ///
- /// The alpha value to multiply.
- /// The hue value to multiply.
- /// The saturation value to multiply.
- /// The value value to multiply.
- /// The new color after the modification.
- public Color MultiplyHSV(double a, double hue, double saturation, double value)
- => FromHSV((int)Math.Round(A * a), Hue * hue, Saturation * saturation, Value * value);
-
- ///
- /// Multiplies the given alpha value to this color.
- ///
- /// The alpha value to multiply.
- /// The new color after the modification.
- public Color MultiplyA(double a) => new Color((int)Math.Round(A * a), R, G, B);
-
- ///
- /// Multiplies the given alpha-percent value to this color.
- ///
- /// The alpha value to multiply.
- /// The new color after the modification.
- public Color MultiplyAPercent(double aPercent) => new Color(APercent * aPercent, RPercent, GPercent, BPercent);
-
- ///
- /// Multiplies the given red value to this color.
- ///
- /// The red value to multiply.
- /// The new color after the modification.
- public Color MultiplyR(double r) => new Color(A, (int)Math.Round(R * r), G, B);
-
- ///
- /// Multiplies the given red-percent value to this color.
- ///
- /// The red value to multiply.
- /// The new color after the modification.
- public Color MultiplyRPercent(double rPercent) => new Color(APercent, RPercent * rPercent, GPercent, BPercent);
-
- ///
- /// Multiplies the given green value to this color.
- ///
- /// The green value to multiply.
- /// The new color after the modification.
- public Color MultiplyG(double g) => new Color(A, R, (int)Math.Round(G * g), B);
-
- ///
- /// Multiplies the given green-percent value to this color.
- ///
- /// The green value to multiply.
- /// The new color after the modification.
- public Color MultiplyGPercent(double gPercent) => new Color(APercent, RPercent, GPercent * gPercent, BPercent);
-
- ///
- /// Multiplies the given blue value to this color.
- ///
- /// The blue value to multiply.
- /// The new color after the modification.
- public Color MultiplyB(double b) => new Color(A, R, G, (int)Math.Round(B * b));
-
- ///
- /// Multiplies the given blue-percent value to this color.
- ///
- /// The blue value to multiply.
- /// The new color after the modification.
- public Color MultiplyBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent * bPercent);
-
- ///
- /// Multiplies the given hue value to this color.
- ///
- /// The hue value to multiply.
- /// The new color after the modification.
- public Color MultiplyHue(double hue) => FromHSV(A, Hue * hue, Saturation, Value);
-
- ///
- /// Multiplies the given saturation value to this color.
- ///
- /// The saturation value to multiply.
- /// The new color after the modification.
- public Color MultiplySaturation(double saturation) => FromHSV(A, Hue, Saturation * saturation, Value);
-
- ///
- /// Multiplies the given value value to this color.
- ///
- /// The value value to multiply.
- /// The new color after the modification.
- public Color MultiplyValue(double value) => FromHSV(A, Hue, Saturation, Value * value);
-
- #endregion
-
- #region Divide
-
- ///
- /// Divides the given RGB values to this color.
- ///
- /// The red value to divide.
- /// The green value to divide.
- /// The blue value to divide.
- /// The new color after the modification.
- public Color DivideRGB(double r, double g, double b) => DivideRGB(1, r, g, b);
-
- ///
- /// Divides the given RGB values to this color.
- ///
- /// The alpha value to divide.
- /// The red value to divide.
- /// The green value to divide.
- /// The blue value to divide.
- /// The new color after the modification.
- public Color DivideRGB(double a, double r, double g, double b)
- => new Color((int)Math.Round(A / a), (int)Math.Round(R / r), (int)Math.Round(G / g), (int)Math.Round(B / b));
-
- ///
- /// Divides the given RGB-percent values to this color.
- ///
- /// The red value to divide.
- /// The green value to divide.
- /// The blue value to divide.
- /// The new color after the modification.
- public Color DividePercent(double rPercent, double gPercent, double bPercent) => DividePercent(1, rPercent, gPercent, bPercent);
-
- ///
- /// Divides the given RGB-percent values to this color.
- ///
- /// The alpha value to divide.
- /// The red value to divide.
- /// The green value to divide.
- /// The blue value to divide.
- /// The new color after the modification.
- public Color DividePercent(double aPercent, double rPercent, double gPercent, double bPercent)
- => new Color(APercent / aPercent, RPercent / rPercent, GPercent / gPercent, BPercent / bPercent);
-
- ///
- /// Divides the given HSV values to this color.
- ///
- /// The hue value to divide.
- /// The saturation value to divide.
- /// The value value to divide.
- /// The new color after the modification.
- public Color DivideHSV(double hue, double saturation, double value) => DivideHSV(1, hue, saturation, value);
-
- ///
- /// Divides the given HSV values to this color.
- ///
- /// The alpha value to divide.
- /// The hue value to divide.
- /// The saturation value to divide.
- /// The value value to divide.
- /// The new color after the modification.
- public Color DivideHSV(double a, double hue, double saturation, double value)
- => FromHSV((int)Math.Round(A / a), Hue / hue, Saturation / saturation, Value / value);
-
- ///
- /// Divides the given alpha value to this color.
- ///
- /// The alpha value to divide.
- /// The new color after the modification.
- public Color DivideA(double a) => new Color((int)Math.Round(A / a), R, G, B);
-
- ///
- /// Divides the given alpha-percent value to this color.
- ///
- /// The alpha value to divide.
- /// The new color after the modification.
- public Color DivideAPercent(double aPercent) => new Color(APercent / aPercent, RPercent, GPercent, BPercent);
-
- ///
- /// Divides the given red value to this color.
- ///
- /// The red value to divide.
- /// The new color after the modification.
- public Color DivideRValue(double r) => new Color(A, (int)Math.Round(R / r), G, B);
-
- ///
- /// Divides the given red-percent value to this color.
- ///
- /// The red value to divide.
- /// The new color after the modification.
- public Color DivideRPercent(double rPercent) => new Color(APercent, RPercent / rPercent, GPercent, BPercent);
-
- ///
- /// Divides the given green value to this color.
- ///
- /// The green value to divide.
- /// The new color after the modification.
- public Color DivideGValue(double g) => new Color(A, R, (int)Math.Round(G / g), B);
-
- ///
- /// Divides the given green-percent value to this color.
- ///
- /// The green value to divide.
- /// The new color after the modification.
- public Color DivideGPercent(double gPercent) => new Color(APercent, RPercent, GPercent / gPercent, BPercent);
-
- ///
- /// Divides the given blue value to this color.
- ///
- /// The blue value to divide.
- /// The new color after the modification.
- public Color DivideBValue(double b) => new Color(A, R, G, (int)Math.Round(B / b));
-
- ///
- /// Divides the given blue-percent value to this color.
- ///
- /// The blue value to divide.
- /// The new color after the modification.
- public Color DivideBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, BPercent / bPercent);
-
- ///
- /// Divides the given hue value to this color.
- ///
- /// The hue value to divide.
- /// The new color after the modification.
- public Color DivideHue(double hue) => FromHSV(A, Hue / hue, Saturation, Value);
-
- ///
- /// Divides the given saturation value to this color.
- ///
- /// The saturation value to divide.
- /// The new color after the modification.
- public Color DivideSaturation(double saturation) => FromHSV(A, Hue, Saturation / saturation, Value);
-
- ///
- /// Divides the given value value to this color.
- ///
- /// The value value to divide.
- /// The new color after the modification.
- public Color DivideValue(double value) => FromHSV(A, Hue, Saturation, Value / value);
-
- #endregion
-
- #region Set
-
- ///
- /// Sets the given alpha value of this color.
- ///
- /// The alpha value to set.
- /// The new color after the modification.
- public Color SetA(int a) => new Color(a, R, G, B);
-
- ///
- /// Sets the given alpha-percent value of this color.
- ///
- /// The alpha value to set.
- /// The new color after the modification.
- public Color SetAPercent(double aPercent) => new Color(aPercent, RPercent, GPercent, BPercent);
-
- ///
- /// Sets the given red value of this color.
- ///
- /// The red value to set.
- /// The new color after the modification.
- public Color SetR(int r) => new Color(A, r, G, B);
-
- ///
- /// Sets the given red-percent value of this color.
- ///
- /// The red value to set.
- /// The new color after the modification.
- public Color SetRPercent(double rPercent) => new Color(APercent, rPercent, GPercent, BPercent);
-
- ///
- /// Sets the given green value of this color.
- ///
- /// The green value to set.
- /// The new color after the modification.
- public Color SetG(int g) => new Color(A, R, g, B);
-
- ///
- /// Sets the given green-percent value of this color.
- ///
- /// The green value to set.
- /// The new color after the modification.
- public Color SetGPercent(double gPercent) => new Color(APercent, RPercent, gPercent, BPercent);
-
- ///
- /// Sets the given blue value of this color.
- ///
- /// The blue value to set.
- /// The new color after the modification.
- public Color SetB(int b) => new Color(A, R, G, b);
-
- ///
- /// Sets the given blue-percent value of this color.
- ///
- /// The blue value to set.
- /// The new color after the modification.
- public Color SetBPercent(double bPercent) => new Color(APercent, RPercent, GPercent, bPercent);
-
- ///
- /// Sets the given hue value of this color.
- ///
- /// The hue value to set.
- /// The new color after the modification.
- public Color SetHue(double hue) => FromHSV(A, hue, Saturation, Value);
-
- ///
- /// Sets the given saturation value of this color.
- ///
- /// The saturation value to set.
- /// The new color after the modification.
- public Color SetSaturation(double saturation) => FromHSV(A, Hue, saturation, Value);
-
- ///
- /// Sets the given value value of this color.
- ///
- /// The value value to set.
- /// The new color after the modification.
- public Color SetValue(double value) => FromHSV(A, Hue, Saturation, value);
-
- #endregion
-
- #endregion
-
- #endregion
-
- #region Operators
-
- ///
- /// Blends the provided colors as if would've been called on .
- ///
- /// The base color.
- /// The color to blend.
- /// The blended color.
- public static Color operator +(Color color1, Color color2) => color1.Blend(color2);
-
- ///
- /// Returns a value that indicates whether two specified are equal.
- ///
- /// The first to compare.
- /// The second to compare.
- /// true if and are equal; otherwise, false.
- public static bool operator ==(Color color1, Color color2) => color1.Equals(color2);
-
- ///
- /// Returns a value that indicates whether two specified are equal.
- ///
- /// The first to compare.
- /// The second to compare.
- /// true if and are not equal; otherwise, false.
- public static bool operator !=(Color color1, Color color2) => !(color1 == color2);
-
- ///
- /// Converts a of ARGB-components to a .
- ///
- /// The containing the components.
- /// The color.
- public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b);
-
- ///
- /// Converts a of HSV-components to a .
- ///
- /// The containing the components.
- /// The color.
- public static implicit operator Color((double hue, double saturation, double value) components) => new Color(components.hue, components.saturation, components.value);
-
- #endregion
- }
-}
diff --git a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings
index d88c562..d216495 100644
--- a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings
+++ b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings
@@ -1,6 +1,8 @@
True
+ TrueTrue
+ TrueTrueTrueTrue
diff --git a/RGB.NET.Decorators/Brush/FlashDecorator.cs b/RGB.NET.Decorators/Brush/FlashDecorator.cs
index dd84f2c..618b243 100644
--- a/RGB.NET.Decorators/Brush/FlashDecorator.cs
+++ b/RGB.NET.Decorators/Brush/FlashDecorator.cs
@@ -77,7 +77,7 @@ namespace RGB.NET.Decorators.Brush
#region Methods
///
- public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetAPercent(_currentValue);
+ public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetA(_currentValue);
///
protected override void Update(double deltaTime)
diff --git a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
index e6d4a6a..28fa936 100644
--- a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
+++ b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
@@ -57,9 +57,9 @@ namespace RGB.NET.Devices.Asus
foreach (KeyValuePair