Unify and improve FromHex in ColorHelper.cs and ColorExtensions.cs (#961)

* Both now use ColorHelper.FromHex, rather than differing implementations

* FromHex now accepts hex numbers with three and four digits matching HTML color codes, where "ABC" maps to "AABBCC"

* Significant performance increase using bitshifts over string operations
This commit is contained in:
Eb3yr
2024-11-07 17:30:18 +00:00
committed by GitHub
parent a0613cff6c
commit d3b4482573
2 changed files with 41 additions and 13 deletions
+1 -5
View File
@@ -11,11 +11,7 @@ namespace MonoGame.Extended
{
public static Color FromHex(string value)
{
var r = int.Parse(value.Substring(1, 2), NumberStyles.HexNumber);
var g = int.Parse(value.Substring(3, 2), NumberStyles.HexNumber);
var b = int.Parse(value.Substring(5, 2), NumberStyles.HexNumber);
var a = value.Length > 7 ? int.Parse(value.Substring(7, 2), NumberStyles.HexNumber) : 255;
return new Color(r, g, b, a);
return ColorHelper.FromHex(value);
}
public static Color ToRgb(this HslColor c)
+40 -8
View File
@@ -45,13 +45,45 @@ namespace MonoGame.Extended
{
if (string.IsNullOrEmpty(value))
return Color.Transparent;
var startIndex = 0;
if (value.StartsWith("#"))
startIndex++;
var r = int.Parse(value.Substring(startIndex, 2), NumberStyles.HexNumber);
var g = int.Parse(value.Substring(startIndex + 2, 2), NumberStyles.HexNumber);
var b = int.Parse(value.Substring(startIndex + 4, 2), NumberStyles.HexNumber);
var a = value.Length > 6 + startIndex ? int.Parse(value.Substring(startIndex + 6, 2), NumberStyles.HexNumber) : 255;
if (value[0] == '#')
value = value.Substring(1);
int r, g, b, a;
uint hexInt = uint.Parse(value, System.Globalization.NumberStyles.HexNumber);
switch (value.Length)
{
case 6:
r = (byte)((hexInt & 0x00FF0000) >> 16);
g = (byte)((hexInt & 0x0000FF00) >> 8);
b = (byte)(hexInt & 0x000000FF);
a = 255;
break;
case 8:
r = (byte)((hexInt & 0xFF000000) >> 24);
g = (byte)((hexInt & 0x00FF0000) >> 16);
b = (byte)((hexInt & 0x0000FF00) >> 8);
a = (byte)(hexInt & 0x000000FF);
break;
case 3:
r = (byte)(((hexInt & 0x00000F00) | (hexInt & 0x00000F00) << 4) >> 8);
g = (byte)(((hexInt & 0x000000F0) | (hexInt & 0x000000F0) << 4) >> 4);
b = (byte)((hexInt & 0x0000000F) | (hexInt & 0x0000000F) << 4);
a = 255;
break;
case 4:
r = (byte)(((hexInt & 0x0000F000) | (hexInt & 0x0000F000) << 4) >> 12);
g = (byte)(((hexInt & 0x00000F00) | (hexInt & 0x00000F00) << 4) >> 8);
b = (byte)(((hexInt & 0x000000F0) | (hexInt & 0x000000F0) << 4) >> 4);
a = (byte)((hexInt & 0x0000000F) | (hexInt & 0x0000000F) << 4);
break;
default:
throw new ArgumentException($"Malformed hexadecimal color: {value}");
}
return new Color(r, g, b, a);
}
@@ -80,4 +112,4 @@ namespace MonoGame.Extended
throw new InvalidOperationException($"{name} is not a valid color");
}
}
}
}