diff --git a/CHANGELOG.md b/CHANGELOG.md index 0183c8c..bfae87c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ Additions - Added Zero, One, Linear and Clamp to Easings - Added GetRandomEntry and GetRandomWeightedEntry to SingleRandom - Added the ability to draw single corners of AutoTiling's extended auto tiles +- Added ColorHelper.TryFromHexString, a non-throwing version of FromHexString + +Improvements +- Stopped the text formatter throwing if a color can't be parsed Fixes - Fixed TextInput not working correctly when using surrogate pairs diff --git a/MLEM.Extended/Tiled/TiledExtensions.cs b/MLEM.Extended/Tiled/TiledExtensions.cs index b933636..cb1d575 100644 --- a/MLEM.Extended/Tiled/TiledExtensions.cs +++ b/MLEM.Extended/Tiled/TiledExtensions.cs @@ -44,7 +44,8 @@ namespace MLEM.Extended.Tiled { /// The key by which to get a property /// The color property public static Color GetColor(this TiledMapProperties properties, string key) { - return ColorHelper.FromHexString(properties.Get(key)); + ColorHelper.TryFromHexString(properties.Get(key), out var val); + return val; } /// diff --git a/MLEM/Extensions/ColorExtensions.cs b/MLEM/Extensions/ColorExtensions.cs index 05b66f2..2ac4b9a 100644 --- a/MLEM/Extensions/ColorExtensions.cs +++ b/MLEM/Extensions/ColorExtensions.cs @@ -1,3 +1,4 @@ +using System; using System.Globalization; using Microsoft.Xna.Framework; @@ -64,16 +65,34 @@ namespace MLEM.Extensions { } /// - /// Parses a hexadecimal string into a color. + /// Parses a hexadecimal string into a color and throws a if parsing fails. /// The string can either be formatted as RRGGBB or AARRGGBB and can optionally start with a #. /// /// The string to parse. /// The resulting color. + /// Thrown if parsing fails. public static Color FromHexString(string value) { + if (!ColorHelper.TryFromHexString(value, out var val)) + throw new FormatException($"Cannot parse hex string {value}"); + return val; + } + + /// + /// Tries to parse a hexadecimal string into a color and returns whether a color was successfully parsed. + /// The string can either be formatted as RRGGBB or AARRGGBB and can optionally start with a #. + /// + /// The string to parse. + /// The resulting color. + /// Whether parsing was successful. + public static bool TryFromHexString(string value, out Color color) { if (value.StartsWith("#")) value = value.Substring(1); - var val = int.Parse(value, NumberStyles.HexNumber); - return value.Length > 6 ? ColorHelper.FromHexRgba(val) : ColorHelper.FromHexRgb(val); + if (int.TryParse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var val)) { + color = value.Length > 6 ? ColorHelper.FromHexRgba(val) : ColorHelper.FromHexRgb(val); + return true; + } + color = default; + return false; } } diff --git a/MLEM/Formatting/TextFormatter.cs b/MLEM/Formatting/TextFormatter.cs index f0789a7..1407572 100644 --- a/MLEM/Formatting/TextFormatter.cs +++ b/MLEM/Formatting/TextFormatter.cs @@ -102,7 +102,7 @@ namespace MLEM.Formatting { this.Codes.Add(new Regex(""), (f, m, r) => new FontCode(m, r, fnt => fnt.Bold)); this.Codes.Add(new Regex(""), (f, m, r) => new FontCode(m, r, fnt => fnt.Italic)); this.Codes.Add(new Regex(@""), (f, m, r) => new ShadowCode(m, r, - m.Groups[1].Success ? ColorHelper.FromHexString(m.Groups[1].Value) : this.DefaultShadowColor, + ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : this.DefaultShadowColor, float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var offset) ? new Vector2(offset) : this.DefaultShadowOffset)); this.Codes.Add(new Regex(""), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.UnderlineOffset)); this.Codes.Add(new Regex(""), (f, m, r) => new UnderlineCode(m, r, this.LineThickness, this.StrikethroughOffset)); @@ -111,7 +111,7 @@ namespace MLEM.Formatting { this.Codes.Add(new Regex(@""), (f, m, r) => new SubSupCode(m, r, float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var off) ? -off : this.DefaultSupOffset)); this.Codes.Add(new Regex(@""), (f, m, r) => new OutlineCode(m, r, - m.Groups[1].Success ? ColorHelper.FromHexString(m.Groups[1].Value) : this.DefaultOutlineColor, + ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : this.DefaultOutlineColor, float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var thickness) ? thickness : this.DefaultOutlineThickness, this.OutlineDiagonals)); } @@ -124,12 +124,13 @@ namespace MLEM.Formatting { this.Codes.Add(new Regex($""), (f, m, r) => new ColorCode(m, r, value)); } } - this.Codes.Add(new Regex(@""), (f, m, r) => new ColorCode(m, r, ColorHelper.FromHexString(m.Groups[1].Value))); + this.Codes.Add(new Regex(@""), (f, m, r) => new ColorCode(m, r, + ColorHelper.TryFromHexString(m.Groups[1].Value, out var color) ? color : Color.Red)); } // animation codes if (hasAnimations) { - this.Codes.Add(new Regex(@""), (f, m, r) => new WobblyCode(m, r, + this.Codes.Add(new Regex(""), (f, m, r) => new WobblyCode(m, r, float.TryParse(m.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var mod) ? mod : this.DefaultWobblyModifier, float.TryParse(m.Groups[2].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out var heightMod) ? heightMod : this.DefaultWobblyHeight)); }