diff --git a/source/MonoGame.Extended/ColorExtensions.cs b/source/MonoGame.Extended/ColorExtensions.cs index 20e87e73..78884407 100644 --- a/source/MonoGame.Extended/ColorExtensions.cs +++ b/source/MonoGame.Extended/ColorExtensions.cs @@ -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) diff --git a/source/MonoGame.Extended/ColorHelper.cs b/source/MonoGame.Extended/ColorHelper.cs index 370af3dc..b6e8ecd6 100644 --- a/source/MonoGame.Extended/ColorHelper.cs +++ b/source/MonoGame.Extended/ColorHelper.cs @@ -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"); } } -} \ No newline at end of file +}