diff --git a/OpenRA.FileFormats/ColorRamp.cs b/OpenRA.FileFormats/ColorRamp.cs index 36929d7c6a..5f0d9f74cd 100644 --- a/OpenRA.FileFormats/ColorRamp.cs +++ b/OpenRA.FileFormats/ColorRamp.cs @@ -14,59 +14,41 @@ namespace OpenRA.FileFormats { public struct ColorRamp { - public byte H,S,L,R; + public readonly HSLColor Color; + public byte Ramp; + + public ColorRamp(HSLColor color, byte ramp) + { + Color = color; + Ramp = ramp; + } public ColorRamp(byte h, byte s, byte l, byte r) { - H = h; S = s; L = l; R = r; + Color = new HSLColor(h, s, l); + Ramp = r; } /* returns a color along the Lum ramp */ - public Color GetColor( float t ) + public Color GetColor(float t) { - return ColorFromHSL( H / 255f, S / 255f, float2.Lerp( L / 255f, L*R / (255f * 255f), t ) ); + var l = float2.Lerp(Color.L, Color.L*Ramp/255f, t); + return HSLColor.RGBFromHSL(Color.H/255f, Color.S/255f, l/255f); } public override string ToString() { - return "{0},{1},{2},{3}".F(H, S, L, R); - } - - // hk is hue in the range [0,1] instead of [0,360] - static Color ColorFromHSL(float hk, float s, float l) - { - // Convert from HSL to RGB - var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s); - var p = 2 * l - q; - - float[] trgb = { hk + 1 / 3.0f, hk, hk - 1/3.0f }; - float[] rgb = { 0, 0, 0 }; - - for (int k = 0; k < 3; k++) - { - while (trgb[k] < 0) trgb[k] += 1.0f; - while (trgb[k] > 1) trgb[k] -= 1.0f; - } - - for (int k = 0; k < 3; k++) - { - if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); } - else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; } - else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); } - else { rgb[k] = p; } - } - - return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255)); + return "{0},{1}".F(Color.ToString(), Ramp); } public static bool operator ==(ColorRamp me, ColorRamp other) { - return (me.H == other.H && me.S == other.S && me.L == other.L && me.R == other.R ); + return (me.Color == other.Color && me.Ramp == other.Ramp); } public static bool operator !=(ColorRamp me, ColorRamp other) { return !(me == other); } - public override int GetHashCode() { return H.GetHashCode() ^ S.GetHashCode() ^ L.GetHashCode() ^ R.GetHashCode(); } + public override int GetHashCode() { return Color.GetHashCode() ^ Ramp.GetHashCode(); } public override bool Equals(object obj) { diff --git a/OpenRA.FileFormats/HSLColor.cs b/OpenRA.FileFormats/HSLColor.cs new file mode 100644 index 0000000000..3b3eab81dd --- /dev/null +++ b/OpenRA.FileFormats/HSLColor.cs @@ -0,0 +1,99 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Drawing; + +namespace OpenRA.FileFormats +{ + public struct HSLColor + { + public readonly byte H; + public readonly byte S; + public readonly byte L; + + public HSLColor(byte h, byte s, byte l) + { + H = h; + S = s; + L = l; + } + + public Color ToColor() + { + return RGBFromHSL(H / 255f, S / 255f, L / 255f); + } + + public void ToHSV(out float h, out float s, out float v) + { + var ll = 2*L / 255f; + var ss = S / 255f * ((ll <= 1) ? ll : 2 - ll); + + h = H / 255f; + s = (2 * ss) / (ll + ss); + v = (ll + ss) / 2; + } + + public static HSLColor FromHSV(float h, float s, float v) + { + var ll = 0.5f*(2 - s)*v; + var ss = (ll >= 1 || v <= 0) ? 0 : 0.5f*s*v / (ll <= 0.5f ? ll : 1 - ll); + return new HSLColor((byte)(255*h), (byte)(255*ss), (byte)(255*ll)); + } + + public static Color RGBFromHSL(float h, float s, float l) + { + // Convert from HSL to RGB + var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s); + var p = 2 * l - q; + + float[] trgb = { h + 1 / 3.0f, h, h - 1/3.0f }; + float[] rgb = { 0, 0, 0 }; + + for (int k = 0; k < 3; k++) + { + while (trgb[k] < 0) trgb[k] += 1.0f; + while (trgb[k] > 1) trgb[k] -= 1.0f; + } + + for (int k = 0; k < 3; k++) + { + if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); } + else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; } + else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); } + else { rgb[k] = p; } + } + + return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255)); + } + + public override string ToString() + { + return "{0},{1},{2}".F(H, S, L); + } + + public static bool operator ==(HSLColor me, HSLColor other) + { + return (me.H == other.H && me.S == other.S && me.L == other.L); + } + + public static bool operator !=(HSLColor me, HSLColor other) { return !(me == other); } + + public override int GetHashCode() { return H.GetHashCode() ^ S.GetHashCode() ^ L.GetHashCode(); } + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + HSLColor o = (HSLColor)obj; + return o == this; + } + } +} diff --git a/OpenRA.FileFormats/OpenRA.FileFormats.csproj b/OpenRA.FileFormats/OpenRA.FileFormats.csproj index fe0f50fbca..e2835f3e54 100644 --- a/OpenRA.FileFormats/OpenRA.FileFormats.csproj +++ b/OpenRA.FileFormats/OpenRA.FileFormats.csproj @@ -137,6 +137,7 @@ + diff --git a/OpenRA.Mods.RA/Widgets/Logic/ColorPickerLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ColorPickerLogic.cs index b539e8b8e9..f373e37a8e 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ColorPickerLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ColorPickerLogic.cs @@ -44,9 +44,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic Action updateSliders = () => { - hueSlider.Value = ramp.H / 255f; - satSlider.Value = ramp.S / 255f; - lumSlider.Value = ramp.L / 255f; + hueSlider.Value = ramp.Color.H / 255f; + satSlider.Value = ramp.Color.S / 255f; + lumSlider.Value = ramp.Color.L / 255f; }; panel.Get("SAVE_BUTTON").OnClick = () => onSelect(ramp);