using System.Drawing;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace Peridot;
///
/// Provides static methods to manipulation.
///
public partial struct ColorF
{
#region Cast operators
///
/// Cast a to .
///
/// The color to cast.
public static implicit operator Vector4(ColorF color) => color.m_rgba;
///
/// Cast a to .
///
///
public static implicit operator ColorF(Vector4 color) => new(color);
///
/// Cast a to .
///
///
public static implicit operator Color(ColorF color)
{
color = Vector4.Clamp(color, Vector4.Zero, Vector4.One) * 255f;
return Color.FromArgb((byte)color.A, (byte)color.R, (byte)color.G, (byte)color.B);
}
///
/// Cast a to .
///
///
public static implicit operator ColorF(Color color)
{
return (ColorF)Vector4.Clamp(new Vector4(color.R, color.G, color.B, color.A) * (1f / 255f), Vector4.Zero, Vector4.One);
}
#endregion
#region Math
public static ColorF Blend(ColorF dst, ColorF src)
{
var dstA = dst.A;
var srcA = src.A;
var res = dst * (1 - srcA) + src * srcA;
res.A = dstA * (1 - srcA) + srcA;
return res;
}
///
/// Negates the specified color.
///
/// The color to negate.
/// The negated vector.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Negate(ColorF color) => -color.m_rgba;
///
/// Adds two colors together.
///
/// The first color.
/// The second color.
/// The summed color.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Add(ColorF left, ColorF right) => left.m_rgba + right.m_rgba;
///
/// Subtracts the second color from the first.
///
/// The first color.
/// The second color.
/// The color that results from subracting from .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Subtract(ColorF left, ColorF right) => left.m_rgba - right.m_rgba;
///
/// Multiplies two colors together.
///
/// The first color.
/// The second color.
/// The product color.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Multiply(ColorF left, ColorF right) => left.m_rgba * right.m_rgba;
///
/// Divides the first color by the second.
///
/// The first color.
/// The second color.
/// The color that results from dividing by .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Divide(ColorF left, ColorF right) => left.m_rgba / right.m_rgba;
///
/// Multiples the specified color by the specified scalar value.
///
/// The color.
/// The scalar value.
/// The scaled color.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Multiply(ColorF left, float right) => left.m_rgba * right;
///
/// Divides the specified color by a specified scalar value.
///
/// The color.
/// The scalar value.
/// The result of the division.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Divide(ColorF left, float right) => left.m_rgba / right;
///
/// Multiples the specified color by the specified scalar value.
///
/// The scalar value.
/// The color.
/// The scaled color.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Multiply(float left, ColorF right) => left * right.m_rgba;
///
/// Linearly interpolates between two colors.
///
/// The first color.
/// The second color.
/// Influence of the second color on the final result.
/// * (1f - ) + * .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ColorF Lerp(in ColorF a, in ColorF b, float t) =>
a + (b - a) * t;
#endregion
#region Operators
///
/// Element-wise equality.
///
/// The first value.
/// The second value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(ColorF left, ColorF right) =>
left.Equals(right);
///
/// Element-wise inequality.
///
/// The first value.
/// The second value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(ColorF left, ColorF right) =>
!left.Equals(right);
///
/// Negates the specified color.
///
/// The color to negate.
/// The negated vector.
public static ColorF operator -(ColorF color) => Negate(color);
///
/// Adds two colors together.
///
/// The first color.
/// The second color.
/// The summed color.
public static ColorF operator +(ColorF left, ColorF right) => Add(left, right);
///
/// Subtracts the second color from the first.
///
/// The first color.
/// The second color.
/// The color that results from subracting from .
public static ColorF operator -(ColorF left, ColorF right) => Subtract(left, right);
///
/// Multiplies two colors together.
///
/// The first color.
/// The second color.
/// The product color.
public static ColorF operator *(ColorF left, ColorF right) => Multiply(left, right);
///
/// Divides the first color by the second.
///
/// The first color.
/// The second color.
/// The color that results from dividing by .
public static ColorF operator /(ColorF left, ColorF right) => Divide(left, right);
///
/// Multiples the specified color by the specified scalar value.
///
/// The color.
/// The scalar value.
/// The scaled color.
public static ColorF operator *(ColorF left, float right) => Multiply(left, right);
///
/// Divides the specified color by a specified scalar value.
///
/// The color.
/// The scalar value.
/// The result of the division.
public static ColorF operator /(ColorF left, float right) => Divide(left, right);
///
/// Multiples the specified color by the specified scalar value.
///
/// The scalar value.
/// The color.
/// The scaled color.
public static ColorF operator *(float left, ColorF right) => Multiply(left, right);
#endregion
#region Colors
///
/// Red (1, 0, 0, 1)
///
public static readonly ColorF Red = new(1f, 0f, 0f, 1f);
///
/// Dark Red (139f / 255f, 0f, 0f, 1f)
///
public static readonly ColorF DarkRed = new(139f / 255f, 0f, 0f, 1f);
///
/// Green (0f, 1f, 0f, 1f)
///
public static readonly ColorF Green = new(0f, 1f, 0f, 1f);
///
/// Blue (0f, 0f, 1f, 1f)
///
public static readonly ColorF Blue = new(0f, 0f, 1f, 1f);
///
/// Yellow (1f, 1f, 0f, 1f)
///
public static readonly ColorF Yellow = new(1f, 1f, 0f, 1f);
///
/// Grey (128f / 255f, 128f / 255f, 128 / 255f, 1f)
///
public static readonly ColorF Grey = new(128f / 255f, 128f / 255f, 128f / 255f, 1f);
///
/// Light Grey (211f / 255f, 211f / 255f, 211f / 255f, 1f)
///
public static readonly ColorF LightGrey = new(211f / 255f, 211f / 255f, 211f / 255f, 1f);
///
/// Cyan (0f, 1f, 1f, 1f)
///
public static readonly ColorF Cyan = new(0f, 1f, 1f, 1f);
///
/// White (1f, 1f, 1f, 1f)
///
public static readonly ColorF White = new(1f, 1f, 1f, 1f);
///
/// Cornflower Blue (100f / 255f, 149f / 255f, 237f / 255f, 1f)
///
public static readonly ColorF CornflowerBlue = new(100f / 255f, 149f / 255f, 237f / 255f, 1f);
///
/// Clear (0f, 0f, 0f, 0f)
///
public static readonly ColorF Clear = new(0f, 0f, 0f, 0f);
///
/// Black (0f, 0f, 0f, 1f)
///
public static readonly ColorF Black = new(0f, 0f, 0f, 1f);
///
/// Pink (1f, 192f / 255f, 203f / 255f, 1f)
///
public static readonly ColorF Pink = new(1f, 192f / 255f, 203f / 255f, 1f);
///
/// Orange (1f, 165f / 255f, 0f, 1f)
///
public static readonly ColorF Orange = new(1f, 165f / 255f, 0f, 1f);
#endregion
}