in src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs [1233:1391]
private static void FillPixelForBox(
double x,
double y,
Hsv baseHsv,
int minDimension,
ColorSpectrumComponents components,
double minHue,
double maxHue,
double minSaturation,
double maxSaturation,
double minValue,
double maxValue,
PooledList<byte> bgraMinPixelData,
PooledList<byte> bgraMiddle1PixelData,
PooledList<byte> bgraMiddle2PixelData,
PooledList<byte> bgraMiddle3PixelData,
PooledList<byte> bgraMiddle4PixelData,
PooledList<byte> bgraMaxPixelData,
List<Hsv> newHsvValues)
{
double hMin = minHue;
double hMax = maxHue;
double sMin = minSaturation / 100.0;
double sMax = maxSaturation / 100.0;
double vMin = minValue / 100.0;
double vMax = maxValue / 100.0;
Hsv hsvMin = baseHsv;
Hsv hsvMiddle1 = baseHsv;
Hsv hsvMiddle2 = baseHsv;
Hsv hsvMiddle3 = baseHsv;
Hsv hsvMiddle4 = baseHsv;
Hsv hsvMax = baseHsv;
double xPercent = (minDimension - 1 - x) / (minDimension - 1);
double yPercent = (minDimension - 1 - y) / (minDimension - 1);
switch (components)
{
case ColorSpectrumComponents.HueValue:
hsvMin.H = hsvMiddle1.H = hsvMiddle2.H = hsvMiddle3.H = hsvMiddle4.H = hsvMax.H = hMin + yPercent * (hMax - hMin);
hsvMin.V = hsvMiddle1.V = hsvMiddle2.V = hsvMiddle3.V = hsvMiddle4.V = hsvMax.V = vMin + xPercent * (vMax - vMin);
hsvMin.S = 0;
hsvMax.S = 1;
break;
case ColorSpectrumComponents.HueSaturation:
hsvMin.H = hsvMiddle1.H = hsvMiddle2.H = hsvMiddle3.H = hsvMiddle4.H = hsvMax.H = hMin + yPercent * (hMax - hMin);
hsvMin.S = hsvMiddle1.S = hsvMiddle2.S = hsvMiddle3.S = hsvMiddle4.S = hsvMax.S = sMin + xPercent * (sMax - sMin);
hsvMin.V = 0;
hsvMax.V = 1;
break;
case ColorSpectrumComponents.ValueHue:
hsvMin.V = hsvMiddle1.V = hsvMiddle2.V = hsvMiddle3.V = hsvMiddle4.V = hsvMax.V = vMin + yPercent * (vMax - vMin);
hsvMin.H = hsvMiddle1.H = hsvMiddle2.H = hsvMiddle3.H = hsvMiddle4.H = hsvMax.H = hMin + xPercent * (hMax - hMin);
hsvMin.S = 0;
hsvMax.S = 1;
break;
case ColorSpectrumComponents.ValueSaturation:
hsvMin.V = hsvMiddle1.V = hsvMiddle2.V = hsvMiddle3.V = hsvMiddle4.V = hsvMax.V = vMin + yPercent * (vMax - vMin);
hsvMin.S = hsvMiddle1.S = hsvMiddle2.S = hsvMiddle3.S = hsvMiddle4.S = hsvMax.S = sMin + xPercent * (sMax - sMin);
hsvMin.H = 0;
hsvMiddle1.H = 60;
hsvMiddle2.H = 120;
hsvMiddle3.H = 180;
hsvMiddle4.H = 240;
hsvMax.H = 300;
break;
case ColorSpectrumComponents.SaturationHue:
hsvMin.S = hsvMiddle1.S = hsvMiddle2.S = hsvMiddle3.S = hsvMiddle4.S = hsvMax.S = sMin + yPercent * (sMax - sMin);
hsvMin.H = hsvMiddle1.H = hsvMiddle2.H = hsvMiddle3.H = hsvMiddle4.H = hsvMax.H = hMin + xPercent * (hMax - hMin);
hsvMin.V = 0;
hsvMax.V = 1;
break;
case ColorSpectrumComponents.SaturationValue:
hsvMin.S = hsvMiddle1.S = hsvMiddle2.S = hsvMiddle3.S = hsvMiddle4.S = hsvMax.S = sMin + yPercent * (sMax - sMin);
hsvMin.V = hsvMiddle1.V = hsvMiddle2.V = hsvMiddle3.V = hsvMiddle4.V = hsvMax.V = vMin + xPercent * (vMax - vMin);
hsvMin.H = 0;
hsvMiddle1.H = 60;
hsvMiddle2.H = 120;
hsvMiddle3.H = 180;
hsvMiddle4.H = 240;
hsvMax.H = 300;
break;
}
// If saturation is an axis in the spectrum with hue, or value is an axis, then we want
// that axis to go from maximum at the top to minimum at the bottom,
// or maximum at the outside to minimum at the inside in the case of the ring configuration,
// so we'll invert the number before assigning the HSL value to the array.
// Otherwise, we'll have a very narrow section in the middle that actually has meaningful hue
// in the case of the ring configuration.
if (components == ColorSpectrumComponents.HueSaturation ||
components == ColorSpectrumComponents.SaturationHue)
{
hsvMin.S = sMax - hsvMin.S + sMin;
hsvMiddle1.S = sMax - hsvMiddle1.S + sMin;
hsvMiddle2.S = sMax - hsvMiddle2.S + sMin;
hsvMiddle3.S = sMax - hsvMiddle3.S + sMin;
hsvMiddle4.S = sMax - hsvMiddle4.S + sMin;
hsvMax.S = sMax - hsvMax.S + sMin;
}
else
{
hsvMin.V = vMax - hsvMin.V + vMin;
hsvMiddle1.V = vMax - hsvMiddle1.V + vMin;
hsvMiddle2.V = vMax - hsvMiddle2.V + vMin;
hsvMiddle3.V = vMax - hsvMiddle3.V + vMin;
hsvMiddle4.V = vMax - hsvMiddle4.V + vMin;
hsvMax.V = vMax - hsvMax.V + vMin;
}
newHsvValues.Add(hsvMin);
Rgb rgbMin = hsvMin.ToRgb();
bgraMinPixelData.Add((byte)Math.Round(rgbMin.B * 255.0)); // b
bgraMinPixelData.Add((byte)Math.Round(rgbMin.G * 255.0)); // g
bgraMinPixelData.Add((byte)Math.Round(rgbMin.R * 255.0)); // r
bgraMinPixelData.Add(255); // a - ignored
// We'll only save pixel data for the middle bitmaps if our third dimension is hue.
if (components == ColorSpectrumComponents.ValueSaturation ||
components == ColorSpectrumComponents.SaturationValue)
{
Rgb rgbMiddle1 = hsvMiddle1.ToRgb();
bgraMiddle1PixelData.Add((byte)Math.Round(rgbMiddle1.B * 255.0)); // b
bgraMiddle1PixelData.Add((byte)Math.Round(rgbMiddle1.G * 255.0)); // g
bgraMiddle1PixelData.Add((byte)Math.Round(rgbMiddle1.R * 255.0)); // r
bgraMiddle1PixelData.Add(255); // a - ignored
Rgb rgbMiddle2 = hsvMiddle2.ToRgb();
bgraMiddle2PixelData.Add((byte)Math.Round(rgbMiddle2.B * 255.0)); // b
bgraMiddle2PixelData.Add((byte)Math.Round(rgbMiddle2.G * 255.0)); // g
bgraMiddle2PixelData.Add((byte)Math.Round(rgbMiddle2.R * 255.0)); // r
bgraMiddle2PixelData.Add(255); // a - ignored
Rgb rgbMiddle3 = hsvMiddle3.ToRgb();
bgraMiddle3PixelData.Add((byte)Math.Round(rgbMiddle3.B * 255.0)); // b
bgraMiddle3PixelData.Add((byte)Math.Round(rgbMiddle3.G * 255.0)); // g
bgraMiddle3PixelData.Add((byte)Math.Round(rgbMiddle3.R * 255.0)); // r
bgraMiddle3PixelData.Add(255); // a - ignored
Rgb rgbMiddle4 = hsvMiddle4.ToRgb();
bgraMiddle4PixelData.Add((byte)Math.Round(rgbMiddle4.B * 255.0)); // b
bgraMiddle4PixelData.Add((byte)Math.Round(rgbMiddle4.G * 255.0)); // g
bgraMiddle4PixelData.Add((byte)Math.Round(rgbMiddle4.R * 255.0)); // r
bgraMiddle4PixelData.Add(255); // a - ignored
}
Rgb rgbMax = hsvMax.ToRgb();
bgraMaxPixelData.Add((byte)Math.Round(rgbMax.B * 255.0)); // b
bgraMaxPixelData.Add((byte)Math.Round(rgbMax.G * 255.0)); // g
bgraMaxPixelData.Add((byte)Math.Round(rgbMax.R * 255.0)); // r
bgraMaxPixelData.Add(255); // a - ignored
}