Merge pull request #9324 from atlimit8/ColorSpacePrefixes

Hex Color Parsing
This commit is contained in:
Oliver Brakmann
2015-11-02 20:28:04 +01:00
221 changed files with 12295 additions and 11794 deletions

View File

@@ -212,21 +212,9 @@ namespace OpenRA
}
else if (fieldType == typeof(Color))
{
if (value != null)
{
var parts = value.Split(',');
if (parts.Length == 3)
return Color.FromArgb(
Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255));
if (parts.Length == 4)
return Color.FromArgb(
Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[1]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[2]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[3]).Clamp(0, 255));
}
Color color;
if (value != null && HSLColor.TryParseRGB(value, out color))
return color;
return InvalidValueAction(value, fieldType, fieldName);
}
@@ -235,20 +223,11 @@ namespace OpenRA
if (value != null)
{
var parts = value.Split(',');
if (parts.Length % 4 != 0)
return InvalidValueAction(value, fieldType, fieldName);
var colors = new Color[parts.Length / 4];
var colors = new Color[parts.Length];
for (var i = 0; i < colors.Length; i++)
{
colors[i] = Color.FromArgb(
Exts.ParseIntegerInvariant(parts[4 * i]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[4 * i + 1]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[4 * i + 2]).Clamp(0, 255),
Exts.ParseIntegerInvariant(parts[4 * i + 3]).Clamp(0, 255));
}
if (!HSLColor.TryParseRGB(parts[i], out colors[i]))
return InvalidValueAction(value, fieldType, fieldName);
return colors;
}
@@ -259,9 +238,12 @@ namespace OpenRA
{
if (value != null)
{
var parts = value.Split(',');
Color rgb;
if (HSLColor.TryParseRGB(value, out rgb))
return new HSLColor(rgb);
// Allow old ColorRamp format to be parsed as HSLColor
// Allow old HSLColor/ColorRamp formats to be parsed as HSLColor
var parts = value.Split(',');
if (parts.Length == 3 || parts.Length == 4)
return new HSLColor(
(byte)Exts.ParseIntegerInvariant(parts[0]).Clamp(0, 255),

View File

@@ -16,6 +16,7 @@ using System.Drawing.Imaging;
using System.Globalization;
using System.Linq;
using System.Reflection;
using OpenRA.Graphics;
namespace OpenRA
{
@@ -73,14 +74,16 @@ namespace OpenRA
var t = v.GetType();
// Color.ToString() does the wrong thing; force it to format as an array
// Color.ToString() does the wrong thing; force it to format as rgb[a] hex
if (t == typeof(Color))
{
var c = (Color)v;
return "{0},{1},{2},{3}".F(((int)c.A).Clamp(0, 255),
((int)c.R).Clamp(0, 255),
((int)c.G).Clamp(0, 255),
((int)c.B).Clamp(0, 255));
return HSLColor.ToHexString((Color)v);
}
// HSLColor.ToString() does the wrong thing; force it to format as rgb[a] hex
if (t == typeof(HSLColor))
{
return ((HSLColor)v).ToHexString();
}
if (t == typeof(ImageFormat))

View File

@@ -9,6 +9,7 @@
#endregion
using System.Drawing;
using System.Globalization;
using OpenRA.Scripting;
namespace OpenRA.Graphics
@@ -27,13 +28,17 @@ namespace OpenRA.Graphics
return new HSLColor((byte)(255 * h), (byte)(255 * ss), (byte)(255 * ll));
}
public HSLColor(Color color)
{
RGB = color;
H = (byte)((color.GetHue() / 360.0f) * 255);
S = (byte)(color.GetSaturation() * 255);
L = (byte)(color.GetBrightness() * 255);
}
public static HSLColor FromRGB(int r, int g, int b)
{
var c = Color.FromArgb(r, g, b);
var h = (byte)((c.GetHue() / 360.0f) * 255);
var s = (byte)(c.GetSaturation() * 255);
var l = (byte)(c.GetBrightness() * 255);
return new HSLColor(h, s, l);
return new HSLColor(Color.FromArgb(r, g, b));
}
public static Color RGBFromHSL(float h, float s, float l)
@@ -66,6 +71,27 @@ namespace OpenRA.Graphics
return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255));
}
public static bool TryParseRGB(string value, out Color color)
{
color = new Color();
value = value.Trim();
if (value.Length != 6 && value.Length != 8)
return false;
byte red, green, blue, alpha = 255;
if (!byte.TryParse(value.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out red)
|| !byte.TryParse(value.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out green)
|| !byte.TryParse(value.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out blue))
return false;
if (value.Length == 8
&& !byte.TryParse(value.Substring(6, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out alpha))
return false;
color = Color.FromArgb(alpha, red, green, blue);
return true;
}
public static bool operator ==(HSLColor me, HSLColor other)
{
return me.H == other.H && me.S == other.S && me.L == other.L;
@@ -96,6 +122,18 @@ namespace OpenRA.Graphics
return "{0},{1},{2}".F(H, S, L);
}
public static string ToHexString(Color color)
{
if (color.A == 255)
return color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
return color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2") + color.A.ToString("X2");
}
public string ToHexString()
{
return ToHexString(RGB);
}
public override int GetHashCode() { return H.GetHashCode() ^ S.GetHashCode() ^ L.GetHashCode(); }
public override bool Equals(object obj)

View File

@@ -344,6 +344,54 @@ namespace OpenRA
Visibility = MapVisibility.MissionSelector;
}
// Format 7 -> 8 replaced normalized HSL triples with rgb(a) hex colors
if (MapFormat < 8)
{
var players = yaml.Nodes.FirstOrDefault(n => n.Key == "Players");
if (players != null)
{
bool noteHexColors = false;
bool noteColorRamp = false;
foreach (var player in players.Value.Nodes)
{
var colorRampNode = player.Value.Nodes.FirstOrDefault(n => n.Key == "ColorRamp");
if (colorRampNode != null)
{
Color dummy;
var parts = colorRampNode.Value.Value.Split(',');
if (parts.Length == 3 || parts.Length == 4)
{
// Try to convert old normalized HSL value to a rgb hex color
try
{
HSLColor color = new HSLColor(
(byte)Exts.ParseIntegerInvariant(parts[0].Trim()).Clamp(0, 255),
(byte)Exts.ParseIntegerInvariant(parts[1].Trim()).Clamp(0, 255),
(byte)Exts.ParseIntegerInvariant(parts[2].Trim()).Clamp(0, 255));
colorRampNode.Value.Value = FieldSaver.FormatValue(color);
noteHexColors = true;
}
catch (Exception)
{
throw new InvalidDataException("Invalid ColorRamp value.\n File: " + path);
}
}
else if (parts.Length != 1 || !HSLColor.TryParseRGB(parts[0], out dummy))
throw new InvalidDataException("Invalid ColorRamp value.\n File: " + path);
colorRampNode.Key = "Color";
noteColorRamp = true;
}
}
Console.WriteLine("Converted " + path + " to MapFormat 8.");
if (noteHexColors)
Console.WriteLine("ColorRamp is now called Color and uses rgb(a) hex value - rrggbb[aa].");
else if (noteColorRamp)
Console.WriteLine("ColorRamp is now called Color.");
}
}
SpawnPoints = Exts.Lazy(() =>
{
var spawns = new List<CPos>();
@@ -389,7 +437,7 @@ namespace OpenRA
// The Uid is calculated from the data on-disk, so
// format changes must be flushed to disk.
// TODO: this isn't very nice
if (MapFormat < 7)
if (MapFormat < 8)
Save(path);
Uid = ComputeHash();
@@ -537,7 +585,7 @@ namespace OpenRA
public void Save(string toPath)
{
MapFormat = 7;
MapFormat = 8;
var root = new List<MiniYamlNode>();
var fields = new[]

View File

@@ -28,10 +28,8 @@ namespace OpenRA
public bool LockFaction = false;
public string Faction;
// ColorRamp naming retained for backward compatibility
public bool LockColor = false;
public HSLColor ColorRamp = new HSLColor(0, 0, 238);
public HSLColor Color { get { return ColorRamp; } set { ColorRamp = value; } }
public HSLColor Color = new HSLColor(0, 0, 238);
public bool LockSpawn = false;
public int Spawn = 0;