Jelajahi Sumber

Fixes #4000. Named colors as enums. (#4005)

* Add W3C color enum with the RGB as numeric value

* Add transform helper class for W3cColor enum

For the sake of backwards compatibility prioritize parsing 16 color mode color names over the W3C colors because the previous resource-based color names/values had a mix of W3C and 16 color mode RGB values.

Mechanism for choosing/prioritizing one color scheme over the other is currently only available at higher application/driver/output level.

* IColorNameResolver enable null analysis

* Remove obsolete color name related ResourceManagerTests

* Replace remains of W3CColors with direct W3C color name resolver

Temporarily breaks backwards compatibility and tests even further.

* Add ANSI 4-bit (ColorName16) color name resolver

* Add multi-standard color name resolver

Combined resolver for both ANSI 4-bit (ColorName16) and W3C colors while trying to maintain backwards compatibility for ColorPicker.

* Split conditional name resolver test cases

* Change W3C colors tests to be similar to name resolvers

* Change W3cColorsTests to W3cColorNameResolverTests

More consistent when all the tests refer to the color name resolver layer.

* Make W3cColors internal

Color name resolver is the public interface.

* W3cColors: Use Color.Argb instead of individual RGB components

* MultiStandardColorNameResolver: Substitute instead of blocking alternative W3C names

Changes color picker behavior a bit, e.g. Aqua will match to Cyan instead of jumping to Aquamarine.

* Remove leftover color string resources

* Consistent position for IColorNameResolver #nullable enable directive

* Add missing XML comments to ColorScheme.Colors.cs
Tonttu 5 bulan lalu
induk
melakukan
1856262b50

+ 2 - 5
Terminal.Gui/Configuration/ColorJsonConverter.cs

@@ -1,6 +1,5 @@
 using System.Text.Json;
 using System.Text.Json.Serialization;
-using ColorHelper;
 
 namespace Terminal.Gui;
 
@@ -40,11 +39,9 @@ internal class ColorJsonConverter : JsonConverter<Color>
             // Get the color string
             ReadOnlySpan<char> colorString = reader.GetString ();
 
-            // Check if the color string is a color name
-            if (ColorStrings.TryParseW3CColorName (colorString.ToString (), out Color color1))
+            if (ColorStrings.TryParseNamedColor (colorString, out Color namedColor))
             {
-                // Return the parsed color
-                return new (color1);
+                return namedColor;
             }
 
             if (Color.TryParse (colorString, null, out Color parsedColor))

+ 70 - 0
Terminal.Gui/Drawing/Color/AnsiColorNameResolver.cs

@@ -0,0 +1,70 @@
+#nullable enable
+
+using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Terminal.Gui;
+
+/// <summary>
+/// Color name resolver for <see cref="ColorName16"/>.
+/// </summary>
+public class AnsiColorNameResolver : IColorNameResolver
+{
+    private static readonly ImmutableArray<string> AnsiColorNames = ImmutableArray.Create(Enum.GetNames<ColorName16>());
+
+    /// <inheritdoc/>
+    public IEnumerable<string> GetColorNames ()
+    {
+        return AnsiColorNames;
+    }
+
+    /// <inheritdoc/>
+    public bool TryNameColor (Color color, [NotNullWhen (true)] out string? name)
+    {
+        if (Color.TryGetExactNamedColor16 (color, out ColorName16 colorName16))
+        {
+            name = Color16Name (colorName16);
+            return true;
+        }
+        name = null;
+        return false;
+    }
+
+    /// <inheritdoc/>
+    public bool TryParseColor (ReadOnlySpan<char> name, out Color color)
+    {
+        if (Enum.TryParse (name, ignoreCase: true, out ColorName16 colorName16) &&
+            // Any numerical value converts to undefined enum value.
+            Enum.IsDefined (colorName16))
+        {
+            color = new Color (colorName16);
+            return true;
+        }
+        color = default;
+        return false;
+    }
+
+    private static string Color16Name (ColorName16 color16)
+    {
+        return color16 switch
+        {
+            ColorName16.Black => nameof (ColorName16.Black),
+            ColorName16.Blue => nameof (ColorName16.Blue),
+            ColorName16.Green => nameof (ColorName16.Green),
+            ColorName16.Cyan => nameof (ColorName16.Cyan),
+            ColorName16.Red => nameof (ColorName16.Red),
+            ColorName16.Magenta => nameof (ColorName16.Magenta),
+            ColorName16.Yellow => nameof (ColorName16.Yellow),
+            ColorName16.Gray => nameof (ColorName16.Gray),
+            ColorName16.DarkGray => nameof (ColorName16.DarkGray),
+            ColorName16.BrightBlue => nameof (ColorName16.BrightBlue),
+            ColorName16.BrightGreen => nameof (ColorName16.BrightGreen),
+            ColorName16.BrightCyan => nameof (ColorName16.BrightCyan),
+            ColorName16.BrightRed => nameof (ColorName16.BrightRed),
+            ColorName16.BrightMagenta => nameof (ColorName16.BrightMagenta),
+            ColorName16.BrightYellow => nameof (ColorName16.BrightYellow),
+            ColorName16.White => nameof (ColorName16.White),
+            _ => throw new NotSupportedException ($"ColorName16 '{color16}' is not supported.")
+        };
+    }
+}

+ 67 - 81
Terminal.Gui/Drawing/Color/Color.Formatting.cs

@@ -1,6 +1,5 @@
 #nullable enable
 using System.Diagnostics.CodeAnalysis;
-using System.Diagnostics.Contracts;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 
@@ -267,90 +266,79 @@ public readonly partial record struct Color
         return text switch
         {
             // Null string or empty span provided
-            { IsEmpty: true } when formatProvider is null => throw new ColorParseException (
-                                                                                            in text,
-                                                                                            "The text provided was null or empty.",
-                                                                                            in text
-                                                                                           ),
+            { IsEmpty: true } when formatProvider is null =>
+                throw new ColorParseException (in text, "The text provided was null or empty.", in text),
 
             // A valid ICustomColorFormatter was specified and the text wasn't null or empty
             { IsEmpty: false } when formatProvider is ICustomColorFormatter f => f.Parse (text),
 
             // Input string is only whitespace
-            { Length: > 0 } when text.IsWhiteSpace () => throw new ColorParseException (
-                                                                                        in text,
-                                                                                        "The text provided consisted of only whitespace characters.",
-                                                                                        in text
-                                                                                       ),
+            { Length: > 0 } when text.IsWhiteSpace () =>
+                throw new ColorParseException (in text, "The text provided consisted of only whitespace characters.", in text),
 
             // Any string too short to possibly be any supported format.
-            { Length: > 0 and < 3 } => throw new ColorParseException (
-                                                                      in text,
-                                                                      "Text was too short to be any possible supported format.",
-                                                                      in text
-                                                                     ),
-
-                                                                     // The various hexadecimal cases
-                                                                     ['#', ..] hexString => hexString switch
-                                                                     {
-                                                                     // #RGB
-                                                                     ['#', var rChar, var gChar, var bChar] chars when chars [1..]
-                                                                                    .IsAllAsciiHexDigits () =>
-                                                                                new Color (
-                                                                                           byte.Parse ([rChar, rChar], NumberStyles.HexNumber),
-                                                                                           byte.Parse ([gChar, gChar], NumberStyles.HexNumber),
-                                                                                           byte.Parse ([bChar, bChar], NumberStyles.HexNumber)
-                                                                                          ),
-
-                                                                                          // #ARGB
-                                                                                          ['#', var aChar, var rChar, var gChar, var bChar] chars when chars [1..]
-                                                                                                         .IsAllAsciiHexDigits () =>
-                                                                                                     new Color (
-                                                                                                                byte.Parse ([rChar, rChar], NumberStyles.HexNumber),
-                                                                                                                byte.Parse ([gChar, gChar], NumberStyles.HexNumber),
-                                                                                                                byte.Parse ([bChar, bChar], NumberStyles.HexNumber),
-                                                                                                                byte.Parse ([aChar, aChar], NumberStyles.HexNumber)
-                                                                                                               ),
-
-                                                                                                               // #RRGGBB
-                                                                                                               [
-                                                                                         '#', var r1Char, var r2Char, var g1Char, var g2Char, var b1Char,
-                                                                                         var b2Char
-                                                                                     ] chars when chars [1..].IsAllAsciiHexDigits () =>
-                                                                                     new Color (
-                                                                                                byte.Parse ([r1Char, r2Char], NumberStyles.HexNumber),
-                                                                                                byte.Parse ([g1Char, g2Char], NumberStyles.HexNumber),
-                                                                                                byte.Parse ([b1Char, b2Char], NumberStyles.HexNumber)
-                                                                                               ),
-
-                                                                                               // #AARRGGBB
-                                                                                               [
-                                                                                         '#', var a1Char, var a2Char, var r1Char, var r2Char, var g1Char,
-                                                                                         var g2Char, var b1Char, var b2Char
-                                                                                     ] chars when chars [1..].IsAllAsciiHexDigits () =>
-                                                                                     new Color (
-                                                                                                byte.Parse ([r1Char, r2Char], NumberStyles.HexNumber),
-                                                                                                byte.Parse ([g1Char, g2Char], NumberStyles.HexNumber),
-                                                                                                byte.Parse ([b1Char, b2Char], NumberStyles.HexNumber),
-                                                                                                byte.Parse ([a1Char, a2Char], NumberStyles.HexNumber)
-                                                                                               ),
-                                                                         _ => throw new ColorParseException (
-                                                                                                                    in hexString,
-                                                                                                                    $"Color hex string {hexString} was not in a supported format",
-                                                                                                                    in hexString
-                                                                                                                   )
-                                                                     },
-
-                                                                     // rgb(r,g,b) or rgb(r,g,b,a)
-                                                                     ['r', 'g', 'b', '(', .., ')'] => ParseRgbaFormat (in text, 4),
-
-                                                                     // rgba(r,g,b,a) or rgba(r,g,b)
-                                                                     ['r', 'g', 'b', 'a', '(', .., ')'] => ParseRgbaFormat (in text, 5),
-
-            // Attempt to parse as a named color from the ColorStrings resources
-            { } when char.IsLetter (text [0]) && ColorStrings.TryParseW3CColorName (text.ToString (), out Color color) =>
-                new Color (color),
+            { Length: > 0 and < 3 } =>
+                throw new ColorParseException (in text, "Text was too short to be any possible supported format.", in text),
 
+            // The various hexadecimal cases
+            ['#', ..] hexString => hexString switch
+            {
+                // #RGB
+                ['#', var rChar, var gChar, var bChar] chars when chars [1..]
+                    .IsAllAsciiHexDigits () =>
+                        new Color (
+                            byte.Parse ([rChar, rChar], NumberStyles.HexNumber),
+                            byte.Parse ([gChar, gChar], NumberStyles.HexNumber),
+                            byte.Parse ([bChar, bChar], NumberStyles.HexNumber)
+                        ),
+
+                // #ARGB
+                ['#', var aChar, var rChar, var gChar, var bChar] chars when chars [1..]
+                    .IsAllAsciiHexDigits () =>
+                        new Color (
+                            byte.Parse ([rChar, rChar], NumberStyles.HexNumber),
+                            byte.Parse ([gChar, gChar], NumberStyles.HexNumber),
+                            byte.Parse ([bChar, bChar], NumberStyles.HexNumber),
+                            byte.Parse ([aChar, aChar], NumberStyles.HexNumber)
+                        ),
+
+                // #RRGGBB
+                [
+                '#', var r1Char, var r2Char, var g1Char, var g2Char, var b1Char, var b2Char
+                ] chars when chars [1..].IsAllAsciiHexDigits () =>
+                    new Color (
+                        byte.Parse ([r1Char, r2Char], NumberStyles.HexNumber),
+                        byte.Parse ([g1Char, g2Char], NumberStyles.HexNumber),
+                        byte.Parse ([b1Char, b2Char], NumberStyles.HexNumber)
+                    ),
+
+                // #AARRGGBB
+                [
+                    '#', var a1Char, var a2Char,
+                    var r1Char, var r2Char,
+                    var g1Char, var g2Char,
+                    var b1Char, var b2Char
+                ] chars when chars [1..].IsAllAsciiHexDigits () =>
+                    new Color (
+                        byte.Parse ([r1Char, r2Char], NumberStyles.HexNumber),
+                        byte.Parse ([g1Char, g2Char], NumberStyles.HexNumber),
+                        byte.Parse ([b1Char, b2Char], NumberStyles.HexNumber),
+                        byte.Parse ([a1Char, a2Char], NumberStyles.HexNumber)
+                    ),
+                _ => throw new ColorParseException (
+                        in hexString,
+                        $"Color hex string {hexString} was not in a supported format",
+                        in hexString
+                    )
+            },
+
+            // rgb(r,g,b) or rgb(r,g,b,a)
+            ['r', 'g', 'b', '(', .., ')'] => ParseRgbaFormat (in text, 4),
+
+            // rgba(r,g,b,a) or rgba(r,g,b)
+            ['r', 'g', 'b', 'a', '(', .., ')'] => ParseRgbaFormat (in text, 5),
+            // Attempt named colors
+            { } when char.IsLetter (text [0]) && ColorStrings.TryParseNamedColor (text, out Color color) => color,
             // Any other input
             _ => throw new ColorParseException (in text, "Text did not match any expected format.", in text, [])
         };
@@ -585,11 +573,9 @@ public readonly partial record struct Color
     [SkipLocalsInit]
     public override string ToString ()
     {
-        string? name = ColorStrings.GetW3CColorName (this);
-
-        if (name is { })
+        if (ColorStrings.GetColorName (this) is string colorName)
         {
-            return name;
+            return colorName;
         }
 
         return $"#{R:X2}{G:X2}{B:X2}";

+ 9 - 2
Terminal.Gui/Drawing/Color/Color.cs

@@ -1,7 +1,5 @@
 #nullable enable
 using System.Collections.Frozen;
-using System.Diagnostics.Contracts;
-using System.Drawing;
 using System.Globalization;
 using System.Numerics;
 using System.Runtime.CompilerServices;
@@ -236,6 +234,15 @@ public readonly partial record struct Color : ISpanParsable<Color>, IUtf8SpanPar
         return ColorExtensions.ColorToName16Map.MinBy (pair => CalculateColorDistance (inputColor, pair.Key)).Value;
     }
 
+    /// <summary>Converts the given color value to exact named color represented by <see cref="ColorName16"/>.</summary>
+    /// <param name="inputColor"></param>
+    /// <param name="colorName16">Successfully converted named color.</param>
+    /// <returns>True if conversion succeeded; otherwise false.</returns>
+    internal static bool TryGetExactNamedColor16 (Color inputColor, out ColorName16 colorName16)
+    {
+        return ColorExtensions.ColorToName16Map.TryGetValue (inputColor, out colorName16);
+    }
+
     [SkipLocalsInit]
     private static float CalculateColorDistance (in Vector4 color1, in Vector4 color2) { return Vector4.Distance (color1, color2); }
 

+ 12 - 1
Terminal.Gui/Drawing/Color/ColorScheme.Colors.cs

@@ -185,6 +185,11 @@ public sealed class Colors : INotifyCollectionChanged, IDictionary<string, Color
         }
     }
 
+    /// <summary>
+    ///     Copies the elements of the <see cref="ColorSchemes"/> to an array, starting at a particular array index.
+    /// </summary>
+    /// <param name="array">The one-dimensional array that is the destination of the elements copied from <see cref="ColorSchemes"/>.</param>
+    /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
     public void CopyTo (KeyValuePair<string, ColorScheme?> [] array, int arrayIndex)
     {
         lock (_lock)
@@ -193,6 +198,10 @@ public sealed class Colors : INotifyCollectionChanged, IDictionary<string, Color
         }
     }
 
+    /// <summary>
+    ///     Returns an enumerator that iterates through the <see cref="ColorSchemes"/>.
+    /// </summary>
+    /// <returns>An enumerator for the <see cref="ColorSchemes"/>.</returns>
     public IEnumerator<KeyValuePair<string, ColorScheme?>> GetEnumerator ()
     {
         lock (_lock)
@@ -206,6 +215,7 @@ public sealed class Colors : INotifyCollectionChanged, IDictionary<string, Color
         return GetEnumerator ();
     }
 
+    /// <inheritdoc />
     public bool Remove (KeyValuePair<string, ColorScheme?> item)
     {
         lock (_lock)
@@ -219,6 +229,7 @@ public sealed class Colors : INotifyCollectionChanged, IDictionary<string, Color
         }
     }
 
+    /// <inheritdoc />
     public bool Remove (string key)
     {
         lock (_lock)
@@ -245,7 +256,7 @@ public sealed class Colors : INotifyCollectionChanged, IDictionary<string, Color
     /// <summary>
     ///     Resets the <see cref="ColorSchemes"/> dictionary to its default values.
     /// </summary>
-    /// <returns></returns>
+    /// <returns>The reset <see cref="ColorSchemes"/> dictionary.</returns>
     public static Dictionary<string, ColorScheme?> Reset ()
     {
         lock (_lock)

+ 87 - 33
Terminal.Gui/Drawing/Color/ColorStrings.cs

@@ -1,8 +1,5 @@
 #nullable enable
-using System.Collections;
 using System.Globalization;
-using System.Resources;
-using Terminal.Gui.Resources;
 
 namespace Terminal.Gui;
 
@@ -11,7 +8,9 @@ namespace Terminal.Gui;
 /// </summary>
 public static class ColorStrings
 {
-    // PERFORMANCE: See https://stackoverflow.com/a/15521524/297526 for why GlobalResources.GetString is fast.
+    private static readonly AnsiColorNameResolver Ansi = new();
+    private static readonly W3cColorNameResolver W3c = new();
+    private static readonly MultiStandardColorNameResolver Multi = new();
 
     /// <summary>
     ///     Gets the W3C standard string for <paramref name="color"/>.
@@ -20,7 +19,39 @@ public static class ColorStrings
     /// <returns><see langword="null"/> if there is no standard color name for the specified color.</returns>
     public static string? GetW3CColorName (Color color)
     {
-        return GlobalResources.GetString ($"#{color.R:X2}{color.G:X2}{color.B:X2}", CultureInfo.CurrentUICulture);
+        if (W3c.TryNameColor (color, out string? name))
+        {
+            return name;
+        }
+        return null;
+    }
+
+    /// <summary>
+    ///     Gets the ANSI 4-bit (16) color name for <paramref name="color"/>.
+    /// </summary>
+    /// <param name="color">The color.</param>
+    /// <returns><see langword="null"/> if there is no standard color name for the specified color.</returns>
+    public static string? GetANSIColor16Name (Color color)
+    {
+        if (Ansi.TryNameColor (color, out string? name))
+        {
+            return name;
+        }
+        return null;
+    }
+
+    /// <summary>
+    ///     Gets backwards compatible color name for <paramref name="color"/>.
+    /// </summary>
+    /// <param name="color">The color.</param>
+    /// <returns>Standard color name for the specified color; otherwise <see langword="null"/>.</returns>
+    public static string? GetColorName (Color color)
+    {
+        if (Multi.TryNameColor (color, out string? name))
+        {
+            return name;
+        }
+        return null;
     }
 
     /// <summary>
@@ -29,54 +60,77 @@ public static class ColorStrings
     /// <returns></returns>
     public static IEnumerable<string> GetW3CColorNames ()
     {
-        ResourceSet? resourceSet = GlobalResources.GetResourceSet (CultureInfo.CurrentUICulture, true, true);
-        if (resourceSet == null)
+        return W3c.GetColorNames ();
+    }
+
+    /// <summary>
+    ///     Parses <paramref name="name"/> and returns <paramref name="color"/> if name is a W3C standard named color.
+    /// </summary>
+    /// <param name="name">The name to parse.</param>
+    /// <param name="color">If successful, the color.</param>
+    /// <returns><see langword="true"/> if <paramref name="name"/> was parsed successfully.</returns>
+    public static bool TryParseW3CColorName (ReadOnlySpan<char> name, out Color color)
+    {
+        if (W3c.TryParseColor (name, out color))
         {
-            yield break;
+            return true;
         }
+        // Backwards compatibility: Also parse #RRGGBB.
+        return TryParseHexColor (name, out color);
+    }
 
-        foreach (DictionaryEntry entry in resourceSet)
+    /// <summary>
+    ///     Parses <paramref name="name"/> and returns <paramref name="color"/> if name is a ANSI 4-bit standard named color.
+    /// </summary>
+    /// <param name="name">The name to parse.</param>
+    /// <param name="color">If successful, the color.</param>
+    /// <returns><see langword="true"/> if <paramref name="name"/> was parsed successfully.</returns>
+    public static bool TryParseColor16 (ReadOnlySpan<char> name, out Color color)
+    {
+        if (Ansi.TryParseColor (name, out color))
         {
-            if (entry is { Value: string colorName, Key: string key } && key.StartsWith ('#'))
-            {
-                yield return colorName;
-            }
+            return true;
         }
+        color = default;
+        return false;
     }
 
     /// <summary>
-    ///     Parses <paramref name="name"/> and returns <paramref name="color"/> if name is a W3C standard named color.
+    ///     Parses <paramref name="name"/> and returns <paramref name="color"/> if name is either ANSI 4-bit or W3C standard named color.
     /// </summary>
     /// <param name="name">The name to parse.</param>
     /// <param name="color">If successful, the color.</param>
     /// <returns><see langword="true"/> if <paramref name="name"/> was parsed successfully.</returns>
-    public static bool TryParseW3CColorName (string name, out Color color)
+    public static bool TryParseNamedColor (ReadOnlySpan<char> name, out Color color)
     {
-        foreach (DictionaryEntry entry in GlobalResources.GetResourceSet (CultureInfo.CurrentUICulture, true, true)!)
+        if (Multi.TryParseColor (name, out color))
         {
-            if (entry.Value is string colorName && colorName.Equals (name, StringComparison.OrdinalIgnoreCase))
-            {
-                return TryParseColorKey (entry.Key.ToString (), out color);
-            }
+            return true;
+        }
+        // Backwards compatibility: Also parse #RRGGBB.
+        if (TryParseHexColor (name, out color))
+        {
+            return true;
         }
 
-        return TryParseColorKey (name, out color);
+        color = default;
+        return false;
+    }
 
-        bool TryParseColorKey (string? key, out Color color)
+    private static bool TryParseHexColor (ReadOnlySpan<char> name, out Color color)
+    {
+        if (name.Length == 7 && name [0] == '#')
         {
-            if (key != null && key.StartsWith ('#') && key.Length == 7)
+            if (int.TryParse (name.Slice (1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int r) &&
+                int.TryParse (name.Slice (3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int g) &&
+                int.TryParse (name.Slice (5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int b))
             {
-                if (int.TryParse (key.AsSpan (1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int r) &&
-                    int.TryParse (key.AsSpan (3, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int g) &&
-                    int.TryParse (key.AsSpan (5, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int b))
-                {
-                    color = new Color (r, g, b);
-                    return true;
-                }
+                color = new Color (r, g, b);
+                return true;
             }
-
-            color = default (Color);
-            return false;
         }
+
+        color = default;
+        return false;
     }
 }

+ 7 - 3
Terminal.Gui/Drawing/Color/IColorNameResolver.cs

@@ -1,4 +1,8 @@
-namespace Terminal.Gui;
+#nullable enable
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Terminal.Gui;
 
 /// <summary>
 ///     When implemented by a class, allows mapping <see cref="Color"/> to
@@ -20,7 +24,7 @@ public interface IColorNameResolver
     /// <param name="color"></param>
     /// <param name="name"></param>
     /// <returns></returns>
-    bool TryNameColor (Color color, out string name);
+    bool TryNameColor (Color color, [NotNullWhen(true)]out string? name);
 
     /// <summary>
     ///     Returns <see langword="true"/> if <paramref name="name"/> is a recognized
@@ -30,5 +34,5 @@ public interface IColorNameResolver
     /// <param name="name"></param>
     /// <param name="color"></param>
     /// <returns></returns>
-    bool TryParseColor (string name, out Color color);
+    bool TryParseColor (ReadOnlySpan<char> name, out Color color);
 }

+ 188 - 0
Terminal.Gui/Drawing/Color/MultiStandardColorNameResolver.cs

@@ -0,0 +1,188 @@
+#nullable enable
+
+using System.Collections.Frozen;
+using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Terminal.Gui;
+
+/// <summary>
+/// Backwards compatible(-ish) color name resolver prioritizing ANSI 4-bit (16) colors with fallback to W3C colors.
+/// </summary>
+public class MultiStandardColorNameResolver : IColorNameResolver
+{
+    private static readonly AnsiColorNameResolver Ansi = new();
+    private static readonly W3cColorNameResolver W3c = new();
+    private static readonly FrozenSet<Color> W3cBlockedColors;
+    private static readonly ImmutableArray<string> CombinedColorNames;
+    private static readonly FrozenDictionary<int, (string Name, Color Color)> W3cSubstituteColors;
+
+    static MultiStandardColorNameResolver ()
+    {
+        HashSet<string> combinedNames = new(Ansi.GetColorNames());
+
+        HashSet<Color> w3cInconsistentColors = new();
+        Dictionary<string, Color> w3cSubstituteColors = new(StringComparer.OrdinalIgnoreCase);
+
+        IEnumerable<string> enumerableW3cNames = W3c.GetColorNames ();
+        IReadOnlyList<string> w3cNames =  enumerableW3cNames is IReadOnlyList<string> alreadyReadOnlyList
+            ? alreadyReadOnlyList
+            : [.. enumerableW3cNames];
+
+        Dictionary<Color, HashSet<string>> w3cColorsWithAlternativeNames = w3cNames
+            .GroupBy(w3cName =>
+            {
+                if (!W3c.TryParseColor(w3cName, out Color w3cColor))
+                {
+                    throw new InvalidOperationException ($"W3C color name '{w3cName}' does not resolve to any W3C color.");
+                }
+                return w3cColor;
+            })
+            .Where(g => g.Count() > 1)
+            .ToDictionary(g => g.Key, g => g.ToHashSet());
+
+        // Gather inconsistencies between ANSI and W3C, filter out or substitute problematic W3C colors and names,
+        // and create additional blocklist for W3C colors.
+        // Blocking and filtering is only applied to W3C because this resolver prioritizes ANSI for backwards compatibility.
+        // It would be a lot simpler to just prioritize W3C colors and names.
+        foreach (string w3cName in w3cNames)
+        {
+            if (w3cSubstituteColors.ContainsKey (w3cName))
+            {
+                // Already dealt with alternative name.
+                continue;
+            }
+
+            if (!W3c.TryParseColor (w3cName, out Color w3cColor))
+            {
+                // This condition is just inverted to reduce indentation.
+                // Also it should practically never happen if the W3C color name resolver is properly implemented.
+                throw new InvalidOperationException ($"W3C color name '{w3cName}' does not resolve to any color.");
+            }
+
+            if (w3cColorsWithAlternativeNames.TryGetValue (w3cColor, out var names))
+            {
+                bool substituted = false;
+                // Alternative names cause issues with ColorPicker etc. when combined with ANSI and prioritizing ANSI resolver.
+                // For example Aqua is not in ColorName16 but the actual color value resolves to ANSI Cyan
+                // so autocomplete for Aqua suddenly changes to Cyan because they happen to have same color value in both color scheme.
+                // Also DarkGrey would cause inconsistencies because the alternative DarkGray exists in ANSI and has different color value.
+                foreach (string name in names)
+                {
+                    if (Ansi.TryParseColor (name, out Color substituteColor))
+                    {
+                        // Block the W3C color when it is inconsistent with the substitute color
+                        // so there is no situation where W3C color -> color name -> ANSI color.
+                        if (w3cColor != substituteColor)
+                        {
+                            w3cInconsistentColors.Add (w3cColor);
+                        }
+
+                        // Substitute all W3C alternatives to match with the ANSI color to keep colors consistent.
+                        foreach (string alternativeName in names)
+                        {
+                            w3cSubstituteColors.Add (alternativeName, substituteColor);
+                            combinedNames.Add (alternativeName);
+                        }
+                        substituted = true;
+                        break;
+                    }
+                }
+
+                if (substituted)
+                {
+                    // Already dealt with, continue to next W3C color name.
+                    continue;
+                }
+            }
+
+            // Same name, different ANSI value.
+            // For example both #767676 (ColorName16) and #A9A9A9 (W3C) resolve to DarkGray,
+            // although a bad example because it is already substituted due to also having alternative names.
+            if (Ansi.TryParseColor (w3cName, out Color ansiColor) && w3cColor != ansiColor)
+            {
+                w3cInconsistentColors.Add (w3cColor);
+                continue;
+            }
+
+            combinedNames.Add (w3cName);
+        }
+
+        // TODO: Utilize .NET 9 and later alternative lookup for matching ReadOnlySpan<char> with string.
+        W3cSubstituteColors = w3cSubstituteColors.ToFrozenDictionary (
+            // Workaround for alternative lookup not being available in .NET 8 by matching ReadOnlySpan<char> hash code to string hash code.
+            keySelector: kvp => string.GetHashCode (kvp.Key, StringComparison.OrdinalIgnoreCase),
+            // The string element is for detecting hash collision.
+            elementSelector: kvp => (kvp.Key, kvp.Value));
+        W3cBlockedColors = w3cInconsistentColors.ToFrozenSet ();
+        CombinedColorNames = combinedNames.Order ().ToImmutableArray ();
+    }
+
+    /// <inheritdoc/>
+    public IEnumerable<string> GetColorNames ()
+    {
+        return CombinedColorNames;
+    }
+
+    /// <inheritdoc/>
+    public bool TryNameColor (Color color, [NotNullWhen (true)] out string? name)
+    {
+        if (Ansi.TryNameColor (color, out string? ansiName))
+        {
+            name = ansiName;
+            return true;
+        }
+
+        if (!IsBlockedW3cColor (color) &&
+            W3c.TryNameColor (color, out string? w3cName))
+        {
+            name = w3cName;
+            return true;
+        }
+
+        name = null;
+        return false;
+    }
+
+    /// <inheritdoc/>
+    public bool TryParseColor (ReadOnlySpan<char> name, out Color color)
+    {
+        if (Ansi.TryParseColor (name, out color))
+        {
+            return true;
+        }
+
+        if (GetSubstituteW3cColor (name, out color))
+        {
+            return true;
+        }
+
+        if (W3c.TryParseColor (name, out color) &&
+            !IsBlockedW3cColor (color))
+        {
+            return true;
+        }
+
+        color = default;
+        return false;
+    }
+
+    private static bool GetSubstituteW3cColor (ReadOnlySpan<char> name, out Color substituteColor)
+    {
+        int nameHashCode = string.GetHashCode(name, StringComparison.OrdinalIgnoreCase);
+        if (W3cSubstituteColors.TryGetValue (nameHashCode, out var match) &&
+            match is (string matchName, Color matchColor) &&
+            name.Equals (matchName, StringComparison.OrdinalIgnoreCase))
+        {
+            substituteColor = matchColor;
+            return true;
+        }
+        substituteColor = default;
+        return false;
+    }
+
+    private static bool IsBlockedW3cColor (Color color)
+    {
+        return W3cBlockedColors.Contains (color);
+    }
+}

+ 0 - 24
Terminal.Gui/Drawing/Color/W3CColors.cs

@@ -1,24 +0,0 @@
-namespace Terminal.Gui;
-
-/// <summary>
-///     Helper class that resolves w3c color names to their hex values
-///     Based on https://www.w3schools.com/colors/color_tryit.asp
-/// </summary>
-public class W3CColors : IColorNameResolver
-{
-    /// <inheritdoc/>
-    public IEnumerable<string> GetColorNames () { return ColorStrings.GetW3CColorNames (); }
-
-    /// <inheritdoc/>
-    public bool TryParseColor (string name, out Color color) { return ColorStrings.TryParseW3CColorName (name, out color); }
-
-    /// <inheritdoc/>
-    public bool TryNameColor (Color color, out string name)
-    {
-        string answer = ColorStrings.GetW3CColorName (color);
-
-        name = answer ?? string.Empty;
-
-        return answer != null;
-    }
-}

+ 777 - 0
Terminal.Gui/Drawing/Color/W3cColor.cs

@@ -0,0 +1,777 @@
+namespace Terminal.Gui;
+
+/// <summary>
+/// Represents the W3C color names with their RGB values.
+/// </summary>
+/// <remarks>
+/// Based on https://www.w3schools.com/colors/color_tryit.asp page.
+/// </remarks>
+public enum W3cColor
+{
+    /// <summary>
+    /// Alice blue RGB(240, 248, 255).
+    /// </summary>
+    AliceBlue = 0xF0F8FF,
+
+    /// <summary>
+    /// Antique white RGB(250, 235, 215).
+    /// </summary>
+    AntiqueWhite = 0xFAEBD7,
+
+    /// <summary>
+    /// Aqua RGB(0, 255, 255).
+    /// </summary>
+    Aqua = 0x00FFFF,
+
+    /// <summary>
+    /// Aquamarine RGB(127, 255, 212).
+    /// </summary>
+    Aquamarine = 0x7FFFD4,
+
+    /// <summary>
+    /// Azure RGB(240, 255, 255).
+    /// </summary>
+    Azure = 0xF0FFFF,
+
+    /// <summary>
+    /// Beige RGB(245, 245, 220).
+    /// </summary>
+    Beige = 0xF5F5DC,
+
+    /// <summary>
+    /// Bisque RGB(255, 228, 196).
+    /// </summary>
+    Bisque = 0xFFE4C4,
+
+    /// <summary>
+    /// Black RGB(0, 0, 0).
+    /// </summary>
+    Black = 0x000000,
+
+    /// <summary>
+    /// Blanched almond RGB(255, 235, 205).
+    /// </summary>
+    BlanchedAlmond = 0xFFEBCD,
+
+    /// <summary>
+    /// Blue RGB(0, 0, 255).
+    /// </summary>
+    Blue = 0x0000FF,
+
+    /// <summary>
+    /// Blue violet RGB(138, 43, 226).
+    /// </summary>
+    BlueViolet = 0x8A2BE2,
+
+    /// <summary>
+    /// Brown RGB(165, 42, 42).
+    /// </summary>
+    Brown = 0xA52A2A,
+
+    /// <summary>
+    /// Burly wood RGB(222, 184, 135).
+    /// </summary>
+    BurlyWood = 0xDEB887,
+
+    /// <summary>
+    /// Cadet blue RGB(95, 158, 160).
+    /// </summary>
+    CadetBlue = 0x5F9EA0,
+
+    /// <summary>
+    /// Chartreuse RGB(127, 255, 0).
+    /// </summary>
+    Chartreuse = 0x7FFF00,
+
+    /// <summary>
+    /// Chocolate RGB(210, 105, 30).
+    /// </summary>
+    Chocolate = 0xD2691E,
+
+    /// <summary>
+    /// Coral RGB(255, 127, 80).
+    /// </summary>
+    Coral = 0xFF7F50,
+
+    /// <summary>
+    /// Cornflower blue RGB(100, 149, 237).
+    /// </summary>
+    CornflowerBlue = 0x6495ED,
+
+    /// <summary>
+    /// Cornsilk RGB(255, 248, 220).
+    /// </summary>
+    Cornsilk = 0xFFF8DC,
+
+    /// <summary>
+    /// Crimson RGB(220, 20, 60).
+    /// </summary>
+    Crimson = 0xDC143C,
+
+    /// <summary>
+    /// Cyan RGB(0, 255, 255).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="Aqua"/>.
+    /// </remarks>
+    Cyan = Aqua,
+
+    /// <summary>
+    /// Dark blue RGB(0, 0, 139).
+    /// </summary>
+    DarkBlue = 0x00008B,
+
+    /// <summary>
+    /// Dark cyan RGB(0, 139, 139).
+    /// </summary>
+    DarkCyan = 0x008B8B,
+
+    /// <summary>
+    /// Dark goldenrod RGB(184, 134, 11).
+    /// </summary>
+    DarkGoldenrod = 0xB8860B,
+
+    /// <summary>
+    /// Dark gray RGB(169, 169, 169).
+    /// </summary>
+    DarkGray = 0xA9A9A9,
+
+    /// <summary>
+    /// Dark green RGB(0, 100, 0).
+    /// </summary>
+    DarkGreen = 0x006400,
+
+    /// <summary>
+    /// Dark grey RGB(169, 169, 169).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="DarkGray"/>.
+    /// </remarks>
+    DarkGrey = DarkGray,
+
+    /// <summary>
+    /// Dark khaki RGB(189, 183, 107).
+    /// </summary>
+    DarkKhaki = 0xBDB76B,
+
+    /// <summary>
+    /// Dark magenta RGB(139, 0, 139).
+    /// </summary>
+    DarkMagenta = 0x8B008B,
+
+    /// <summary>
+    /// Dark olive green RGB(85, 107, 47).
+    /// </summary>
+    DarkOliveGreen = 0x556B2F,
+
+    /// <summary>
+    /// Dark orange RGB(255, 140, 0).
+    /// </summary>
+    DarkOrange = 0xFF8C00,
+
+    /// <summary>
+    /// Dark orchid RGB(153, 50, 204).
+    /// </summary>
+    DarkOrchid = 0x9932CC,
+
+    /// <summary>
+    /// Dark red RGB(139, 0, 0).
+    /// </summary>
+    DarkRed = 0x8B0000,
+
+    /// <summary>
+    /// Dark salmon RGB(233, 150, 122).
+    /// </summary>
+    DarkSalmon = 0xE9967A,
+
+    /// <summary>
+    /// Dark sea green RGB(143, 188, 143).
+    /// </summary>
+    DarkSeaGreen = 0x8FBC8F,
+
+    /// <summary>
+    /// Dark slate blue RGB(72, 61, 139).
+    /// </summary>
+    DarkSlateBlue = 0x483D8B,
+
+    /// <summary>
+    /// Dark slate gray RGB(47, 79, 79).
+    /// </summary>
+    DarkSlateGray = 0x2F4F4F,
+
+    /// <summary>
+    /// Dark slate grey RGB(47, 79, 79).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="DarkSlateGray"/>.
+    /// </remarks>
+    DarkSlateGrey = DarkSlateGray,
+
+    /// <summary>
+    /// Dark turquoise RGB(0, 206, 209).
+    /// </summary>
+    DarkTurquoise = 0x00CED1,
+
+    /// <summary>
+    /// Dark violet RGB(148, 0, 211).
+    /// </summary>
+    DarkViolet = 0x9400D3,
+
+    /// <summary>
+    /// Deep pink RGB(255, 20, 147).
+    /// </summary>
+    DeepPink = 0xFF1493,
+
+    /// <summary>
+    /// Deep sky blue RGB(0, 191, 255).
+    /// </summary>
+    DeepSkyBlue = 0x00BFFF,
+
+    /// <summary>
+    /// Dim gray RGB(105, 105, 105).
+    /// </summary>
+    DimGray = 0x696969,
+
+    /// <summary>
+    /// Dim grey RGB(105, 105, 105).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="DimGray"/>.
+    /// </remarks>
+    DimGrey = DimGray,
+
+    /// <summary>
+    /// Dodger blue RGB(30, 144, 255).
+    /// </summary>
+    DodgerBlue = 0x1E90FF,
+
+    /// <summary>
+    /// Fire brick RGB(178, 34, 34).
+    /// </summary>
+    FireBrick = 0xB22222,
+
+    /// <summary>
+    /// Floral white RGB(255, 250, 240).
+    /// </summary>
+    FloralWhite = 0xFFFAF0,
+
+    /// <summary>
+    /// Forest green RGB(34, 139, 34).
+    /// </summary>
+    ForestGreen = 0x228B22,
+
+    /// <summary>
+    /// Fuchsia RGB(255, 0, 255).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="Magenta"/>.
+    /// </remarks>
+    Fuchsia = Magenta,
+
+    /// <summary>
+    /// Gainsboro RGB(220, 220, 220).
+    /// </summary>
+    Gainsboro = 0xDCDCDC,
+
+    /// <summary>
+    /// Ghost white RGB(248, 248, 255).
+    /// </summary>
+    GhostWhite = 0xF8F8FF,
+
+    /// <summary>
+    /// Gold RGB(255, 215, 0).
+    /// </summary>
+    Gold = 0xFFD700,
+
+    /// <summary>
+    /// Goldenrod RGB(218, 165, 32).
+    /// </summary>
+    Goldenrod = 0xDAA520,
+
+    /// <summary>
+    /// Gray RGB(128, 128, 128).
+    /// </summary>
+    Gray = 0x808080,
+
+    /// <summary>
+    /// Green RGB(0, 128, 0).
+    /// </summary>
+    Green = 0x008000,
+
+    /// <summary>
+    /// Green yellow RGB(173, 255, 47).
+    /// </summary>
+    GreenYellow = 0xADFF2F,
+
+    /// <summary>
+    /// Grey RGB(128, 128, 128).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="Gray"/>.
+    /// </remarks>
+    Grey = Gray,
+
+    /// <summary>
+    /// Honey dew RGB(240, 255, 240).
+    /// </summary>
+    HoneyDew = 0xF0FFF0,
+
+    /// <summary>
+    /// Hot pink RGB(255, 105, 180).
+    /// </summary>
+    HotPink = 0xFF69B4,
+
+    /// <summary>
+    /// Indian red RGB(205, 92, 92).
+    /// </summary>
+    IndianRed = 0xCD5C5C,
+
+    /// <summary>
+    /// Indigo RGB(75, 0, 130).
+    /// </summary>
+    Indigo = 0x4B0082,
+
+    /// <summary>
+    /// Ivory RGB(255, 255, 240).
+    /// </summary>
+    Ivory = 0xFFFFF0,
+
+    /// <summary>
+    /// Khaki RGB(240, 230, 140).
+    /// </summary>
+    Khaki = 0xF0E68C,
+
+    /// <summary>
+    /// Lavender RGB(230, 230, 250).
+    /// </summary>
+    Lavender = 0xE6E6FA,
+
+    /// <summary>
+    /// Lavender blush RGB(255, 240, 245).
+    /// </summary>
+    LavenderBlush = 0xFFF0F5,
+
+    /// <summary>
+    /// Lawn green RGB(124, 252, 0).
+    /// </summary>
+    LawnGreen = 0x7CFC00,
+
+    /// <summary>
+    /// Lemon chiffon RGB(255, 250, 205).
+    /// </summary>
+    LemonChiffon = 0xFFFACD,
+
+    /// <summary>
+    /// Light blue RGB(173, 216, 230).
+    /// </summary>
+    LightBlue = 0xADD8E6,
+
+    /// <summary>
+    /// Light coral RGB(240, 128, 128).
+    /// </summary>
+    LightCoral = 0xF08080,
+
+    /// <summary>
+    /// Light cyan RGB(224, 255, 255).
+    /// </summary>
+    LightCyan = 0xE0FFFF,
+
+    /// <summary>
+    /// Light goldenrod yellow RGB(250, 250, 210).
+    /// </summary>
+    LightGoldenrodYellow = 0xFAFAD2,
+
+    /// <summary>
+    /// Light gray RGB(211, 211, 211).
+    /// </summary>
+    LightGray = 0xD3D3D3,
+
+    /// <summary>
+    /// Light green RGB(144, 238, 144).
+    /// </summary>
+    LightGreen = 0x90EE90,
+
+    /// <summary>
+    /// Light grey RGB(211, 211, 211).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="LightGray"/>.
+    /// </remarks>
+    LightGrey = LightGray,
+
+    /// <summary>
+    /// Light pink RGB(255, 182, 193).
+    /// </summary>
+    LightPink = 0xFFB6C1,
+
+    /// <summary>
+    /// Light salmon RGB(255, 160, 122).
+    /// </summary>
+    LightSalmon = 0xFFA07A,
+
+    /// <summary>
+    /// Light sea green RGB(32, 178, 170).
+    /// </summary>
+    LightSeaGreen = 0x20B2AA,
+
+    /// <summary>
+    /// Light sky blue RGB(135, 206, 250).
+    /// </summary>
+    LightSkyBlue = 0x87CEFA,
+
+    /// <summary>
+    /// Light slate gray RGB(119, 136, 153).
+    /// </summary>
+    LightSlateGray = 0x778899,
+
+    /// <summary>
+    /// Light slate grey RGB(119, 136, 153).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="LightSlateGray"/>.
+    /// </remarks>
+    LightSlateGrey = LightSlateGray,
+
+    /// <summary>
+    /// Light steel blue RGB(176, 196, 222).
+    /// </summary>
+    LightSteelBlue = 0xB0C4DE,
+
+    /// <summary>
+    /// Light yellow RGB(255, 255, 224).
+    /// </summary>
+    LightYellow = 0xFFFFE0,
+
+    /// <summary>
+    /// Lime RGB(0, 255, 0).
+    /// </summary>
+    Lime = 0x00FF00,
+
+    /// <summary>
+    /// Lime green RGB(50, 205, 50).
+    /// </summary>
+    LimeGreen = 0x32CD32,
+
+    /// <summary>
+    /// Linen RGB(250, 240, 230).
+    /// </summary>
+    Linen = 0xFAF0E6,
+
+    /// <summary>
+    /// Magenta RGB(255, 0, 255).
+    /// </summary>
+    Magenta = 0xFF00FF,
+
+    /// <summary>
+    /// Maroon RGB(128, 0, 0).
+    /// </summary>
+    Maroon = 0x800000,
+
+    /// <summary>
+    /// Medium aqua marine RGB(102, 205, 170).
+    /// </summary>
+    MediumAquaMarine = 0x66CDAA,
+
+    /// <summary>
+    /// Medium blue RGB(0, 0, 205).
+    /// </summary>
+    MediumBlue = 0x0000CD,
+
+    /// <summary>
+    /// Medium orchid RGB(186, 85, 211).
+    /// </summary>
+    MediumOrchid = 0xBA55D3,
+
+    /// <summary>
+    /// Medium purple RGB(147, 112, 219).
+    /// </summary>
+    MediumPurple = 0x9370DB,
+
+    /// <summary>
+    /// Medium sea green RGB(60, 179, 113).
+    /// </summary>
+    MediumSeaGreen = 0x3CB371,
+
+    /// <summary>
+    /// Medium slate blue RGB(123, 104, 238).
+    /// </summary>
+    MediumSlateBlue = 0x7B68EE,
+
+    /// <summary>
+    /// Medium spring green RGB(0, 250, 154).
+    /// </summary>
+    MediumSpringGreen = 0x00FA9A,
+
+    /// <summary>
+    /// Medium turquoise RGB(72, 209, 204).
+    /// </summary>
+    MediumTurquoise = 0x48D1CC,
+
+    /// <summary>
+    /// Medium violet red RGB(199, 21, 133).
+    /// </summary>
+    MediumVioletRed = 0xC71585,
+
+    /// <summary>
+    /// Midnight blue RGB(25, 25, 112).
+    /// </summary>
+    MidnightBlue = 0x191970,
+
+    /// <summary>
+    /// Mint cream RGB(245, 255, 250).
+    /// </summary>
+    MintCream = 0xF5FFFA,
+
+    /// <summary>
+    /// Misty rose RGB(255, 228, 225).
+    /// </summary>
+    MistyRose = 0xFFE4E1,
+
+    /// <summary>
+    /// Moccasin RGB(255, 228, 181).
+    /// </summary>
+    Moccasin = 0xFFE4B5,
+
+    /// <summary>
+    /// Navajo white RGB(255, 222, 173).
+    /// </summary>
+    NavajoWhite = 0xFFDEAD,
+
+    /// <summary>
+    /// Navy RGB(0, 0, 128).
+    /// </summary>
+    Navy = 0x000080,
+
+    /// <summary>
+    /// Old lace RGB(253, 245, 230).
+    /// </summary>
+    OldLace = 0xFDF5E6,
+
+    /// <summary>
+    /// Olive RGB(128, 128, 0).
+    /// </summary>
+    Olive = 0x808000,
+
+    /// <summary>
+    /// Olive drab RGB(107, 142, 35).
+    /// </summary>
+    OliveDrab = 0x6B8E23,
+
+    /// <summary>
+    /// Orange RGB(255, 165, 0).
+    /// </summary>
+    Orange = 0xFFA500,
+
+    /// <summary>
+    /// Orange red RGB(255, 69, 0).
+    /// </summary>
+    OrangeRed = 0xFF4500,
+
+    /// <summary>
+    /// Orchid RGB(218, 112, 214).
+    /// </summary>
+    Orchid = 0xDA70D6,
+
+    /// <summary>
+    /// Pale goldenrod RGB(238, 232, 170).
+    /// </summary>
+    PaleGoldenrod = 0xEEE8AA,
+
+    /// <summary>
+    /// Pale green RGB(152, 251, 152).
+    /// </summary>
+    PaleGreen = 0x98FB98,
+
+    /// <summary>
+    /// Pale turquoise RGB(175, 238, 238).
+    /// </summary>
+    PaleTurquoise = 0xAFEEEE,
+
+    /// <summary>
+    /// Pale violet red RGB(219, 112, 147).
+    /// </summary>
+    PaleVioletRed = 0xDB7093,
+
+    /// <summary>
+    /// Papaya whip RGB(255, 239, 213).
+    /// </summary>
+    PapayaWhip = 0xFFEFD5,
+
+    /// <summary>
+    /// Peach puff RGB(255, 218, 185).
+    /// </summary>
+    PeachPuff = 0xFFDAB9,
+
+    /// <summary>
+    /// Peru RGB(205, 133, 63).
+    /// </summary>
+    Peru = 0xCD853F,
+
+    /// <summary>
+    /// Pink RGB(255, 192, 203).
+    /// </summary>
+    Pink = 0xFFC0CB,
+
+    /// <summary>
+    /// Plum RGB(221, 160, 221).
+    /// </summary>
+    Plum = 0xDDA0DD,
+
+    /// <summary>
+    /// Powder blue RGB(176, 224, 230).
+    /// </summary>
+    PowderBlue = 0xB0E0E6,
+
+    /// <summary>
+    /// Purple RGB(128, 0, 128).
+    /// </summary>
+    Purple = 0x800080,
+
+    /// <summary>
+    /// Rebecca purple RGB(102, 51, 153).
+    /// </summary>
+    RebeccaPurple = 0x663399,
+
+    /// <summary>
+    /// Red RGB(255, 0, 0).
+    /// </summary>
+    Red = 0xFF0000,
+
+    /// <summary>
+    /// Rosy brown RGB(188, 143, 143).
+    /// </summary>
+    RosyBrown = 0xBC8F8F,
+
+    /// <summary>
+    /// Royal blue RGB(65, 105, 225).
+    /// </summary>
+    RoyalBlue = 0x4169E1,
+
+    /// <summary>
+    /// Saddle brown RGB(139, 69, 19).
+    /// </summary>
+    SaddleBrown = 0x8B4513,
+
+    /// <summary>
+    /// Salmon RGB(250, 128, 114).
+    /// </summary>
+    Salmon = 0xFA8072,
+
+    /// <summary>
+    /// Sandy brown RGB(244, 164, 96).
+    /// </summary>
+    SandyBrown = 0xF4A460,
+
+    /// <summary>
+    /// Sea green RGB(46, 139, 87).
+    /// </summary>
+    SeaGreen = 0x2E8B57,
+
+    /// <summary>
+    /// Sea shell RGB(255, 245, 238).
+    /// </summary>
+    SeaShell = 0xFFF5EE,
+
+    /// <summary>
+    /// Sienna RGB(160, 82, 45).
+    /// </summary>
+    Sienna = 0xA0522D,
+
+    /// <summary>
+    /// Silver RGB(192, 192, 192).
+    /// </summary>
+    Silver = 0xC0C0C0,
+
+    /// <summary>
+    /// Sky blue RGB(135, 206, 235).
+    /// </summary>
+    SkyBlue = 0x87CEEB,
+
+    /// <summary>
+    /// Slate blue RGB(106, 90, 205).
+    /// </summary>
+    SlateBlue = 0x6A5ACD,
+
+    /// <summary>
+    /// Slate gray RGB(112, 128, 144).
+    /// </summary>
+    SlateGray = 0x708090,
+
+    /// <summary>
+    /// Slate grey RGB(112, 128, 144).
+    /// </summary>
+    /// <remarks>
+    /// Same as <see cref="SlateGray"/>.
+    /// </remarks>
+    SlateGrey = SlateGray,
+
+    /// <summary>
+    /// Snow RGB(255, 250, 250).
+    /// </summary>
+    Snow = 0xFFFAFA,
+
+    /// <summary>
+    /// Spring green RGB(0, 255, 127).
+    /// </summary>
+    SpringGreen = 0x00FF7F,
+
+    /// <summary>
+    /// Steel blue RGB(70, 130, 180).
+    /// </summary>
+    SteelBlue = 0x4682B4,
+
+    /// <summary>
+    /// Tan RGB(210, 180, 140).
+    /// </summary>
+    Tan = 0xD2B48C,
+
+    /// <summary>
+    /// Teal RGB(0, 128, 128).
+    /// </summary>
+    Teal = 0x008080,
+
+    /// <summary>
+    /// Thistle RGB(216, 191, 216).
+    /// </summary>
+    Thistle = 0xD8BFD8,
+
+    /// <summary>
+    /// Tomato RGB(255, 99, 71).
+    /// </summary>
+    Tomato = 0xFF6347,
+
+    /// <summary>
+    /// Turquoise RGB(64, 224, 208).
+    /// </summary>
+    Turquoise = 0x40E0D0,
+
+    /// <summary>
+    /// Violet RGB(238, 130, 238).
+    /// </summary>
+    Violet = 0xEE82EE,
+
+    /// <summary>
+    /// Wheat RGB(245, 222, 179).
+    /// </summary>
+    Wheat = 0xF5DEB3,
+
+    /// <summary>
+    /// White RGB(255, 255, 255).
+    /// </summary>
+    White = 0xFFFFFF,
+
+    /// <summary>
+    /// White smoke RGB(245, 245, 245).
+    /// </summary>
+    WhiteSmoke = 0xF5F5F5,
+
+    /// <summary>
+    /// Yellow RGB(255, 255, 0).
+    /// </summary>
+    Yellow = 0xFFFF00,
+
+    /// <summary>
+    /// Yellow green RGB(154, 205, 50).
+    /// </summary>
+    YellowGreen = 0x9ACD32
+}

+ 110 - 0
Terminal.Gui/Drawing/Color/W3cColorNameResolver.cs

@@ -0,0 +1,110 @@
+#nullable enable
+
+using System.Collections.Frozen;
+using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Terminal.Gui;
+
+/// <summary>
+/// W3C color name resolver.
+/// </summary>
+public class W3cColorNameResolver : IColorNameResolver
+{
+    /// <inheritdoc/>
+    public IEnumerable<string> GetColorNames () =>
+        W3cColors.GetColorNames ();
+
+    /// <inheritdoc/>
+    public bool TryParseColor (ReadOnlySpan<char> name, out Color color) =>
+        W3cColors.TryParseColor (name, out color);
+
+    /// <inheritdoc/>
+    public bool TryNameColor (Color color, [NotNullWhen (true)] out string? name) =>
+        W3cColors.TryNameColor (color, out name);
+}
+
+/// <summary>
+/// Helper class for transforming to and from <see cref="W3cColor"/> enum.
+/// </summary>
+internal static class W3cColors
+{
+    private static readonly ImmutableArray<string> Names;
+    private static readonly FrozenDictionary<uint, string> ArgbNameMap;
+
+    static W3cColors ()
+    {
+        // Populate based on names because enums with same numerical value
+        // are not otherwise distinguishable from each other.
+        string[] w3cNames = Enum.GetNames<W3cColor> ().Order().ToArray();
+
+        Dictionary<uint, string> map = new(w3cNames.Length);
+        foreach (string name in w3cNames)
+        {
+            W3cColor w3c = Enum.Parse<W3cColor>(name);
+            uint argb = GetArgb(w3c);
+            // TODO: Collect aliases?
+            _ = map.TryAdd (argb, name);
+        }
+
+        Names = ImmutableArray.Create (w3cNames);
+        ArgbNameMap = map.ToFrozenDictionary ();
+    }
+
+    /// <summary>
+    /// Gets read-only list of the W3C colors in alphabetical order.
+    /// </summary>
+    public static IReadOnlyList<string> GetColorNames ()
+    {
+        return Names;
+    }
+
+    /// <summary>
+    /// Converts the given W3C color name to equivalent color value.
+    /// </summary>
+    /// <param name="name">W3C color name.</param>
+    /// <param name="color">The successfully converted W3C color value.</param>
+    /// <returns>True if the conversion succeeded; otherwise false.</returns>
+    public static bool TryParseColor (ReadOnlySpan<char> name, out Color color)
+    {
+        if (!Enum.TryParse (name, ignoreCase: true, out W3cColor w3cColor) ||
+            // Any numerical value converts to undefined enum value.
+            !Enum.IsDefined (w3cColor))
+        {
+            color = default;
+            return false;
+        }
+
+        uint argb = GetArgb (w3cColor);
+        color = new Color (argb);
+        return true;
+    }
+
+    /// <summary>
+    /// Converts the given color value to a W3C color name.
+    /// </summary>
+    /// <param name="color">Color value to match W3C color.</param>
+    /// <param name="name">The successfully converted W3C color name.</param>
+    /// <returns>True if conversion succeeded; otherwise false.</returns>
+    public static bool TryNameColor (Color color, [NotNullWhen (true)] out string? name)
+    {
+        if (ArgbNameMap.TryGetValue (color.Argb, out name))
+        {
+            return true;
+        }
+
+        name = null;
+        return false;
+    }
+
+    private static uint GetArgb (W3cColor w3cColor)
+    {
+        const int alphaShift = 24;
+        const uint alphaMask = 0xFFU << alphaShift;
+
+        int rgb = (int)w3cColor;
+
+        uint argb = (uint)rgb | alphaMask;
+        return argb;
+    }
+}

+ 0 - 1314
Terminal.Gui/Resources/Strings.Designer.cs

@@ -60,1320 +60,6 @@ namespace Terminal.Gui.Resources {
             }
         }
         
-        /// <summary>
-        ///   Looks up a localized string similar to Black.
-        /// </summary>
-        internal static string _000000 {
-            get {
-                return ResourceManager.GetString("#000000", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Navy.
-        /// </summary>
-        internal static string _000080 {
-            get {
-                return ResourceManager.GetString("#000080", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkBlue.
-        /// </summary>
-        internal static string _00008B {
-            get {
-                return ResourceManager.GetString("#00008B", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumBlue.
-        /// </summary>
-        internal static string _0000CD {
-            get {
-                return ResourceManager.GetString("#0000CD", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Blue.
-        /// </summary>
-        internal static string _0000FF {
-            get {
-                return ResourceManager.GetString("#0000FF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkGreen.
-        /// </summary>
-        internal static string _006400 {
-            get {
-                return ResourceManager.GetString("#006400", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Green.
-        /// </summary>
-        internal static string _008000 {
-            get {
-                return ResourceManager.GetString("#008000", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Teal.
-        /// </summary>
-        internal static string _008080 {
-            get {
-                return ResourceManager.GetString("#008080", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkCyan.
-        /// </summary>
-        internal static string _008B8B {
-            get {
-                return ResourceManager.GetString("#008B8B", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DeepSkyBlue.
-        /// </summary>
-        internal static string _00BFFF {
-            get {
-                return ResourceManager.GetString("#00BFFF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkTurquoise.
-        /// </summary>
-        internal static string _00CED1 {
-            get {
-                return ResourceManager.GetString("#00CED1", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumSpringGreen.
-        /// </summary>
-        internal static string _00FA9A {
-            get {
-                return ResourceManager.GetString("#00FA9A", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Lime.
-        /// </summary>
-        internal static string _00FF00 {
-            get {
-                return ResourceManager.GetString("#00FF00", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SpringGreen.
-        /// </summary>
-        internal static string _00FF7F {
-            get {
-                return ResourceManager.GetString("#00FF7F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cyan.
-        /// </summary>
-        internal static string _00FFFF {
-            get {
-                return ResourceManager.GetString("#00FFFF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BrightGreen.
-        /// </summary>
-        internal static string _16C60C {
-            get {
-                return ResourceManager.GetString("#16C60C", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MidnightBlue.
-        /// </summary>
-        internal static string _191970 {
-            get {
-                return ResourceManager.GetString("#191970", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DodgerBlue.
-        /// </summary>
-        internal static string _1E90FF {
-            get {
-                return ResourceManager.GetString("#1E90FF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightSeaGreen.
-        /// </summary>
-        internal static string _20B2AA {
-            get {
-                return ResourceManager.GetString("#20B2AA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to ForestGreen.
-        /// </summary>
-        internal static string _228B22 {
-            get {
-                return ResourceManager.GetString("#228B22", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SeaGreen.
-        /// </summary>
-        internal static string _2E8B57 {
-            get {
-                return ResourceManager.GetString("#2E8B57", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkSlateGrey.
-        /// </summary>
-        internal static string _2F4F4F {
-            get {
-                return ResourceManager.GetString("#2F4F4F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LimeGreen.
-        /// </summary>
-        internal static string _32CD32 {
-            get {
-                return ResourceManager.GetString("#32CD32", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BrightBlue.
-        /// </summary>
-        internal static string _3B78FF {
-            get {
-                return ResourceManager.GetString("#3B78FF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumSeaGreen.
-        /// </summary>
-        internal static string _3CB371 {
-            get {
-                return ResourceManager.GetString("#3CB371", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Turquoise.
-        /// </summary>
-        internal static string _40E0D0 {
-            get {
-                return ResourceManager.GetString("#40E0D0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to RoyalBlue.
-        /// </summary>
-        internal static string _4169E1 {
-            get {
-                return ResourceManager.GetString("#4169E1", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SteelBlue.
-        /// </summary>
-        internal static string _4682B4 {
-            get {
-                return ResourceManager.GetString("#4682B4", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkSlateBlue.
-        /// </summary>
-        internal static string _483D8B {
-            get {
-                return ResourceManager.GetString("#483D8B", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumTurquoise.
-        /// </summary>
-        internal static string _48D1CC {
-            get {
-                return ResourceManager.GetString("#48D1CC", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Indigo.
-        /// </summary>
-        internal static string _4B0082 {
-            get {
-                return ResourceManager.GetString("#4B0082", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkOliveGreen.
-        /// </summary>
-        internal static string _556B2F {
-            get {
-                return ResourceManager.GetString("#556B2F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to CadetBlue.
-        /// </summary>
-        internal static string _5F9EA0 {
-            get {
-                return ResourceManager.GetString("#5F9EA0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BrightCyan.
-        /// </summary>
-        internal static string _61D6D6 {
-            get {
-                return ResourceManager.GetString("#61D6D6", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to CornflowerBlue.
-        /// </summary>
-        internal static string _6495ED {
-            get {
-                return ResourceManager.GetString("#6495ED", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to RebeccaPurple.
-        /// </summary>
-        internal static string _663399 {
-            get {
-                return ResourceManager.GetString("#663399", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumAquaMarine.
-        /// </summary>
-        internal static string _66CDAA {
-            get {
-                return ResourceManager.GetString("#66CDAA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DimGray.
-        /// </summary>
-        internal static string _696969 {
-            get {
-                return ResourceManager.GetString("#696969", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SlateBlue.
-        /// </summary>
-        internal static string _6A5ACD {
-            get {
-                return ResourceManager.GetString("#6A5ACD", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to OliveDrab.
-        /// </summary>
-        internal static string _6B8E23 {
-            get {
-                return ResourceManager.GetString("#6B8E23", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SlateGray.
-        /// </summary>
-        internal static string _708090 {
-            get {
-                return ResourceManager.GetString("#708090", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkGray.
-        /// </summary>
-        internal static string _767676 {
-            get {
-                return ResourceManager.GetString("#767676", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightSlateGrey.
-        /// </summary>
-        internal static string _778899 {
-            get {
-                return ResourceManager.GetString("#778899", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumSlateBlue.
-        /// </summary>
-        internal static string _7B68EE {
-            get {
-                return ResourceManager.GetString("#7B68EE", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LawnGreen.
-        /// </summary>
-        internal static string _7CFC00 {
-            get {
-                return ResourceManager.GetString("#7CFC00", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Chartreuse.
-        /// </summary>
-        internal static string _7FFF00 {
-            get {
-                return ResourceManager.GetString("#7FFF00", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Aquamarine.
-        /// </summary>
-        internal static string _7FFFD4 {
-            get {
-                return ResourceManager.GetString("#7FFFD4", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Maroon.
-        /// </summary>
-        internal static string _800000 {
-            get {
-                return ResourceManager.GetString("#800000", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Purple.
-        /// </summary>
-        internal static string _800080 {
-            get {
-                return ResourceManager.GetString("#800080", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Olive.
-        /// </summary>
-        internal static string _808000 {
-            get {
-                return ResourceManager.GetString("#808000", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Gray.
-        /// </summary>
-        internal static string _808080 {
-            get {
-                return ResourceManager.GetString("#808080", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SkyBlue.
-        /// </summary>
-        internal static string _87CEEB {
-            get {
-                return ResourceManager.GetString("#87CEEB", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightSkyBlue.
-        /// </summary>
-        internal static string _87CEFA {
-            get {
-                return ResourceManager.GetString("#87CEFA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BlueViolet.
-        /// </summary>
-        internal static string _8A2BE2 {
-            get {
-                return ResourceManager.GetString("#8A2BE2", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkRed.
-        /// </summary>
-        internal static string _8B0000 {
-            get {
-                return ResourceManager.GetString("#8B0000", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkMagenta.
-        /// </summary>
-        internal static string _8B008B {
-            get {
-                return ResourceManager.GetString("#8B008B", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SaddleBrown.
-        /// </summary>
-        internal static string _8B4513 {
-            get {
-                return ResourceManager.GetString("#8B4513", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkSeaGreen.
-        /// </summary>
-        internal static string _8FBC8F {
-            get {
-                return ResourceManager.GetString("#8FBC8F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightGreen.
-        /// </summary>
-        internal static string _90EE90 {
-            get {
-                return ResourceManager.GetString("#90EE90", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumPurple.
-        /// </summary>
-        internal static string _9370DB {
-            get {
-                return ResourceManager.GetString("#9370DB", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkViolet.
-        /// </summary>
-        internal static string _9400D3 {
-            get {
-                return ResourceManager.GetString("#9400D3", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PaleGreen.
-        /// </summary>
-        internal static string _98FB98 {
-            get {
-                return ResourceManager.GetString("#98FB98", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkOrchid.
-        /// </summary>
-        internal static string _9932CC {
-            get {
-                return ResourceManager.GetString("#9932CC", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to YellowGreen.
-        /// </summary>
-        internal static string _9ACD32 {
-            get {
-                return ResourceManager.GetString("#9ACD32", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Sienna.
-        /// </summary>
-        internal static string _A0522D {
-            get {
-                return ResourceManager.GetString("#A0522D", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Brown.
-        /// </summary>
-        internal static string _A52A2A {
-            get {
-                return ResourceManager.GetString("#A52A2A", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkGrey.
-        /// </summary>
-        internal static string _A9A9A9 {
-            get {
-                return ResourceManager.GetString("#A9A9A9", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightBlue.
-        /// </summary>
-        internal static string _ADD8E6 {
-            get {
-                return ResourceManager.GetString("#ADD8E6", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to GreenYellow.
-        /// </summary>
-        internal static string _ADFF2F {
-            get {
-                return ResourceManager.GetString("#ADFF2F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PaleTurquoise.
-        /// </summary>
-        internal static string _AFEEEE {
-            get {
-                return ResourceManager.GetString("#AFEEEE", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightSteelBlue.
-        /// </summary>
-        internal static string _B0C4DE {
-            get {
-                return ResourceManager.GetString("#B0C4DE", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PowderBlue.
-        /// </summary>
-        internal static string _B0E0E6 {
-            get {
-                return ResourceManager.GetString("#B0E0E6", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to FireBrick.
-        /// </summary>
-        internal static string _B22222 {
-            get {
-                return ResourceManager.GetString("#B22222", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BrightMagenta.
-        /// </summary>
-        internal static string _B4009E {
-            get {
-                return ResourceManager.GetString("#B4009E", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkGoldenRod.
-        /// </summary>
-        internal static string _B8860B {
-            get {
-                return ResourceManager.GetString("#B8860B", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumOrchid.
-        /// </summary>
-        internal static string _BA55D3 {
-            get {
-                return ResourceManager.GetString("#BA55D3", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to RosyBrown.
-        /// </summary>
-        internal static string _BC8F8F {
-            get {
-                return ResourceManager.GetString("#BC8F8F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkKhaki.
-        /// </summary>
-        internal static string _BDB76B {
-            get {
-                return ResourceManager.GetString("#BDB76B", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Silver.
-        /// </summary>
-        internal static string _C0C0C0 {
-            get {
-                return ResourceManager.GetString("#C0C0C0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MediumVioletRed.
-        /// </summary>
-        internal static string _C71585 {
-            get {
-                return ResourceManager.GetString("#C71585", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to IndianRed.
-        /// </summary>
-        internal static string _CD5C5C {
-            get {
-                return ResourceManager.GetString("#CD5C5C", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Peru.
-        /// </summary>
-        internal static string _CD853F {
-            get {
-                return ResourceManager.GetString("#CD853F", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Chocolate.
-        /// </summary>
-        internal static string _D2691E {
-            get {
-                return ResourceManager.GetString("#D2691E", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Tan.
-        /// </summary>
-        internal static string _D2B48C {
-            get {
-                return ResourceManager.GetString("#D2B48C", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightGray.
-        /// </summary>
-        internal static string _D3D3D3 {
-            get {
-                return ResourceManager.GetString("#D3D3D3", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Thistle.
-        /// </summary>
-        internal static string _D8BFD8 {
-            get {
-                return ResourceManager.GetString("#D8BFD8", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Orchid.
-        /// </summary>
-        internal static string _DA70D6 {
-            get {
-                return ResourceManager.GetString("#DA70D6", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to GoldenRod.
-        /// </summary>
-        internal static string _DAA520 {
-            get {
-                return ResourceManager.GetString("#DAA520", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PaleVioletRed.
-        /// </summary>
-        internal static string _DB7093 {
-            get {
-                return ResourceManager.GetString("#DB7093", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Crimson.
-        /// </summary>
-        internal static string _DC143C {
-            get {
-                return ResourceManager.GetString("#DC143C", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Gainsboro.
-        /// </summary>
-        internal static string _DCDCDC {
-            get {
-                return ResourceManager.GetString("#DCDCDC", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Plum.
-        /// </summary>
-        internal static string _DDA0DD {
-            get {
-                return ResourceManager.GetString("#DDA0DD", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BurlyWood.
-        /// </summary>
-        internal static string _DEB887 {
-            get {
-                return ResourceManager.GetString("#DEB887", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightCyan.
-        /// </summary>
-        internal static string _E0FFFF {
-            get {
-                return ResourceManager.GetString("#E0FFFF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Lavender.
-        /// </summary>
-        internal static string _E6E6FA {
-            get {
-                return ResourceManager.GetString("#E6E6FA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BrightRed.
-        /// </summary>
-        internal static string _E74856 {
-            get {
-                return ResourceManager.GetString("#E74856", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkSalmon.
-        /// </summary>
-        internal static string _E9967A {
-            get {
-                return ResourceManager.GetString("#E9967A", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Violet.
-        /// </summary>
-        internal static string _EE82EE {
-            get {
-                return ResourceManager.GetString("#EE82EE", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PaleGoldenRod.
-        /// </summary>
-        internal static string _EEE8AA {
-            get {
-                return ResourceManager.GetString("#EEE8AA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightCoral.
-        /// </summary>
-        internal static string _F08080 {
-            get {
-                return ResourceManager.GetString("#F08080", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Khaki.
-        /// </summary>
-        internal static string _F0E68C {
-            get {
-                return ResourceManager.GetString("#F0E68C", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to AliceBlue.
-        /// </summary>
-        internal static string _F0F8FF {
-            get {
-                return ResourceManager.GetString("#F0F8FF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to HoneyDew.
-        /// </summary>
-        internal static string _F0FFF0 {
-            get {
-                return ResourceManager.GetString("#F0FFF0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Azure.
-        /// </summary>
-        internal static string _F0FFFF {
-            get {
-                return ResourceManager.GetString("#F0FFFF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SandyBrown.
-        /// </summary>
-        internal static string _F4A460 {
-            get {
-                return ResourceManager.GetString("#F4A460", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Wheat.
-        /// </summary>
-        internal static string _F5DEB3 {
-            get {
-                return ResourceManager.GetString("#F5DEB3", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Beige.
-        /// </summary>
-        internal static string _F5F5DC {
-            get {
-                return ResourceManager.GetString("#F5F5DC", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to WhiteSmoke.
-        /// </summary>
-        internal static string _F5F5F5 {
-            get {
-                return ResourceManager.GetString("#F5F5F5", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MintCream.
-        /// </summary>
-        internal static string _F5FFFA {
-            get {
-                return ResourceManager.GetString("#F5FFFA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to GhostWhite.
-        /// </summary>
-        internal static string _F8F8FF {
-            get {
-                return ResourceManager.GetString("#F8F8FF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BrightYellow.
-        /// </summary>
-        internal static string _F9F1A5 {
-            get {
-                return ResourceManager.GetString("#F9F1A5", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Salmon.
-        /// </summary>
-        internal static string _FA8072 {
-            get {
-                return ResourceManager.GetString("#FA8072", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to AntiqueWhite.
-        /// </summary>
-        internal static string _FAEBD7 {
-            get {
-                return ResourceManager.GetString("#FAEBD7", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Linen.
-        /// </summary>
-        internal static string _FAF0E6 {
-            get {
-                return ResourceManager.GetString("#FAF0E6", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightGoldenRodYellow.
-        /// </summary>
-        internal static string _FAFAD2 {
-            get {
-                return ResourceManager.GetString("#FAFAD2", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to OldLace.
-        /// </summary>
-        internal static string _FDF5E6 {
-            get {
-                return ResourceManager.GetString("#FDF5E6", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Red.
-        /// </summary>
-        internal static string _FF0000 {
-            get {
-                return ResourceManager.GetString("#FF0000", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Magenta.
-        /// </summary>
-        internal static string _FF00FF {
-            get {
-                return ResourceManager.GetString("#FF00FF", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DeepPink.
-        /// </summary>
-        internal static string _FF1493 {
-            get {
-                return ResourceManager.GetString("#FF1493", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to OrangeRed.
-        /// </summary>
-        internal static string _FF4500 {
-            get {
-                return ResourceManager.GetString("#FF4500", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Tomato.
-        /// </summary>
-        internal static string _FF6347 {
-            get {
-                return ResourceManager.GetString("#FF6347", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to HotPink.
-        /// </summary>
-        internal static string _FF69B4 {
-            get {
-                return ResourceManager.GetString("#FF69B4", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Coral.
-        /// </summary>
-        internal static string _FF7F50 {
-            get {
-                return ResourceManager.GetString("#FF7F50", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to DarkOrange.
-        /// </summary>
-        internal static string _FF8C00 {
-            get {
-                return ResourceManager.GetString("#FF8C00", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightSalmon.
-        /// </summary>
-        internal static string _FFA07A {
-            get {
-                return ResourceManager.GetString("#FFA07A", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Orange.
-        /// </summary>
-        internal static string _FFA500 {
-            get {
-                return ResourceManager.GetString("#FFA500", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightPink.
-        /// </summary>
-        internal static string _FFB6C1 {
-            get {
-                return ResourceManager.GetString("#FFB6C1", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Pink.
-        /// </summary>
-        internal static string _FFC0CB {
-            get {
-                return ResourceManager.GetString("#FFC0CB", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Gold.
-        /// </summary>
-        internal static string _FFD700 {
-            get {
-                return ResourceManager.GetString("#FFD700", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PeachPuff.
-        /// </summary>
-        internal static string _FFDAB9 {
-            get {
-                return ResourceManager.GetString("#FFDAB9", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to NavajoWhite.
-        /// </summary>
-        internal static string _FFDEAD {
-            get {
-                return ResourceManager.GetString("#FFDEAD", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Moccasin.
-        /// </summary>
-        internal static string _FFE4B5 {
-            get {
-                return ResourceManager.GetString("#FFE4B5", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Bisque.
-        /// </summary>
-        internal static string _FFE4C4 {
-            get {
-                return ResourceManager.GetString("#FFE4C4", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to MistyRose.
-        /// </summary>
-        internal static string _FFE4E1 {
-            get {
-                return ResourceManager.GetString("#FFE4E1", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to BlanchedAlmond.
-        /// </summary>
-        internal static string _FFEBCD {
-            get {
-                return ResourceManager.GetString("#FFEBCD", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to PapayaWhip.
-        /// </summary>
-        internal static string _FFEFD5 {
-            get {
-                return ResourceManager.GetString("#FFEFD5", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LavenderBlush.
-        /// </summary>
-        internal static string _FFF0F5 {
-            get {
-                return ResourceManager.GetString("#FFF0F5", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to SeaShell.
-        /// </summary>
-        internal static string _FFF5EE {
-            get {
-                return ResourceManager.GetString("#FFF5EE", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cornsilk.
-        /// </summary>
-        internal static string _FFF8DC {
-            get {
-                return ResourceManager.GetString("#FFF8DC", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LemonChiffon.
-        /// </summary>
-        internal static string _FFFACD {
-            get {
-                return ResourceManager.GetString("#FFFACD", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to FloralWhite.
-        /// </summary>
-        internal static string _FFFAF0 {
-            get {
-                return ResourceManager.GetString("#FFFAF0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Snow.
-        /// </summary>
-        internal static string _FFFAFA {
-            get {
-                return ResourceManager.GetString("#FFFAFA", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Yellow.
-        /// </summary>
-        internal static string _FFFF00 {
-            get {
-                return ResourceManager.GetString("#FFFF00", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to LightYellow.
-        /// </summary>
-        internal static string _FFFFE0 {
-            get {
-                return ResourceManager.GetString("#FFFFE0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Ivory.
-        /// </summary>
-        internal static string _FFFFF0 {
-            get {
-                return ResourceManager.GetString("#FFFFF0", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to White.
-        /// </summary>
-        internal static string _FFFFFF {
-            get {
-                return ResourceManager.GetString("#FFFFFF", resourceCulture);
-            }
-        }
-        
         /// <summary>
         ///   Looks up a localized string similar to _Cancel.
         /// </summary>

+ 0 - 438
Terminal.Gui/Resources/Strings.resx

@@ -280,444 +280,6 @@
   <data name="dpTitle" xml:space="preserve">
     <value>Date Picker</value>
   </data>
-  <data name="#F0F8FF" xml:space="preserve">
-    <value>AliceBlue</value>
-  </data>
-  <data name="#FAEBD7" xml:space="preserve">
-    <value>AntiqueWhite</value>
-  </data>
-  <data name="#7FFFD4" xml:space="preserve">
-    <value>Aquamarine</value>
-  </data>
-  <data name="#F0FFFF" xml:space="preserve">
-    <value>Azure</value>
-  </data>
-  <data name="#F5F5DC" xml:space="preserve">
-    <value>Beige</value>
-  </data>
-  <data name="#FFE4C4" xml:space="preserve">
-    <value>Bisque</value>
-  </data>
-  <data name="#000000" xml:space="preserve">
-    <value>Black</value>
-  </data>
-  <data name="#FFEBCD" xml:space="preserve">
-    <value>BlanchedAlmond</value>
-  </data>
-  <data name="#0000FF" xml:space="preserve">
-    <value>Blue</value>
-  </data>
-  <data name="#8A2BE2" xml:space="preserve">
-    <value>BlueViolet</value>
-  </data>
-  <data name="#A52A2A" xml:space="preserve">
-    <value>Brown</value>
-  </data>
-  <data name="#DEB887" xml:space="preserve">
-    <value>BurlyWood</value>
-  </data>
-  <data name="#5F9EA0" xml:space="preserve">
-    <value>CadetBlue</value>
-  </data>
-  <data name="#7FFF00" xml:space="preserve">
-    <value>Chartreuse</value>
-  </data>
-  <data name="#D2691E" xml:space="preserve">
-    <value>Chocolate</value>
-  </data>
-  <data name="#FF7F50" xml:space="preserve">
-    <value>Coral</value>
-  </data>
-  <data name="#6495ED" xml:space="preserve">
-    <value>CornflowerBlue</value>
-  </data>
-  <data name="#FFF8DC" xml:space="preserve">
-    <value>Cornsilk</value>
-  </data>
-  <data name="#DC143C" xml:space="preserve">
-    <value>Crimson</value>
-  </data>
-  <data name="#00FFFF" xml:space="preserve">
-    <value>Cyan</value>
-  </data>
-  <data name="#00008B" xml:space="preserve">
-    <value>DarkBlue</value>
-  </data>
-  <data name="#008B8B" xml:space="preserve">
-    <value>DarkCyan</value>
-  </data>
-  <data name="#B8860B" xml:space="preserve">
-    <value>DarkGoldenRod</value>
-  </data>
-  <data name="#A9A9A9" xml:space="preserve">
-    <value>DarkGrey</value>
-  </data>
-  <data name="#006400" xml:space="preserve">
-    <value>DarkGreen</value>
-  </data>
-  <data name="#BDB76B" xml:space="preserve">
-    <value>DarkKhaki</value>
-  </data>
-  <data name="#8B008B" xml:space="preserve">
-    <value>DarkMagenta</value>
-  </data>
-  <data name="#556B2F" xml:space="preserve">
-    <value>DarkOliveGreen</value>
-  </data>
-  <data name="#FF8C00" xml:space="preserve">
-    <value>DarkOrange</value>
-  </data>
-  <data name="#9932CC" xml:space="preserve">
-    <value>DarkOrchid</value>
-  </data>
-  <data name="#8B0000" xml:space="preserve">
-    <value>DarkRed</value>
-  </data>
-  <data name="#E9967A" xml:space="preserve">
-    <value>DarkSalmon</value>
-  </data>
-  <data name="#8FBC8F" xml:space="preserve">
-    <value>DarkSeaGreen</value>
-  </data>
-  <data name="#483D8B" xml:space="preserve">
-    <value>DarkSlateBlue</value>
-  </data>
-  <data name="#2F4F4F" xml:space="preserve">
-    <value>DarkSlateGrey</value>
-  </data>
-  <data name="#00CED1" xml:space="preserve">
-    <value>DarkTurquoise</value>
-  </data>
-  <data name="#9400D3" xml:space="preserve">
-    <value>DarkViolet</value>
-  </data>
-  <data name="#FF1493" xml:space="preserve">
-    <value>DeepPink</value>
-  </data>
-  <data name="#00BFFF" xml:space="preserve">
-    <value>DeepSkyBlue</value>
-  </data>
-  <data name="#696969" xml:space="preserve">
-    <value>DimGray</value>
-  </data>
-  <data name="#1E90FF" xml:space="preserve">
-    <value>DodgerBlue</value>
-  </data>
-  <data name="#B22222" xml:space="preserve">
-    <value>FireBrick</value>
-  </data>
-  <data name="#FFFAF0" xml:space="preserve">
-    <value>FloralWhite</value>
-  </data>
-  <data name="#228B22" xml:space="preserve">
-    <value>ForestGreen</value>
-  </data>
-  <data name="#DCDCDC" xml:space="preserve">
-    <value>Gainsboro</value>
-  </data>
-  <data name="#F8F8FF" xml:space="preserve">
-    <value>GhostWhite</value>
-  </data>
-  <data name="#FFD700" xml:space="preserve">
-    <value>Gold</value>
-  </data>
-  <data name="#DAA520" xml:space="preserve">
-    <value>GoldenRod</value>
-  </data>
-  <data name="#808080" xml:space="preserve">
-    <value>Gray</value>
-  </data>
-  <data name="#008000" xml:space="preserve">
-    <value>Green</value>
-  </data>
-  <data name="#ADFF2F" xml:space="preserve">
-    <value>GreenYellow</value>
-  </data>
-  <data name="#F0FFF0" xml:space="preserve">
-    <value>HoneyDew</value>
-  </data>
-  <data name="#FF69B4" xml:space="preserve">
-    <value>HotPink</value>
-  </data>
-  <data name="#CD5C5C" xml:space="preserve">
-    <value>IndianRed</value>
-  </data>
-  <data name="#4B0082" xml:space="preserve">
-    <value>Indigo</value>
-  </data>
-  <data name="#FFFFF0" xml:space="preserve">
-    <value>Ivory</value>
-  </data>
-  <data name="#F0E68C" xml:space="preserve">
-    <value>Khaki</value>
-  </data>
-  <data name="#E6E6FA" xml:space="preserve">
-    <value>Lavender</value>
-  </data>
-  <data name="#FFF0F5" xml:space="preserve">
-    <value>LavenderBlush</value>
-  </data>
-  <data name="#7CFC00" xml:space="preserve">
-    <value>LawnGreen</value>
-  </data>
-  <data name="#FFFACD" xml:space="preserve">
-    <value>LemonChiffon</value>
-  </data>
-  <data name="#ADD8E6" xml:space="preserve">
-    <value>LightBlue</value>
-  </data>
-  <data name="#F08080" xml:space="preserve">
-    <value>LightCoral</value>
-  </data>
-  <data name="#E0FFFF" xml:space="preserve">
-    <value>LightCyan</value>
-  </data>
-  <data name="#FAFAD2" xml:space="preserve">
-    <value>LightGoldenRodYellow</value>
-  </data>
-  <data name="#D3D3D3" xml:space="preserve">
-    <value>LightGray</value>
-  </data>
-  <data name="#90EE90" xml:space="preserve">
-    <value>LightGreen</value>
-  </data>
-  <data name="#FFB6C1" xml:space="preserve">
-    <value>LightPink</value>
-  </data>
-  <data name="#FFA07A" xml:space="preserve">
-    <value>LightSalmon</value>
-  </data>
-  <data name="#20B2AA" xml:space="preserve">
-    <value>LightSeaGreen</value>
-  </data>
-  <data name="#87CEFA" xml:space="preserve">
-    <value>LightSkyBlue</value>
-  </data>
-  <data name="#778899" xml:space="preserve">
-    <value>LightSlateGrey</value>
-  </data>
-  <data name="#B0C4DE" xml:space="preserve">
-    <value>LightSteelBlue</value>
-  </data>
-  <data name="#FFFFE0" xml:space="preserve">
-    <value>LightYellow</value>
-  </data>
-  <data name="#00FF00" xml:space="preserve">
-    <value>Lime</value>
-  </data>
-  <data name="#32CD32" xml:space="preserve">
-    <value>LimeGreen</value>
-  </data>
-  <data name="#FAF0E6" xml:space="preserve">
-    <value>Linen</value>
-  </data>
-  <data name="#FF00FF" xml:space="preserve">
-    <value>Magenta</value>
-  </data>
-  <data name="#800000" xml:space="preserve">
-    <value>Maroon</value>
-  </data>
-  <data name="#66CDAA" xml:space="preserve">
-    <value>MediumAquaMarine</value>
-  </data>
-  <data name="#0000CD" xml:space="preserve">
-    <value>MediumBlue</value>
-  </data>
-  <data name="#BA55D3" xml:space="preserve">
-    <value>MediumOrchid</value>
-  </data>
-  <data name="#9370DB" xml:space="preserve">
-    <value>MediumPurple</value>
-  </data>
-  <data name="#3CB371" xml:space="preserve">
-    <value>MediumSeaGreen</value>
-  </data>
-  <data name="#7B68EE" xml:space="preserve">
-    <value>MediumSlateBlue</value>
-  </data>
-  <data name="#00FA9A" xml:space="preserve">
-    <value>MediumSpringGreen</value>
-  </data>
-  <data name="#48D1CC" xml:space="preserve">
-    <value>MediumTurquoise</value>
-  </data>
-  <data name="#C71585" xml:space="preserve">
-    <value>MediumVioletRed</value>
-  </data>
-  <data name="#191970" xml:space="preserve">
-    <value>MidnightBlue</value>
-  </data>
-  <data name="#F5FFFA" xml:space="preserve">
-    <value>MintCream</value>
-  </data>
-  <data name="#FFE4E1" xml:space="preserve">
-    <value>MistyRose</value>
-  </data>
-  <data name="#FFE4B5" xml:space="preserve">
-    <value>Moccasin</value>
-  </data>
-  <data name="#FFDEAD" xml:space="preserve">
-    <value>NavajoWhite</value>
-  </data>
-  <data name="#000080" xml:space="preserve">
-    <value>Navy</value>
-  </data>
-  <data name="#FDF5E6" xml:space="preserve">
-    <value>OldLace</value>
-  </data>
-  <data name="#808000" xml:space="preserve">
-    <value>Olive</value>
-  </data>
-  <data name="#6B8E23" xml:space="preserve">
-    <value>OliveDrab</value>
-  </data>
-  <data name="#FFA500" xml:space="preserve">
-    <value>Orange</value>
-  </data>
-  <data name="#FF4500" xml:space="preserve">
-    <value>OrangeRed</value>
-  </data>
-  <data name="#DA70D6" xml:space="preserve">
-    <value>Orchid</value>
-  </data>
-  <data name="#EEE8AA" xml:space="preserve">
-    <value>PaleGoldenRod</value>
-  </data>
-  <data name="#98FB98" xml:space="preserve">
-    <value>PaleGreen</value>
-  </data>
-  <data name="#AFEEEE" xml:space="preserve">
-    <value>PaleTurquoise</value>
-  </data>
-  <data name="#DB7093" xml:space="preserve">
-    <value>PaleVioletRed</value>
-  </data>
-  <data name="#FFEFD5" xml:space="preserve">
-    <value>PapayaWhip</value>
-  </data>
-  <data name="#FFDAB9" xml:space="preserve">
-    <value>PeachPuff</value>
-  </data>
-  <data name="#CD853F" xml:space="preserve">
-    <value>Peru</value>
-  </data>
-  <data name="#FFC0CB" xml:space="preserve">
-    <value>Pink</value>
-  </data>
-  <data name="#DDA0DD" xml:space="preserve">
-    <value>Plum</value>
-  </data>
-  <data name="#B0E0E6" xml:space="preserve">
-    <value>PowderBlue</value>
-  </data>
-  <data name="#800080" xml:space="preserve">
-    <value>Purple</value>
-  </data>
-  <data name="#663399" xml:space="preserve">
-    <value>RebeccaPurple</value>
-  </data>
-  <data name="#FF0000" xml:space="preserve">
-    <value>Red</value>
-  </data>
-  <data name="#BC8F8F" xml:space="preserve">
-    <value>RosyBrown</value>
-  </data>
-  <data name="#4169E1" xml:space="preserve">
-    <value>RoyalBlue</value>
-  </data>
-  <data name="#8B4513" xml:space="preserve">
-    <value>SaddleBrown</value>
-  </data>
-  <data name="#FA8072" xml:space="preserve">
-    <value>Salmon</value>
-  </data>
-  <data name="#F4A460" xml:space="preserve">
-    <value>SandyBrown</value>
-  </data>
-  <data name="#2E8B57" xml:space="preserve">
-    <value>SeaGreen</value>
-  </data>
-  <data name="#FFF5EE" xml:space="preserve">
-    <value>SeaShell</value>
-  </data>
-  <data name="#A0522D" xml:space="preserve">
-    <value>Sienna</value>
-  </data>
-  <data name="#C0C0C0" xml:space="preserve">
-    <value>Silver</value>
-  </data>
-  <data name="#87CEEB" xml:space="preserve">
-    <value>SkyBlue</value>
-  </data>
-  <data name="#6A5ACD" xml:space="preserve">
-    <value>SlateBlue</value>
-  </data>
-  <data name="#708090" xml:space="preserve">
-    <value>SlateGray</value>
-  </data>
-  <data name="#FFFAFA" xml:space="preserve">
-    <value>Snow</value>
-  </data>
-  <data name="#00FF7F" xml:space="preserve">
-    <value>SpringGreen</value>
-  </data>
-  <data name="#4682B4" xml:space="preserve">
-    <value>SteelBlue</value>
-  </data>
-  <data name="#D2B48C" xml:space="preserve">
-    <value>Tan</value>
-  </data>
-  <data name="#008080" xml:space="preserve">
-    <value>Teal</value>
-  </data>
-  <data name="#D8BFD8" xml:space="preserve">
-    <value>Thistle</value>
-  </data>
-  <data name="#FF6347" xml:space="preserve">
-    <value>Tomato</value>
-  </data>
-  <data name="#40E0D0" xml:space="preserve">
-    <value>Turquoise</value>
-  </data>
-  <data name="#EE82EE" xml:space="preserve">
-    <value>Violet</value>
-  </data>
-  <data name="#F5DEB3" xml:space="preserve">
-    <value>Wheat</value>
-  </data>
-  <data name="#FFFFFF" xml:space="preserve">
-    <value>White</value>
-  </data>
-  <data name="#F5F5F5" xml:space="preserve">
-    <value>WhiteSmoke</value>
-  </data>
-  <data name="#FFFF00" xml:space="preserve">
-    <value>Yellow</value>
-  </data>
-  <data name="#9ACD32" xml:space="preserve">
-    <value>YellowGreen</value>
-  </data>
-  <data name="#3B78FF" xml:space="preserve">
-    <value>BrightBlue</value>
-  </data>
-  <data name="#61D6D6" xml:space="preserve">
-    <value>BrightCyan</value>
-  </data>
-  <data name="#E74856" xml:space="preserve">
-    <value>BrightRed</value>
-  </data>
-  <data name="#16C60C" xml:space="preserve">
-    <value>BrightGreen</value>
-  </data>
-  <data name="#B4009E" xml:space="preserve">
-    <value>BrightMagenta</value>
-  </data>
-  <data name="#F9F1A5" xml:space="preserve">
-    <value>BrightYellow</value>
-  </data>
-  <data name="#767676" xml:space="preserve">
-    <value>DarkGray</value>
-  </data>
   <data name="ctxColors" xml:space="preserve">
     <value>Co_lors</value>
   </data>

+ 5 - 7
Terminal.Gui/Views/ColorPicker.cs

@@ -1,7 +1,5 @@
 #nullable enable
 
-using System;
-
 namespace Terminal.Gui;
 
 /// <summary>
@@ -34,7 +32,7 @@ public partial class ColorPicker : View
     private Color _selectedColor = Color.Black;
 
     // TODO: Add interface
-    private readonly IColorNameResolver _colorNameResolver = new W3CColors ();
+    private readonly IColorNameResolver _colorNameResolver = new MultiStandardColorNameResolver ();
 
     private List<IColorBar> _bars = new ();
 
@@ -64,7 +62,7 @@ public partial class ColorPicker : View
                     Width = textFieldWidth
                 };
                 tfValue.HasFocusChanged += UpdateSingleBarValueFromTextField;
-                tfValue.Accepting += (s, _)=>UpdateSingleBarValueFromTextField(s);
+                tfValue.Accepting += (s, _) => UpdateSingleBarValueFromTextField (s);
                 _textFields.Add (bar, tfValue);
             }
 
@@ -182,7 +180,7 @@ public partial class ColorPicker : View
         Add (_tfHex);
 
         _tfHex.HasFocusChanged += UpdateValueFromTextField;
-        _tfHex.Accepting += (_,_)=> UpdateValueFromTextField();
+        _tfHex.Accepting += (_, _) => UpdateValueFromTextField ();
     }
 
     private void DisposeOldViews ()
@@ -266,7 +264,7 @@ public partial class ColorPicker : View
 
         if (_tfName != null)
         {
-            _tfName.Text = _colorNameResolver.TryNameColor (_selectedColor, out string name) ? name : string.Empty;
+            _tfName.Text = _colorNameResolver.TryNameColor (_selectedColor, out string? name) ? name : string.Empty;
         }
 
         if (_tfHex != null)
@@ -312,7 +310,7 @@ public partial class ColorPicker : View
         }
 
         // it is a leave event so update
-        UpdateValueFromName();
+        UpdateValueFromName ();
     }
     private void UpdateValueFromName ()
     {

+ 0 - 49
Tests/UnitTests/Resources/ResourceManagerTests.cs

@@ -9,10 +9,6 @@ namespace Terminal.Gui.ResourcesTests;
 
 public class ResourceManagerTests
 {
-    private const string DODGER_BLUE_COLOR_KEY = "DodgerBlue";
-    private const string DODGER_BLUE_COLOR_NAME = "DodgerBlue";
-    private const string NO_NAMED_COLOR_KEY = "#1E80FF";
-    private const string NO_NAMED_COLOR_NAME = "#1E80FF";
     private const string EXISTENT_CULTURE = "pt-PT";
     private const string NO_EXISTENT_CULTURE = "de-DE";
     private const string NO_EXISTENT_KEY = "blabla";
@@ -50,51 +46,6 @@ public class ResourceManagerTests
         RestoreCurrentCultures ();
     }
 
-    [Fact]
-    public void GetResourceSet_FallBack_To_Default_For_No_Existent_Culture_File ()
-    {
-        CultureInfo.CurrentCulture = new (NO_EXISTENT_CULTURE);
-        CultureInfo.CurrentUICulture = new (NO_EXISTENT_CULTURE);
-
-        // W3CColors.GetColorNames also calls ColorStrings.GetW3CColorNames
-        string [] colorNames = new W3CColors ().GetColorNames ().ToArray ();
-        Assert.Contains (DODGER_BLUE_COLOR_NAME, colorNames);
-        Assert.DoesNotContain (NO_TRANSLATED_VALUE, colorNames);
-
-        RestoreCurrentCultures ();
-    }
-
-    [Fact]
-    public void GetResourceSet_FallBack_To_Default_For_Not_Translated_Existent_Culture_File ()
-    {
-        CultureInfo.CurrentCulture = new (EXISTENT_CULTURE);
-        CultureInfo.CurrentUICulture = new (EXISTENT_CULTURE);
-
-        // These aren't already translated
-        // ColorStrings.GetW3CColorNames method uses GetResourceSet method to retrieve color names
-        IEnumerable<string> colorNames = ColorStrings.GetW3CColorNames ();
-        Assert.NotEmpty (colorNames);
-
-        // W3CColors.GetColorNames also calls ColorStrings.GetW3CColorNames
-        colorNames = new W3CColors ().GetColorNames ().ToArray ();
-        Assert.Contains (DODGER_BLUE_COLOR_NAME, colorNames);
-        Assert.DoesNotContain (NO_TRANSLATED_VALUE, colorNames);
-
-        // ColorStrings.TryParseW3CColorName method uses GetResourceSet method to retrieve a color value
-        Assert.True (ColorStrings.TryParseW3CColorName (DODGER_BLUE_COLOR_NAME, out Color color));
-        Assert.Equal (DODGER_BLUE_COLOR_KEY, color.ToString ());
-
-        // W3CColors.GetColorNames also calls ColorStrings.GetW3CColorNames for no-named colors
-        colorNames = new W3CColors ().GetColorNames ().ToArray ();
-        Assert.DoesNotContain (NO_NAMED_COLOR_NAME, colorNames);
-
-        // ColorStrings.TryParseW3CColorName method uses GetResourceSet method to retrieve a color value for no-named colors
-        Assert.True (ColorStrings.TryParseW3CColorName (NO_NAMED_COLOR_NAME, out color));
-        Assert.Equal (NO_NAMED_COLOR_KEY, color.ToString ());
-
-        RestoreCurrentCultures ();
-    }
-
     [Fact]
     public void GetResourceSet_With_Filter_Does_Not_Overflows_If_Key_Does_Not_Exist ()
     {

+ 11 - 11
Tests/UnitTests/Views/ColorPickerTests.cs

@@ -749,7 +749,15 @@ public class ColorPickerTests
         // Auto complete the color name
         Application.RaiseKeyDownEvent (Key.Tab);
 
-        Assert.Equal ("Aquamarine", name.Text);
+        // Match cyan alternative name
+        Assert.Equal ("Aqua", name.Text);
+
+        Assert.True (name.HasFocus);
+
+        Application.RaiseKeyDownEvent (Key.Tab);
+
+        // Resolves to cyan color
+        Assert.Equal ("Cyan", name.Text);
 
         // Tab out of the text field
         Application.RaiseKeyDownEvent (Key.Tab);
@@ -757,7 +765,7 @@ public class ColorPickerTests
         Assert.False (name.HasFocus);
         Assert.NotSame (name, cp.Focused);
 
-        Assert.Equal ("#7FFFD4", hex.Text);
+        Assert.Equal ("#00FFFF", hex.Text);
 
         Application.Top?.Dispose ();
         Application.ResetState (true);
@@ -817,14 +825,6 @@ public class ColorPickerTests
         };
     }
 
-    [Fact]
-    public void TestColorNames ()
-    {
-        var colors = new W3CColors ();
-        Assert.Contains ("Aquamarine", colors.GetColorNames ());
-        Assert.DoesNotContain ("Save as", colors.GetColorNames ());
-    }
-
     private ColorBar GetColorBar (ColorPicker cp, ColorPickerPart toGet)
     {
         if (toGet <= ColorPickerPart.Bar3)
@@ -845,7 +845,7 @@ public class ColorPickerTests
 
         Application.Navigation = new ();
 
-        Application.Top = new() { Width = 20, Height = 5 };
+        Application.Top = new () { Width = 20, Height = 5 };
         Application.Top.Add (cp);
 
         Application.Top.LayoutSubViews ();

+ 124 - 0
Tests/UnitTestsParallelizable/Drawing/Color/AnsiColorNameResolverTests.cs

@@ -0,0 +1,124 @@
+#nullable enable
+
+namespace Terminal.Gui.DrawingTests;
+
+public class AnsiColorNameResolverTests
+{
+    private readonly AnsiColorNameResolver _candidate = new();
+
+    [Fact]
+    public void GetNames_Returns16ColorNames ()
+    {
+        string[] expected = Enum.GetNames<ColorName16>();
+
+        string[] actual = _candidate.GetColorNames ().ToArray();
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (0, 0, 0, nameof (ColorName16.Black))]
+    [InlineData (0, 0, 255, nameof (ColorName16.Blue))]
+    [InlineData (59, 120, 255, nameof (ColorName16.BrightBlue))]
+    [InlineData (97, 214, 214, nameof (ColorName16.BrightCyan))]
+    [InlineData (22, 198, 12, nameof (ColorName16.BrightGreen))]
+    [InlineData (180, 0, 158, nameof (ColorName16.BrightMagenta))]
+    [InlineData (231, 72, 86, nameof (ColorName16.BrightRed))]
+    [InlineData (249, 241, 165, nameof (ColorName16.BrightYellow))]
+    [InlineData (0, 255, 255, nameof (ColorName16.Cyan))]
+    [InlineData (118, 118, 118, nameof (ColorName16.DarkGray))]
+    [InlineData (128, 128, 128, nameof (ColorName16.Gray))]
+    [InlineData (0, 128, 0, nameof (ColorName16.Green))]
+    [InlineData (255, 0, 255, nameof (ColorName16.Magenta))]
+    [InlineData (255, 0, 0, nameof (ColorName16.Red))]
+    [InlineData (255, 255, 255, nameof (ColorName16.White))]
+    [InlineData (255, 255, 0, nameof (ColorName16.Yellow))]
+    public void TryNameColor_ReturnsExpectedColorName (byte r, byte g, byte b, string expectedName)
+    {
+        var expected = (true, expectedName);
+
+        bool actualSuccess = _candidate.TryNameColor(new Color(r, g, b), out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Fact]
+    public void TryNameColor_NoMatchFails ()
+    {
+        (bool, string?) expected = (false, null);
+
+        bool actualSuccess = _candidate.TryNameColor (new Color (1, 2, 3), out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (nameof (ColorName16.Black), 0, 0, 0)]
+    [InlineData (nameof (ColorName16.Blue), 0, 0, 255)]
+    [InlineData (nameof (ColorName16.BrightBlue), 59, 120, 255)]
+    [InlineData (nameof (ColorName16.BrightCyan), 97, 214, 214)]
+    [InlineData (nameof (ColorName16.BrightGreen), 22, 198, 12)]
+    [InlineData (nameof (ColorName16.BrightMagenta), 180, 0, 158)]
+    [InlineData (nameof (ColorName16.BrightRed), 231, 72, 86)]
+    [InlineData (nameof (ColorName16.BrightYellow), 249, 241, 165)]
+    [InlineData (nameof (ColorName16.Cyan), 0, 255, 255)]
+    [InlineData (nameof (ColorName16.DarkGray), 118, 118, 118)]
+    [InlineData (nameof (ColorName16.Gray), 128, 128, 128)]
+    [InlineData (nameof (ColorName16.Green), 0, 128, 0)]
+    [InlineData (nameof (ColorName16.Magenta), 255, 0, 255)]
+    [InlineData (nameof (ColorName16.Red), 255, 0, 0)]
+    [InlineData (nameof (ColorName16.White), 255, 255, 255)]
+    [InlineData (nameof (ColorName16.Yellow), 255, 255, 0)]
+    // Case-insensitive
+    [InlineData ("BRIGHTBLUE", 59, 120, 255)]
+    [InlineData ("brightblue", 59, 120, 255)]
+    public void TryParseColor_ReturnsExpectedColor (string inputName, byte r, byte g, byte b)
+    {
+        var expected = (true, new Color(r, g, b));
+
+        bool actualSuccess = _candidate.TryParseColor (inputName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ("12", 231, 72, 86)] // ColorName16.BrightRed
+    public void TryParseColor_ResolvesValidEnumNumber (string inputName, byte r, byte g, byte b)
+    {
+        var expected = (true, new Color(r, g, b));
+
+        bool actualSuccess = _candidate.TryParseColor (inputName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (null)]
+    [InlineData ("")]
+    [InlineData ("brightlight")]
+    public void TryParseColor_FailsOnInvalidColorName (string? invalidName)
+    {
+        var expected = (false, default(Color));
+
+        bool actualSuccess = _candidate.TryParseColor (invalidName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ("-12")]
+    public void TryParseColor_FailsOnInvalidEnumNumber (string invalidName)
+    {
+        var expected = (false, default(Color));
+
+        bool actualSuccess = _candidate.TryParseColor (invalidName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+}

+ 232 - 0
Tests/UnitTestsParallelizable/Drawing/Color/MultiStandardColorNameResolverTests.cs

@@ -0,0 +1,232 @@
+#nullable enable
+
+namespace Terminal.Gui.DrawingTests;
+
+public class MultiStandardColorNameResolverTests
+{
+    private readonly MultiStandardColorNameResolver _candidate = new();
+
+    [Theory]
+    // ANSI color names.
+    [InlineData (nameof (ColorName16.Black))]
+    [InlineData (nameof (ColorName16.White))]
+    [InlineData (nameof (ColorName16.Red))]
+    [InlineData (nameof (ColorName16.Green))]
+    [InlineData (nameof (ColorName16.Blue))]
+    [InlineData (nameof (ColorName16.Cyan))]
+    [InlineData (nameof (ColorName16.Magenta))]
+    [InlineData (nameof (ColorName16.DarkGray))]
+    [InlineData (nameof (ColorName16.BrightGreen))]
+    [InlineData (nameof (ColorName16.BrightMagenta))]
+    // Regular W3C color.
+    [InlineData (nameof (W3cColor.AliceBlue))]
+    [InlineData (nameof (W3cColor.BlanchedAlmond))]
+    [InlineData (nameof (W3cColor.CadetBlue))]
+    [InlineData (nameof (W3cColor.DarkBlue))]
+    [InlineData (nameof (W3cColor.FireBrick))]
+    [InlineData (nameof (W3cColor.Gainsboro))]
+    [InlineData (nameof (W3cColor.HoneyDew))]
+    [InlineData (nameof (W3cColor.Indigo))]
+    [InlineData (nameof (W3cColor.Khaki))]
+    [InlineData (nameof (W3cColor.Lavender))]
+    [InlineData (nameof (W3cColor.Maroon))]
+    [InlineData (nameof (W3cColor.Navy))]
+    [InlineData (nameof (W3cColor.Olive))]
+    [InlineData (nameof (W3cColor.Plum))]
+    [InlineData (nameof (W3cColor.RoyalBlue))]
+    [InlineData (nameof (W3cColor.Silver))]
+    [InlineData (nameof (W3cColor.Tomato))]
+    [InlineData (nameof (W3cColor.Violet))]
+    [InlineData (nameof (W3cColor.WhiteSmoke))]
+    [InlineData (nameof (W3cColor.YellowGreen))]
+    // W3C alternatives.
+    [InlineData (nameof (W3cColor.Grey))]
+    [InlineData (nameof (W3cColor.DarkGrey))]
+    [InlineData (nameof (W3cColor.Aqua))]
+    [InlineData (nameof (W3cColor.Fuchsia))]
+    [InlineData (nameof (W3cColor.DarkSlateGray))]
+    [InlineData (nameof (W3cColor.DarkSlateGrey))]
+    [InlineData (nameof (W3cColor.DimGray))]
+    [InlineData (nameof (W3cColor.DimGrey))]
+    [InlineData (nameof (W3cColor.LightGray))]
+    [InlineData (nameof (W3cColor.LightGrey))]
+    [InlineData (nameof (W3cColor.SlateGray))]
+    [InlineData (nameof (W3cColor.SlateGrey))]
+    public void GetNames_ContainsCombinationOfAnsiAndW3cNames (string name)
+    {
+        string[] names = _candidate.GetColorNames ().ToArray();
+        Assert.Contains (name, names);
+    }
+
+    [Theory]
+    // ANSI color names
+    [InlineData (0, 0, 0, nameof (ColorName16.Black))]
+    [InlineData (0, 0, 255, nameof (ColorName16.Blue))]
+    [InlineData (59, 120, 255, nameof (ColorName16.BrightBlue))]
+    [InlineData (97, 214, 214, nameof (ColorName16.BrightCyan))]
+    [InlineData (22, 198, 12, nameof (ColorName16.BrightGreen))]
+    [InlineData (180, 0, 158, nameof (ColorName16.BrightMagenta))]
+    [InlineData (231, 72, 86, nameof (ColorName16.BrightRed))]
+    [InlineData (249, 241, 165, nameof (ColorName16.BrightYellow))]
+    [InlineData (0, 255, 255, nameof (ColorName16.Cyan))]
+    [InlineData (118, 118, 118, nameof (ColorName16.DarkGray))]
+    [InlineData (128, 128, 128, nameof (ColorName16.Gray))]
+    [InlineData (0, 128, 0, nameof (ColorName16.Green))]
+    [InlineData (255, 0, 255, nameof (ColorName16.Magenta))]
+    [InlineData (255, 0, 0, nameof (ColorName16.Red))]
+    [InlineData (255, 255, 255, nameof (ColorName16.White))]
+    [InlineData (255, 255, 0, nameof (ColorName16.Yellow))]
+    // W3C color names
+    [InlineData (240, 248, 255, nameof (W3cColor.AliceBlue))]
+    [InlineData (255, 235, 205, nameof (W3cColor.BlanchedAlmond))]
+    [InlineData (95, 158, 160, nameof (W3cColor.CadetBlue))]
+    [InlineData (0, 0, 139, nameof (W3cColor.DarkBlue))]
+    [InlineData (178, 34, 34, nameof (W3cColor.FireBrick))]
+    [InlineData (220, 220, 220, nameof (W3cColor.Gainsboro))]
+    [InlineData (240, 255, 240, nameof (W3cColor.HoneyDew))]
+    [InlineData (75, 0, 130, nameof (W3cColor.Indigo))]
+    [InlineData (240, 230, 140, nameof (W3cColor.Khaki))]
+    [InlineData (230, 230, 250, nameof (W3cColor.Lavender))]
+    [InlineData (128, 0, 0, nameof (W3cColor.Maroon))]
+    [InlineData (0, 0, 128, nameof (W3cColor.Navy))]
+    [InlineData (128, 128, 0, nameof (W3cColor.Olive))]
+    [InlineData (221, 160, 221, nameof (W3cColor.Plum))]
+    [InlineData (65, 105, 225, nameof (W3cColor.RoyalBlue))]
+    [InlineData (192, 192, 192, nameof (W3cColor.Silver))]
+    [InlineData (255, 99, 71, nameof (W3cColor.Tomato))]
+    [InlineData (238, 130, 238, nameof (W3cColor.Violet))]
+    [InlineData (245, 245, 245, nameof (W3cColor.WhiteSmoke))]
+    [InlineData (154, 205, 50, nameof (W3cColor.YellowGreen))]
+    public void TryNameColor_ReturnsExpectedColorNames (byte r, byte g, byte b, string expectedName)
+    {
+        var expected = (true, expectedName);
+
+        bool actualSuccess = _candidate.TryNameColor(new Color(r, g, b), out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (169, 169, 169)] // W3cColor.DarkGr(a|e)y
+    public void TryNameColor_OmitsBlockedW3cColors (byte r, byte g, byte b)
+    {
+        (bool, string?) expected = (false, null);
+
+        bool actualSuccess = _candidate.TryNameColor (new Color (r, g, b), out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Fact]
+    public void TryNameColor_NoMatchFails ()
+    {
+        (bool, string?) expected = (false, null);
+
+        bool actualSuccess = _candidate.TryNameColor (new Color (1, 2, 3), out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    // ANSI colors
+    [InlineData (nameof (ColorName16.Black), 0, 0, 0)]
+    [InlineData (nameof (ColorName16.Blue), 0, 0, 255)]
+    [InlineData (nameof (ColorName16.BrightBlue), 59, 120, 255)]
+    [InlineData (nameof (ColorName16.BrightCyan), 97, 214, 214)]
+    [InlineData (nameof (ColorName16.BrightGreen), 22, 198, 12)]
+    [InlineData (nameof (ColorName16.BrightMagenta), 180, 0, 158)]
+    [InlineData (nameof (ColorName16.BrightRed), 231, 72, 86)]
+    [InlineData (nameof (ColorName16.BrightYellow), 249, 241, 165)]
+    [InlineData (nameof (ColorName16.Cyan), 0, 255, 255)]
+    [InlineData (nameof (ColorName16.DarkGray), 118, 118, 118)]
+    [InlineData (nameof (ColorName16.Gray), 128, 128, 128)]
+    [InlineData (nameof (ColorName16.Green), 0, 128, 0)]
+    [InlineData (nameof (ColorName16.Magenta), 255, 0, 255)]
+    [InlineData (nameof (ColorName16.Red), 255, 0, 0)]
+    [InlineData (nameof (ColorName16.White), 255, 255, 255)]
+    [InlineData (nameof (ColorName16.Yellow), 255, 255, 0)]
+    // W3C color name => substituted ANSI color
+    [InlineData (nameof (W3cColor.Fuchsia), 255, 0, 255)] // ANSI Magenta
+    [InlineData (nameof (W3cColor.DarkGrey), 118, 118, 118)] // ANSI Dark Gray
+    [InlineData (nameof (W3cColor.Grey), 128, 128, 128)] // ANSI Gray
+    [InlineData (nameof (W3cColor.Aqua), 0, 255, 255)] // ANSI Cyan
+    // W3C colors
+    [InlineData (nameof (W3cColor.AliceBlue), 240, 248, 255)]
+    [InlineData (nameof (W3cColor.BlanchedAlmond), 255, 235, 205)]
+    [InlineData (nameof (W3cColor.CadetBlue), 95, 158, 160)]
+    [InlineData (nameof (W3cColor.DarkBlue), 0, 0, 139)]
+    [InlineData (nameof (W3cColor.FireBrick), 178, 34, 34)]
+    [InlineData (nameof (W3cColor.Gainsboro), 220, 220, 220)]
+    [InlineData (nameof (W3cColor.HoneyDew), 240, 255, 240)]
+    [InlineData (nameof (W3cColor.Indigo), 75, 0, 130)]
+    [InlineData (nameof (W3cColor.Khaki), 240, 230, 140)]
+    [InlineData (nameof (W3cColor.Lavender), 230, 230, 250)]
+    [InlineData (nameof (W3cColor.Maroon), 128, 0, 0)]
+    [InlineData (nameof (W3cColor.Navy), 0, 0, 128)]
+    [InlineData (nameof (W3cColor.Olive), 128, 128, 0)]
+    [InlineData (nameof (W3cColor.Plum), 221, 160, 221)]
+    [InlineData (nameof (W3cColor.RoyalBlue), 65, 105, 225)]
+    [InlineData (nameof (W3cColor.Silver), 192, 192, 192)]
+    [InlineData (nameof (W3cColor.Tomato), 255, 99, 71)]
+    [InlineData (nameof (W3cColor.Violet), 238, 130, 238)]
+    [InlineData (nameof (W3cColor.WhiteSmoke), 245, 245, 245)]
+    [InlineData (nameof (W3cColor.YellowGreen), 154, 205, 50)]
+    // Case-insensitive
+    [InlineData ("BRIGHTBLUE", 59, 120, 255)]
+    [InlineData ("brightblue", 59, 120, 255)]
+    [InlineData ("TOMATO", 255, 99, 71)]
+    [InlineData ("tomato", 255, 99, 71)]
+
+    public void TryParseColor_ResolvesCombinationOfAnsiAndW3cColors (string inputName, byte r, byte g, byte b)
+    {
+        var expected = (true, new Color(r, g, b));
+
+        bool actualSuccess = _candidate.TryParseColor (inputName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ("12", 231, 72, 86)] // ColorName16.BrightRed
+    [InlineData ("16737095", 255, 99, 71)] // W3cColor.Tomato
+    public void TryParseColor_ResolvesValidEnumNumber (string inputName, byte r, byte g, byte b)
+    {
+        var expected = (true, new Color(r, g, b));
+
+        bool actualSuccess = _candidate.TryParseColor (inputName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (null)]
+    [InlineData ("")]
+    [InlineData ("brightlight")]
+    public void TryParseColor_FailsOnInvalidColorName (string? invalidName)
+    {
+        var expected = (false, default(Color));
+
+        bool actualSuccess = _candidate.TryParseColor (invalidName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ("-12")]
+    [InlineData ("-16737095")]
+    public void TryParseColor_FailsOnInvalidEnumNumber (string invalidName)
+    {
+        var expected = (false, default(Color));
+
+        bool actualSuccess = _candidate.TryParseColor (invalidName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+}

+ 150 - 0
Tests/UnitTestsParallelizable/Drawing/Color/W3cColorNameResolverTests.cs

@@ -0,0 +1,150 @@
+#nullable enable
+
+namespace Terminal.Gui.DrawingTests;
+
+public class W3cColorNameResolverTests
+{
+    private readonly W3cColorNameResolver _candidate = new();
+
+    [Fact]
+    public void GetColorNames_NamesAreInAlphabeticalOrder ()
+    {
+        string[] alphabeticallyOrderedNames = Enum.GetNames<W3cColor> ().Order ().ToArray ();
+
+        Assert.Equal (alphabeticallyOrderedNames, _candidate.GetColorNames ());
+    }
+
+    [Theory]
+    [InlineData (nameof (W3cColor.Aqua))]
+    [InlineData (nameof (W3cColor.Cyan))]
+    [InlineData (nameof (W3cColor.DarkGray))]
+    [InlineData (nameof (W3cColor.DarkGrey))]
+    [InlineData (nameof (W3cColor.DarkSlateGray))]
+    [InlineData (nameof (W3cColor.DarkSlateGrey))]
+    [InlineData (nameof (W3cColor.DimGray))]
+    [InlineData (nameof (W3cColor.DimGrey))]
+    [InlineData (nameof (W3cColor.Fuchsia))]
+    [InlineData (nameof (W3cColor.LightGray))]
+    [InlineData (nameof (W3cColor.LightGrey))]
+    [InlineData (nameof (W3cColor.LightSlateGray))]
+    [InlineData (nameof (W3cColor.LightSlateGrey))]
+    [InlineData (nameof (W3cColor.Magenta))]
+    [InlineData (nameof (W3cColor.SlateGray))]
+    [InlineData (nameof (W3cColor.SlateGrey))]
+    public void GetColorNames_IncludesNamesWithSameValues (string name)
+    {
+        string[] names = _candidate.GetColorNames ().ToArray();
+
+        Assert.True (names.Contains (name), $"W3C color names is missing '{name}'.");
+    }
+
+    [Theory]
+    [InlineData (240, 248, 255, nameof (W3cColor.AliceBlue))]
+    [InlineData (0, 255, 255, nameof (W3cColor.Aqua))]
+    [InlineData (255, 0, 0, nameof (W3cColor.Red))]
+    [InlineData (0, 128, 0, nameof (W3cColor.Green))]
+    [InlineData (0, 0, 255, nameof (W3cColor.Blue))]
+    [InlineData (0, 255, 0, nameof (W3cColor.Lime))]
+    [InlineData (0, 0, 0, nameof (W3cColor.Black))]
+    [InlineData (255, 255, 255, nameof (W3cColor.White))]
+    [InlineData (154, 205, 50, nameof (W3cColor.YellowGreen))]
+    public void TryNameColor_ReturnsExpectedColorName (int r, int g, int b, string expectedName)
+    {
+        var expected = (true, expectedName);
+
+        Color inputColor = new(r, g, b);
+        bool actualSuccess = _candidate.TryNameColor (inputColor, out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Fact]
+    public void TryNameColor_NoMatchFails ()
+    {
+        (bool, string?) expected = (false, null);
+
+        bool actualSuccess = _candidate.TryNameColor (new Color (1, 2, 3), out string? actualName);
+        var actual = (actualSuccess, actualName);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (nameof (W3cColor.AliceBlue), 240, 248, 255)]
+    [InlineData (nameof (W3cColor.BlanchedAlmond), 255, 235, 205)]
+    [InlineData (nameof (W3cColor.CadetBlue), 95, 158, 160)]
+    [InlineData (nameof (W3cColor.DarkBlue), 0, 0, 139)]
+    [InlineData (nameof (W3cColor.FireBrick), 178, 34, 34)]
+    [InlineData (nameof (W3cColor.Gainsboro), 220, 220, 220)]
+    [InlineData (nameof (W3cColor.HoneyDew), 240, 255, 240)]
+    [InlineData (nameof (W3cColor.Indigo), 75, 0, 130)]
+    [InlineData (nameof (W3cColor.Khaki), 240, 230, 140)]
+    [InlineData (nameof (W3cColor.Lavender), 230, 230, 250)]
+    [InlineData (nameof (W3cColor.Maroon), 128, 0, 0)]
+    [InlineData (nameof (W3cColor.Navy), 0, 0, 128)]
+    [InlineData (nameof (W3cColor.Olive), 128, 128, 0)]
+    [InlineData (nameof (W3cColor.Plum), 221, 160, 221)]
+    [InlineData (nameof (W3cColor.RoyalBlue), 65, 105, 225)]
+    [InlineData (nameof (W3cColor.Silver), 192, 192, 192)]
+    [InlineData (nameof (W3cColor.Tomato), 255, 99, 71)]
+    [InlineData (nameof (W3cColor.Violet), 238, 130, 238)]
+    [InlineData (nameof (W3cColor.WhiteSmoke), 245, 245, 245)]
+    [InlineData (nameof (W3cColor.YellowGreen), 154, 205, 50)]
+    // Aliases also work
+    [InlineData (nameof (W3cColor.Aqua), 0, 255, 255)]
+    [InlineData (nameof (W3cColor.Cyan), 0, 255, 255)]
+    [InlineData (nameof (W3cColor.DarkGray), 169, 169, 169)]
+    [InlineData (nameof (W3cColor.DarkGrey), 169, 169, 169)]
+    // Case-insensitive
+    [InlineData ("Red", 255, 0, 0)]
+    [InlineData ("red", 255, 0, 0)]
+    [InlineData ("RED", 255, 0, 0)]
+    public void TryParseColor_ReturnsExpectedColor (string inputName, int r, int g, int b)
+    {
+        var expected = (true, new Color(r, g, b));
+
+        bool actualSuccess = _candidate.TryParseColor (inputName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ("16737095", 255, 99, 71)] // W3cColor.Tomato
+    public void TryParseColor_ResolvesValidEnumNumber (string inputName, byte r, byte g, byte b)
+    {
+        var expected = (true, new Color(r, g, b));
+
+        bool actualSuccess = _candidate.TryParseColor (inputName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData (null)]
+    [InlineData ("")]
+    [InlineData ("brightlight")]
+    public void TryParseColor_FailsOnInvalidColorName (string? invalidName)
+    {
+        var expected = (false, default(Color));
+
+        bool actualSuccess = _candidate.TryParseColor (invalidName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+
+    [Theory]
+    [InlineData ("-16737095")]
+    public void TryParseColor_FailsOnInvalidEnumNumber (string invalidName)
+    {
+        var expected = (false, default(Color));
+
+        bool actualSuccess = _candidate.TryParseColor (invalidName, out Color actualColor);
+        var actual = (actualSuccess, actualColor);
+
+        Assert.Equal (expected, actual);
+    }
+}