Browse Source

Add higher performance, mutable RGB and HSV structs

These are only for internal use with the ColorSpectrum
pull/7842/head
robloo 5 years ago
parent
commit
653abb3b31
  1. 87
      src/Avalonia.Controls/ColorPicker/ColorSpectrum/Hsv.cs
  2. 94
      src/Avalonia.Controls/ColorPicker/ColorSpectrum/Rgb.cs

87
src/Avalonia.Controls/ColorPicker/ColorSpectrum/Hsv.cs

@ -0,0 +1,87 @@
// Portions of this source file are adapted from the WinUI project.
// (https://github.com/microsoft/microsoft-ui-xaml)
//
// Licensed to The Avalonia Project under the MIT License.
using System.Numerics;
using Avalonia.Media;
namespace Avalonia.Controls.Primitives
{
/// <summary>
/// Contains and allows modification of Hue, Saturation and Value channel values.
/// </summary>
/// <remarks>
/// The is a specialized struct optimized for permanence and memory:
/// <list type="bullet">
/// <item>This is not a read-only struct like <see cref="HsvColor"/> and allows editing the fields</item>
/// <item>Removes the alpha component unnecessary in core calculations</item>
/// <item>No channel value bounds checks or clamping is done.</item>
/// </list>
/// </remarks>
internal struct Hsv
{
/// <summary>
/// The Hue channel value in the range from 0..359.
/// </summary>
public double H;
/// <summary>
/// The Saturation channel value in the range from 0..1.
/// </summary>
public double S;
/// <summary>
/// The Value channel value in the range from 0..1.
/// </summary>
public double V;
/// <summary>
/// Initializes a new instance of the <see cref="Hsv"/> struct.
/// </summary>
/// <param name="h">The Hue channel value in the range from 0..360.</param>
/// <param name="s">The Saturation channel value in the range from 0..1.</param>
/// <param name="v">The Value channel value in the range from 0..1.</param>
public Hsv(double h, double s, double v)
{
H = h;
S = s;
V = v;
}
/// <summary>
/// Initializes a new instance of the <see cref="Hsv"/> struct.
/// </summary>
/// <param name="hsvColor">An existing <see cref="HsvColor"/> to convert to <see cref="Hsv"/>.</param>
public Hsv(HsvColor hsvColor)
{
H = hsvColor.H;
S = hsvColor.S;
V = hsvColor.V;
}
/// <summary>
/// Converts this <see cref="Hsv"/> struct into a standard <see cref="HsvColor"/>.
/// </summary>
/// <param name="alpha">The Alpha channel value in the range from 0..1.</param>
/// <returns>A new <see cref="HsvColor"/> representing this <see cref="Hsv"/> struct.</returns>
public HsvColor ToHsvColor(double alpha = 1.0)
{
// Clamping is done automatically in the constructor
return HsvColor.FromAhsv(alpha, H, S, V);
}
/// <summary>
/// Returns the <see cref="Rgb"/> color model equivalent of this <see cref="Hsv"/> color.
/// </summary>
/// <returns>The <see cref="Rgb"/> equivalent color.</returns>
public Rgb ToRgb()
{
// Instantiating a Color is unfortunately necessary to use existing conversions
// Clamping is done internally in the conversion method
Color color = HsvColor.ToRgb(H, S, V);
return new Rgb(color);
}
}
}

94
src/Avalonia.Controls/ColorPicker/ColorSpectrum/Rgb.cs

@ -0,0 +1,94 @@
// Portions of this source file are adapted from the WinUI project.
// (https://github.com/microsoft/microsoft-ui-xaml)
//
// Licensed to The Avalonia Project under the MIT License.
using System;
using Avalonia.Media;
using Avalonia.Utilities;
namespace Avalonia.Controls.Primitives
{
/// <summary>
/// Contains and allows modification of Red, Green and Blue channel values.
/// </summary>
/// <remarks>
/// The is a specialized struct optimized for permanence and memory:
/// <list type="bullet">
/// <item>This is not a read-only struct like <see cref="Color"/> and allows editing the fields</item>
/// <item>Removes the alpha component unnecessary in core calculations</item>
/// <item>Normalizes RGB channel values in the range of 0..1 to simplify calculations.</item>
/// <item>No channel value bounds checks or clamping is done.</item>
/// </list>
/// </remarks>
internal struct Rgb
{
/// <summary>
/// The Red channel value in the range from 0..1.
/// </summary>
public double R;
/// <summary>
/// The Green channel value in the range from 0..1.
/// </summary>
public double G;
/// <summary>
/// The Blue channel value in the range from 0..1.
/// </summary>
public double B;
/// <summary>
/// Initializes a new instance of the <see cref="Rgb"/> struct.
/// </summary>
/// <param name="r">The Red channel value in the range from 0..1.</param>
/// <param name="g">The Green channel value in the range from 0..1.</param>
/// <param name="b">The Blue channel value in the range from 0..1.</param>
public Rgb(double r, double g, double b)
{
R = r;
G = g;
B = b;
}
/// <summary>
/// Initializes a new instance of the <see cref="Rgb"/> struct.
/// </summary>
/// <param name="color">An existing <see cref="Color"/> to convert to <see cref="Rgb"/>.</param>
public Rgb(Color color)
{
R = color.R / 255.0;
G = color.G / 255.0;
B = color.B / 255.0;
}
/// <summary>
/// Converts this <see cref="Rgb"/> struct into a standard <see cref="Color"/>.
/// </summary>
/// <param name="alpha">The Alpha channel value in the range from 0..1.</param>
/// <returns>A new <see cref="Color"/> representing this <see cref="Rgb"/> struct.</returns>
public Color ToColor(double alpha = 1.0)
{
return Color.FromArgb(
(byte)MathUtilities.Clamp(alpha * 255.0, 0x00, 0xFF),
(byte)MathUtilities.Clamp(R * 255.0, 0x00, 0xFF),
(byte)MathUtilities.Clamp(G * 255.0, 0x00, 0xFF),
(byte)MathUtilities.Clamp(B * 255.0, 0x00, 0xFF));
}
/// <summary>
/// Returns the <see cref="Hsv"/> color model equivalent of this <see cref="Rgb"/> color.
/// </summary>
/// <returns>The <see cref="Hsv"/> equivalent color.</returns>
public Hsv ToHsv()
{
// Instantiating an HsvColor is unfortunately necessary to use existing conversions
HsvColor hsvColor = HsvColor.FromRgb(
MathUtilities.Clamp(R, 0.0, 1.0),
MathUtilities.Clamp(G, 0.0, 1.0),
MathUtilities.Clamp(B, 0.0, 1.0));
return new Hsv(hsvColor);
}
}
}
Loading…
Cancel
Save