Remove hooking of system color changes (dotnet/corefx#39468)
authorJeremy Kuhne <jkuhne@microsoft.com>
Tue, 16 Jul 2019 04:21:10 +0000 (21:21 -0700)
committerGitHub <noreply@github.com>
Tue, 16 Jul 2019 04:21:10 +0000 (21:21 -0700)
* Remove hooking of system color changes

Hooking user preference changes to update system colors is expensive, particularly as it is hooked via reflection. Getting the current color from the OS is extremely cheap.  Removing this layer of caching avoids creating a watcher window and thread and a significant number of startup allocations.

In starting up a blank WinForms app this cuts 200 allocations.

Note that Pens and Brushes in System.Drawing start their own user preference watcher so that they can update GDI+ when backed by system colors.

* Address feedback

* Remove newly dead files

Commit migrated from https://github.com/dotnet/corefx/commit/97c736e09f2e119d6ec3d3ebebb7234dee48145d

20 files changed:
src/libraries/Common/src/Interop/Windows/User32/Interop.GetSysColor.cs
src/libraries/Common/src/Interop/Windows/User32/Interop.Win32SystemColors.cs
src/libraries/Common/src/System/Drawing/ColorTranslator.cs
src/libraries/Common/src/System/Drawing/ColorUtil.netcoreapp20.cs [deleted file]
src/libraries/Common/src/System/Drawing/ColorUtil.netcoreapp21.cs [deleted file]
src/libraries/Common/src/System/Drawing/KnownColor.cs
src/libraries/Common/src/System/Drawing/KnownColorTable.cs
src/libraries/Common/src/System/Drawing/SystemColors.cs
src/libraries/System.Drawing.Common/src/System.Drawing.Common.csproj
src/libraries/System.Drawing.Common/src/System/Drawing/Pen.cs
src/libraries/System.Drawing.Common/src/System/Drawing/SolidBrush.cs
src/libraries/System.Drawing.Common/src/System/Drawing/SystemBrushes.cs
src/libraries/System.Drawing.Common/src/System/Drawing/SystemPens.cs
src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj
src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs
src/libraries/System.Drawing.Primitives/src/System/Drawing/KnownColorNames.cs [new file with mode: 0644]
src/libraries/System.Drawing.Primitives/tests/ColorTests.cs
src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs [new file with mode: 0644]
src/libraries/System.Drawing.Primitives/tests/Helpers.cs [new file with mode: 0644]
src/libraries/System.Drawing.Primitives/tests/System.Drawing.Primitives.Tests.csproj

index 8ce696a..0a4d690 100644 (file)
@@ -8,7 +8,14 @@ internal partial class Interop
 {
     internal partial class User32
     {
-        [DllImport(Libraries.User32, SetLastError = true, CharSet = CharSet.Auto)]
-        public static extern int GetSysColor(int nIndex);
+        // The returned value is a COLORREF. The docs don't say that explicitly, but
+        // they do document the same macros (GetRValue, etc.). [0x00BBGGRR]
+        //
+        // This API sets last error, but we never check it and as such we won't take
+        // the overhead in the P/Invoke. It will only fail if we try and grab a color
+        // index that doesn't exist.
+
+        [DllImport(Libraries.User32, ExactSpelling = true)]
+        internal static extern uint GetSysColor(int nIndex);
     }
-}
\ No newline at end of file
+}
index 2ba4db8..6094c65 100644 (file)
@@ -6,7 +6,7 @@ internal partial class Interop
 {
     internal partial class User32
     {
-        internal enum Win32SystemColors
+        internal enum Win32SystemColors : byte
         {
             ActiveBorder = 0x0A,
             ActiveCaption = 0x02,
@@ -43,4 +43,4 @@ internal partial class Interop
             WindowText = 0x08
         }
     }
-}
\ No newline at end of file
+}
index e5a8893..d186d35 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 
 namespace System.Drawing
@@ -12,18 +13,27 @@ namespace System.Drawing
     /// </summary>
     public static class ColorTranslator
     {
-        private const int Win32RedShift = 0;
-        private const int Win32GreenShift = 8;
-        private const int Win32BlueShift = 16;
+        // COLORREF is 0x00BBGGRR
+        internal const int COLORREF_RedShift = 0;
+        internal const int COLORREF_GreenShift = 8;
+        internal const int COLORREF_BlueShift = 16;
 
-        private static Hashtable s_htmlSysColorTable;
+        private const int OleSystemColorFlag = unchecked((int)0x80000000);
+
+        private static Dictionary<string, Color> s_htmlSysColorTable;
+
+        internal static uint COLORREFToARGB(uint value)
+            => ((value >> COLORREF_RedShift) & 0xFF) << Color.ARGBRedShift
+                | ((value >> COLORREF_GreenShift) & 0xFF) << Color.ARGBGreenShift
+                | ((value >> COLORREF_BlueShift) & 0xFF) << Color.ARGBBlueShift
+                | Color.ARGBAlphaMask; // COLORREF's are always fully opaque
 
         /// <summary>
         /// Translates the specified <see cref='Color'/> to a Win32 color.
         /// </summary>
         public static int ToWin32(Color c)
         {
-            return c.R << Win32RedShift | c.G << Win32GreenShift | c.B << Win32BlueShift;
+            return c.R << COLORREF_RedShift | c.G << COLORREF_GreenShift | c.B << COLORREF_BlueShift;
         }
 
         /// <summary>
@@ -31,13 +41,17 @@ namespace System.Drawing
         /// </summary>
         public static int ToOle(Color c)
         {
-            //    WARNING!!! WARNING!!! WARNING!!! WARNING!!! 
-            //    WARNING!!! WARNING!!! WARNING!!! WARNING!!!
-            //    We must never have another method called ToOle() with a different signature.
-            //    This is so that we can push into the runtime a custom marshaller for OLE_COLOR to Color.
+            // IMPORTANT: This signature is invoked directly by the runtime marshaler and cannot change without
+            // also updating the runtime.
+
+            // This method converts Color to an OLE_COLOR.
+            // https://docs.microsoft.com/openspecs/office_file_formats/ms-oforms/4b8f4be0-3fff-4e42-9fc1-b9fd00251e8e
 
-            if (ColorUtil.GetIsKnownColor(c))
+            if (c.IsKnownColor && c.IsSystemColor)
             {
+                // Unfortunately KnownColor didn't keep the same ordering as the various GetSysColor()
+                // COLOR_ * values, otherwise this could be greatly simplified.
+
                 switch (c.ToKnownColor())
                 {
                     case KnownColor.ActiveBorder:
@@ -117,80 +131,78 @@ namespace System.Drawing
         /// </summary>
         public static Color FromOle(int oleColor)
         {
-            //    WARNING!!! WARNING!!! WARNING!!! WARNING!!! 
-            //    WARNING!!! WARNING!!! WARNING!!! WARNING!!!
-            //    We must never have another method called ToOle() with a different signature.
-            //    This is so that we can push into the runtime a custom marshaller for OLE_COLOR to Color.
+            // IMPORTANT: This signature is invoked directly by the runtime marshaler and cannot change without
+            // also updating the runtime.
 
-            switch (oleColor)
+            if ((oleColor & OleSystemColorFlag) != 0)
             {
-                case unchecked((int)0x8000000A):
-                    return ColorUtil.FromKnownColor(KnownColor.ActiveBorder);
-                case unchecked((int)0x80000002):
-                    return ColorUtil.FromKnownColor(KnownColor.ActiveCaption);
-                case unchecked((int)0x80000009):
-                    return ColorUtil.FromKnownColor(KnownColor.ActiveCaptionText);
-                case unchecked((int)0x8000000C):
-                    return ColorUtil.FromKnownColor(KnownColor.AppWorkspace);
-                case unchecked((int)0x8000000F):
-                    return ColorUtil.FromKnownColor(KnownColor.Control);
-                case unchecked((int)0x80000010):
-                    return ColorUtil.FromKnownColor(KnownColor.ControlDark);
-                case unchecked((int)0x80000015):
-                    return ColorUtil.FromKnownColor(KnownColor.ControlDarkDark);
-                case unchecked((int)0x80000016):
-                    return ColorUtil.FromKnownColor(KnownColor.ControlLight);
-                case unchecked((int)0x80000014):
-                    return ColorUtil.FromKnownColor(KnownColor.ControlLightLight);
-                case unchecked((int)0x80000012):
-                    return ColorUtil.FromKnownColor(KnownColor.ControlText);
-                case unchecked((int)0x80000001):
-                    return ColorUtil.FromKnownColor(KnownColor.Desktop);
-                case unchecked((int)0x8000001B):
-                    return ColorUtil.FromKnownColor(KnownColor.GradientActiveCaption);
-                case unchecked((int)0x8000001C):
-                    return ColorUtil.FromKnownColor(KnownColor.GradientInactiveCaption);
-                case unchecked((int)0x80000011):
-                    return ColorUtil.FromKnownColor(KnownColor.GrayText);
-                case unchecked((int)0x8000000D):
-                    return ColorUtil.FromKnownColor(KnownColor.Highlight);
-                case unchecked((int)0x8000000E):
-                    return ColorUtil.FromKnownColor(KnownColor.HighlightText);
-                case unchecked((int)0x8000001A):
-                    return ColorUtil.FromKnownColor(KnownColor.HotTrack);
-                case unchecked((int)0x8000000B):
-                    return ColorUtil.FromKnownColor(KnownColor.InactiveBorder);
-                case unchecked((int)0x80000003):
-                    return ColorUtil.FromKnownColor(KnownColor.InactiveCaption);
-                case unchecked((int)0x80000013):
-                    return ColorUtil.FromKnownColor(KnownColor.InactiveCaptionText);
-                case unchecked((int)0x80000018):
-                    return ColorUtil.FromKnownColor(KnownColor.Info);
-                case unchecked((int)0x80000017):
-                    return ColorUtil.FromKnownColor(KnownColor.InfoText);
-                case unchecked((int)0x80000004):
-                    return ColorUtil.FromKnownColor(KnownColor.Menu);
-                case unchecked((int)0x8000001E):
-                    return ColorUtil.FromKnownColor(KnownColor.MenuBar);
-                case unchecked((int)0x8000001D):
-                    return ColorUtil.FromKnownColor(KnownColor.MenuHighlight);
-                case unchecked((int)0x80000007):
-                    return ColorUtil.FromKnownColor(KnownColor.MenuText);
-                case unchecked((int)0x80000000):
-                    return ColorUtil.FromKnownColor(KnownColor.ScrollBar);
-                case unchecked((int)0x80000005):
-                    return ColorUtil.FromKnownColor(KnownColor.Window);
-                case unchecked((int)0x80000006):
-                    return ColorUtil.FromKnownColor(KnownColor.WindowFrame);
-                case unchecked((int)0x80000008):
-                    return ColorUtil.FromKnownColor(KnownColor.WindowText);
+                switch (oleColor)
+                {
+                    case unchecked((int)0x8000000A):
+                        return Color.FromKnownColor(KnownColor.ActiveBorder);
+                    case unchecked((int)0x80000002):
+                        return Color.FromKnownColor(KnownColor.ActiveCaption);
+                    case unchecked((int)0x80000009):
+                        return Color.FromKnownColor(KnownColor.ActiveCaptionText);
+                    case unchecked((int)0x8000000C):
+                        return Color.FromKnownColor(KnownColor.AppWorkspace);
+                    case unchecked((int)0x8000000F):
+                        return Color.FromKnownColor(KnownColor.Control);
+                    case unchecked((int)0x80000010):
+                        return Color.FromKnownColor(KnownColor.ControlDark);
+                    case unchecked((int)0x80000015):
+                        return Color.FromKnownColor(KnownColor.ControlDarkDark);
+                    case unchecked((int)0x80000016):
+                        return Color.FromKnownColor(KnownColor.ControlLight);
+                    case unchecked((int)0x80000014):
+                        return Color.FromKnownColor(KnownColor.ControlLightLight);
+                    case unchecked((int)0x80000012):
+                        return Color.FromKnownColor(KnownColor.ControlText);
+                    case unchecked((int)0x80000001):
+                        return Color.FromKnownColor(KnownColor.Desktop);
+                    case unchecked((int)0x8000001B):
+                        return Color.FromKnownColor(KnownColor.GradientActiveCaption);
+                    case unchecked((int)0x8000001C):
+                        return Color.FromKnownColor(KnownColor.GradientInactiveCaption);
+                    case unchecked((int)0x80000011):
+                        return Color.FromKnownColor(KnownColor.GrayText);
+                    case unchecked((int)0x8000000D):
+                        return Color.FromKnownColor(KnownColor.Highlight);
+                    case unchecked((int)0x8000000E):
+                        return Color.FromKnownColor(KnownColor.HighlightText);
+                    case unchecked((int)0x8000001A):
+                        return Color.FromKnownColor(KnownColor.HotTrack);
+                    case unchecked((int)0x8000000B):
+                        return Color.FromKnownColor(KnownColor.InactiveBorder);
+                    case unchecked((int)0x80000003):
+                        return Color.FromKnownColor(KnownColor.InactiveCaption);
+                    case unchecked((int)0x80000013):
+                        return Color.FromKnownColor(KnownColor.InactiveCaptionText);
+                    case unchecked((int)0x80000018):
+                        return Color.FromKnownColor(KnownColor.Info);
+                    case unchecked((int)0x80000017):
+                        return Color.FromKnownColor(KnownColor.InfoText);
+                    case unchecked((int)0x80000004):
+                        return Color.FromKnownColor(KnownColor.Menu);
+                    case unchecked((int)0x8000001E):
+                        return Color.FromKnownColor(KnownColor.MenuBar);
+                    case unchecked((int)0x8000001D):
+                        return Color.FromKnownColor(KnownColor.MenuHighlight);
+                    case unchecked((int)0x80000007):
+                        return Color.FromKnownColor(KnownColor.MenuText);
+                    case unchecked((int)0x80000000):
+                        return Color.FromKnownColor(KnownColor.ScrollBar);
+                    case unchecked((int)0x80000005):
+                        return Color.FromKnownColor(KnownColor.Window);
+                    case unchecked((int)0x80000006):
+                        return Color.FromKnownColor(KnownColor.WindowFrame);
+                    case unchecked((int)0x80000008):
+                        return Color.FromKnownColor(KnownColor.WindowText);
+                }
             }
 
-            Color color = Color.FromArgb((byte)((oleColor >> Win32RedShift) & 0xFF),
-                                         (byte)((oleColor >> Win32GreenShift) & 0xFF),
-                                         (byte)((oleColor >> Win32BlueShift) & 0xFF));
-
-            return KnownColorTable.ArgbToKnownColor(color.ToArgb());
+            // When we don't find a system color, we treat the color as a COLORREF
+            return KnownColorTable.ArgbToKnownColor(COLORREFToARGB((uint)oleColor));
         }
 
         /// <summary>
@@ -248,11 +260,7 @@ namespace System.Drawing
                     InitializeHtmlSysColorTable();
                 }
 
-                object o = s_htmlSysColorTable[htmlColor.ToLower(CultureInfo.InvariantCulture)];
-                if (o != null)
-                {
-                    c = (Color)o;
-                }
+                s_htmlSysColorTable.TryGetValue(htmlColor.ToLower(CultureInfo.InvariantCulture), out c);
             }
 
             // resort to type converter which will handle named colors
@@ -281,7 +289,7 @@ namespace System.Drawing
             if (c.IsEmpty)
                 return colorString;
 
-            if (ColorUtil.IsSystemColor(c))
+            if (c.IsSystemColor)
             {
                 switch (c.ToKnownColor())
                 {
@@ -391,34 +399,36 @@ namespace System.Drawing
 
         private static void InitializeHtmlSysColorTable()
         {
-            s_htmlSysColorTable = new Hashtable(26);
-            s_htmlSysColorTable["activeborder"] = ColorUtil.FromKnownColor(KnownColor.ActiveBorder);
-            s_htmlSysColorTable["activecaption"] = ColorUtil.FromKnownColor(KnownColor.ActiveCaption);
-            s_htmlSysColorTable["appworkspace"] = ColorUtil.FromKnownColor(KnownColor.AppWorkspace);
-            s_htmlSysColorTable["background"] = ColorUtil.FromKnownColor(KnownColor.Desktop);
-            s_htmlSysColorTable["buttonface"] = ColorUtil.FromKnownColor(KnownColor.Control);
-            s_htmlSysColorTable["buttonhighlight"] = ColorUtil.FromKnownColor(KnownColor.ControlLightLight);
-            s_htmlSysColorTable["buttonshadow"] = ColorUtil.FromKnownColor(KnownColor.ControlDark);
-            s_htmlSysColorTable["buttontext"] = ColorUtil.FromKnownColor(KnownColor.ControlText);
-            s_htmlSysColorTable["captiontext"] = ColorUtil.FromKnownColor(KnownColor.ActiveCaptionText);
-            s_htmlSysColorTable["graytext"] = ColorUtil.FromKnownColor(KnownColor.GrayText);
-            s_htmlSysColorTable["highlight"] = ColorUtil.FromKnownColor(KnownColor.Highlight);
-            s_htmlSysColorTable["highlighttext"] = ColorUtil.FromKnownColor(KnownColor.HighlightText);
-            s_htmlSysColorTable["inactiveborder"] = ColorUtil.FromKnownColor(KnownColor.InactiveBorder);
-            s_htmlSysColorTable["inactivecaption"] = ColorUtil.FromKnownColor(KnownColor.InactiveCaption);
-            s_htmlSysColorTable["inactivecaptiontext"] = ColorUtil.FromKnownColor(KnownColor.InactiveCaptionText);
-            s_htmlSysColorTable["infobackground"] = ColorUtil.FromKnownColor(KnownColor.Info);
-            s_htmlSysColorTable["infotext"] = ColorUtil.FromKnownColor(KnownColor.InfoText);
-            s_htmlSysColorTable["menu"] = ColorUtil.FromKnownColor(KnownColor.Menu);
-            s_htmlSysColorTable["menutext"] = ColorUtil.FromKnownColor(KnownColor.MenuText);
-            s_htmlSysColorTable["scrollbar"] = ColorUtil.FromKnownColor(KnownColor.ScrollBar);
-            s_htmlSysColorTable["threeddarkshadow"] = ColorUtil.FromKnownColor(KnownColor.ControlDarkDark);
-            s_htmlSysColorTable["threedface"] = ColorUtil.FromKnownColor(KnownColor.Control);
-            s_htmlSysColorTable["threedhighlight"] = ColorUtil.FromKnownColor(KnownColor.ControlLight);
-            s_htmlSysColorTable["threedlightshadow"] = ColorUtil.FromKnownColor(KnownColor.ControlLightLight);
-            s_htmlSysColorTable["window"] = ColorUtil.FromKnownColor(KnownColor.Window);
-            s_htmlSysColorTable["windowframe"] = ColorUtil.FromKnownColor(KnownColor.WindowFrame);
-            s_htmlSysColorTable["windowtext"] = ColorUtil.FromKnownColor(KnownColor.WindowText);
+            s_htmlSysColorTable = new Dictionary<string, Color>(27)
+            {
+                ["activeborder"] = Color.FromKnownColor(KnownColor.ActiveBorder),
+                ["activecaption"] = Color.FromKnownColor(KnownColor.ActiveCaption),
+                ["appworkspace"] = Color.FromKnownColor(KnownColor.AppWorkspace),
+                ["background"] = Color.FromKnownColor(KnownColor.Desktop),
+                ["buttonface"] = Color.FromKnownColor(KnownColor.Control),
+                ["buttonhighlight"] = Color.FromKnownColor(KnownColor.ControlLightLight),
+                ["buttonshadow"] = Color.FromKnownColor(KnownColor.ControlDark),
+                ["buttontext"] = Color.FromKnownColor(KnownColor.ControlText),
+                ["captiontext"] = Color.FromKnownColor(KnownColor.ActiveCaptionText),
+                ["graytext"] = Color.FromKnownColor(KnownColor.GrayText),
+                ["highlight"] = Color.FromKnownColor(KnownColor.Highlight),
+                ["highlighttext"] = Color.FromKnownColor(KnownColor.HighlightText),
+                ["inactiveborder"] = Color.FromKnownColor(KnownColor.InactiveBorder),
+                ["inactivecaption"] = Color.FromKnownColor(KnownColor.InactiveCaption),
+                ["inactivecaptiontext"] = Color.FromKnownColor(KnownColor.InactiveCaptionText),
+                ["infobackground"] = Color.FromKnownColor(KnownColor.Info),
+                ["infotext"] = Color.FromKnownColor(KnownColor.InfoText),
+                ["menu"] = Color.FromKnownColor(KnownColor.Menu),
+                ["menutext"] = Color.FromKnownColor(KnownColor.MenuText),
+                ["scrollbar"] = Color.FromKnownColor(KnownColor.ScrollBar),
+                ["threeddarkshadow"] = Color.FromKnownColor(KnownColor.ControlDarkDark),
+                ["threedface"] = Color.FromKnownColor(KnownColor.Control),
+                ["threedhighlight"] = Color.FromKnownColor(KnownColor.ControlLight),
+                ["threedlightshadow"] = Color.FromKnownColor(KnownColor.ControlLightLight),
+                ["window"] = Color.FromKnownColor(KnownColor.Window),
+                ["windowframe"] = Color.FromKnownColor(KnownColor.WindowFrame),
+                ["windowtext"] = Color.FromKnownColor(KnownColor.WindowText)
+            };
         }
     }
 }
diff --git a/src/libraries/Common/src/System/Drawing/ColorUtil.netcoreapp20.cs b/src/libraries/Common/src/System/Drawing/ColorUtil.netcoreapp20.cs
deleted file mode 100644 (file)
index 259c9ae..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Diagnostics;
-using System.Reflection;
-
-namespace System.Drawing
-{
-    // System.Drawing.Common uses several members on System.Drawing.Common which are implemented in .NET Core 2.0, but
-    // not exposed. This is a helper class which allows System.Drawing.Common to access those members through reflection.
-    internal static class ColorUtil
-    {
-        private const short StateKnownColorValid = 0x0001;
-        private const short StateNameValid = 0x0008;
-        private const long NotDefinedValue = 0;
-
-        private static readonly ConstructorInfo s_ctorKnownColor; // internal Color(KnownColor knownColor)
-        private static readonly ConstructorInfo s_ctorAllValues; // private Color(long value, short state, string name, KnownColor knownColor)
-        private static readonly FieldInfo s_fieldKnownColor; // private readonly short knownColor
-        private static readonly FieldInfo s_fieldState; // private readonly short state
-
-        static ColorUtil()
-        {
-            Type colorType = typeof(Color);
-            Type knownColorType = colorType.Assembly.GetType("System.Drawing.KnownColor", true);
-            Debug.Assert(knownColorType != null);
-            const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
-            s_ctorKnownColor = colorType.GetConstructor(bindingFlags, null, new Type[] { knownColorType }, null);
-            Debug.Assert(s_ctorKnownColor != null);
-
-            s_ctorAllValues = colorType.GetConstructor(bindingFlags, null, new Type[] { typeof(long), typeof(short), typeof(string), knownColorType }, null);
-            Debug.Assert(s_ctorAllValues != null);
-
-            s_fieldKnownColor = colorType.GetField("knownColor", bindingFlags);
-            Debug.Assert(s_fieldKnownColor != null);
-
-            s_fieldState = colorType.GetField("state", bindingFlags);
-            Debug.Assert(s_fieldState != null);
-        }
-
-        public static Color FromKnownColor(KnownColor color)
-        {
-            var value = (int)color;
-            if (value < (int)KnownColor.ActiveBorder || value > (int)KnownColor.MenuHighlight)
-            {
-                return FromName(color.ToString());
-            }
-
-            return (Color)s_ctorKnownColor.Invoke(new object[] { value });
-        }
-
-        public static Color FromName(string name)
-        {
-            // try to get a known color first
-            Color color;
-            if (ColorTable.TryGetNamedColor(name, out color))
-            {
-                return color;
-            }
-            // otherwise treat it as a named color
-            return (Color)s_ctorAllValues.Invoke(new object[] { NotDefinedValue, StateNameValid, name, 0 });
-        }
-
-        public static bool IsSystemColor(this Color color)
-        {
-            short knownColor = GetKnownColor(color);
-            return GetIsKnownColor(color) && ((((KnownColor)knownColor) <= KnownColor.WindowText) || (((KnownColor)knownColor) > KnownColor.YellowGreen));
-        }
-
-        public static short GetKnownColor(this Color color)
-        {
-            return (short)s_fieldKnownColor.GetValue(color);
-        }
-
-        public static short GetState(this Color color)
-        {
-            return (short)s_fieldState.GetValue(color);
-        }
-
-        public static bool GetIsSystemColor(this Color color)
-        {
-            short knownColor = color.GetKnownColor();
-            return GetIsKnownColor(color) && ((((KnownColor)knownColor) <= KnownColor.WindowText) || (((KnownColor)knownColor) > KnownColor.YellowGreen));
-        }
-
-        public static bool GetIsKnownColor(this Color color)
-        {
-            short state = GetState(color);
-            return ((state & StateKnownColorValid) != 0);
-        }
-
-        public static KnownColor ToKnownColor(this Color c)
-        {
-            return (KnownColor)GetKnownColor(c);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/libraries/Common/src/System/Drawing/ColorUtil.netcoreapp21.cs b/src/libraries/Common/src/System/Drawing/ColorUtil.netcoreapp21.cs
deleted file mode 100644 (file)
index 3b4cfca..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-namespace System.Drawing
-{
-    internal static class ColorUtil
-    {
-        public static Color FromKnownColor(KnownColor color) => Color.FromKnownColor(color);
-        public static bool IsSystemColor(this Color color) => color.IsSystemColor;
-        public static bool GetIsKnownColor(this Color color) => color.IsKnownColor;
-    }
-}
\ No newline at end of file
index 03978ba..ce2db64 100644 (file)
@@ -3,11 +3,12 @@
 // See the LICENSE file in the project root for more information.
 
 using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
 
 namespace System.Drawing
 {
     [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")]
-    [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+    [TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
 #if netcoreapp20
     internal
 #else
@@ -15,363 +16,192 @@ namespace System.Drawing
 #endif
     enum KnownColor
     {
-        // This enum is order dependant!!!
+        // This enum is order dependent!!!
         //
         // The value of these known colors are indexes into a color array.
         // Do not modify this enum without updating KnownColorTable.
-        //
 
         // 0 - reserved for "not a known color"
+
         // "System" colors
         ActiveBorder = 1,
-
         ActiveCaption,
-
         ActiveCaptionText,
-
         AppWorkspace,
-
         Control,
-
         ControlDark,
-
         ControlDarkDark,
-
         ControlLight,
-
         ControlLightLight,
-
         ControlText,
-
         Desktop,
-
         GrayText,
-
         Highlight,
-
         HighlightText,
-
         HotTrack,
-
         InactiveBorder,
-
         InactiveCaption,
-
         InactiveCaptionText,
-
         Info,
-
         InfoText,
-
         Menu,
-
         MenuText,
-
         ScrollBar,
-
         Window,
-
         WindowFrame,
-
         WindowText,
 
         // "Web" Colors
         Transparent,
-
         AliceBlue,
-
         AntiqueWhite,
-
         Aqua,
-
         Aquamarine,
-
         Azure,
-
         Beige,
-
         Bisque,
-
         Black,
-
         BlanchedAlmond,
-
         Blue,
-
         BlueViolet,
-
         Brown,
-
         BurlyWood,
-
         CadetBlue,
-
         Chartreuse,
-
         Chocolate,
-
         Coral,
-
         CornflowerBlue,
-
         Cornsilk,
-
         Crimson,
-
         Cyan,
-
         DarkBlue,
-
         DarkCyan,
-
         DarkGoldenrod,
-
         DarkGray,
-
         DarkGreen,
-
         DarkKhaki,
-
         DarkMagenta,
-
         DarkOliveGreen,
-
         DarkOrange,
-
         DarkOrchid,
-
         DarkRed,
-
         DarkSalmon,
-
         DarkSeaGreen,
-
         DarkSlateBlue,
-
         DarkSlateGray,
-
         DarkTurquoise,
-
         DarkViolet,
-
         DeepPink,
-
         DeepSkyBlue,
-
         DimGray,
-
         DodgerBlue,
-
         Firebrick,
-
         FloralWhite,
-
         ForestGreen,
-
         Fuchsia,
-
         Gainsboro,
-
         GhostWhite,
-
         Gold,
-
         Goldenrod,
-
         Gray,
-
         Green,
-
         GreenYellow,
-
         Honeydew,
-
         HotPink,
-
         IndianRed,
-
         Indigo,
-
         Ivory,
-
         Khaki,
-
         Lavender,
-
         LavenderBlush,
-
         LawnGreen,
-
         LemonChiffon,
-
         LightBlue,
-
         LightCoral,
-
         LightCyan,
-
         LightGoldenrodYellow,
-
         LightGray,
-
         LightGreen,
-
         LightPink,
-
         LightSalmon,
-
         LightSeaGreen,
-
         LightSkyBlue,
-
         LightSlateGray,
-
         LightSteelBlue,
-
         LightYellow,
-
         Lime,
-
         LimeGreen,
-
         Linen,
-
         Magenta,
-
         Maroon,
-
         MediumAquamarine,
-
         MediumBlue,
-
         MediumOrchid,
-
         MediumPurple,
-
         MediumSeaGreen,
-
         MediumSlateBlue,
-
         MediumSpringGreen,
-
         MediumTurquoise,
-
         MediumVioletRed,
-
         MidnightBlue,
-
         MintCream,
-
         MistyRose,
-
         Moccasin,
-
         NavajoWhite,
-
         Navy,
-
         OldLace,
-
         Olive,
-
         OliveDrab,
-
         Orange,
-
         OrangeRed,
-
         Orchid,
-
         PaleGoldenrod,
-
         PaleGreen,
-
         PaleTurquoise,
-
         PaleVioletRed,
-
         PapayaWhip,
-
         PeachPuff,
-
         Peru,
-
         Pink,
-
         Plum,
-
         PowderBlue,
-
         Purple,
-
         Red,
-
         RosyBrown,
-
         RoyalBlue,
-
         SaddleBrown,
-
         Salmon,
-
         SandyBrown,
-
         SeaGreen,
-
         SeaShell,
-
         Sienna,
-
         Silver,
-
         SkyBlue,
-
         SlateBlue,
-
         SlateGray,
-
         Snow,
-
         SpringGreen,
-
         SteelBlue,
-
         Tan,
-
         Teal,
-
         Thistle,
-
         Tomato,
-
         Turquoise,
-
         Violet,
-
         Wheat,
-
         White,
-
         WhiteSmoke,
-
         Yellow,
-
         YellowGreen,
 
-        // NEW ADDITIONS IN WHIDBEY - DO NOT MOVE THESE UP OR IT WILL BE A BREAKING CHANGE
+        // New system color additions in Visual Studio 2005 (.NET Framework 2.0)
 
         ButtonFace,
-
         ButtonHighlight,
-
         ButtonShadow,
-
         GradientActiveCaption,
-
         GradientInactiveCaption,
-
         MenuBar,
-
         MenuHighlight
     }
 }
index 6a1d5ea..fe19c05 100644 (file)
 // See the LICENSE file in the project root for more information.
 
 using System.Diagnostics;
-using System.Reflection;
 
 namespace System.Drawing
 {
-    static internal class KnownColorTable
+    internal static class KnownColorTable
     {
-        private static MethodInfo s_categoryGetter;
-        private static int[] s_colorTable;
-        private static string[] s_colorNameTable;
-
-        /**
-         * Shift count and bit mask for A, R, G, B components
-         */
-        private const int AlphaShift = 24;
-        private const int RedShift = 16;
-        private const int GreenShift = 8;
-        private const int BlueShift = 0;
-
-        private const int Win32RedShift = 0;
-        private const int Win32GreenShift = 8;
-        private const int Win32BlueShift = 16;
+        // All non system colors (in order of definition in the KnownColor enum).
+        private static readonly uint[] s_colorTable = new uint[]
+        {
+            0x00FFFFFF,     // Transparent
+            0xFFF0F8FF,     // AliceBlue
+            0xFFFAEBD7,     // AntiqueWhite
+            0xFF00FFFF,     // Aqua
+            0xFF7FFFD4,     // Aquamarine
+            0xFFF0FFFF,     // Azure
+            0xFFF5F5DC,     // Beige
+            0xFFFFE4C4,     // Bisque
+            0xFF000000,     // Black
+            0xFFFFEBCD,     // BlanchedAlmond
+            0xFF0000FF,     // Blue
+            0xFF8A2BE2,     // BlueViolet
+            0xFFA52A2A,     // Brown
+            0xFFDEB887,     // BurlyWood
+            0xFF5F9EA0,     // CadetBlue
+            0xFF7FFF00,     // Chartreuse
+            0xFFD2691E,     // Chocolate
+            0xFFFF7F50,     // Coral
+            0xFF6495ED,     // CornflowerBlue
+            0xFFFFF8DC,     // Cornsilk
+            0xFFDC143C,     // Crimson
+            0xFF00FFFF,     // Cyan
+            0xFF00008B,     // DarkBlue
+            0xFF008B8B,     // DarkCyan
+            0xFFB8860B,     // DarkGoldenrod
+            0xFFA9A9A9,     // DarkGray
+            0xFF006400,     // DarkGreen
+            0xFFBDB76B,     // DarkKhaki
+            0xFF8B008B,     // DarkMagenta
+            0xFF556B2F,     // DarkOliveGreen
+            0xFFFF8C00,     // DarkOrange
+            0xFF9932CC,     // DarkOrchid
+            0xFF8B0000,     // DarkRed
+            0xFFE9967A,     // DarkSalmon
+            0xFF8FBC8B,     // DarkSeaGreen
+            0xFF483D8B,     // DarkSlateBlue
+            0xFF2F4F4F,     // DarkSlateGray
+            0xFF00CED1,     // DarkTurquoise
+            0xFF9400D3,     // DarkViolet
+            0xFFFF1493,     // DeepPink
+            0xFF00BFFF,     // DeepSkyBlue
+            0xFF696969,     // DimGray
+            0xFF1E90FF,     // DodgerBlue
+            0xFFB22222,     // Firebrick
+            0xFFFFFAF0,     // FloralWhite
+            0xFF228B22,     // ForestGreen
+            0xFFFF00FF,     // Fuchsia
+            0xFFDCDCDC,     // Gainsboro
+            0xFFF8F8FF,     // GhostWhite
+            0xFFFFD700,     // Gold
+            0xFFDAA520,     // Goldenrod
+            0xFF808080,     // Gray
+            0xFF008000,     // Green
+            0xFFADFF2F,     // GreenYellow
+            0xFFF0FFF0,     // Honeydew
+            0xFFFF69B4,     // HotPink
+            0xFFCD5C5C,     // IndianRed
+            0xFF4B0082,     // Indigo
+            0xFFFFFFF0,     // Ivory
+            0xFFF0E68C,     // Khaki
+            0xFFE6E6FA,     // Lavender
+            0xFFFFF0F5,     // LavenderBlush
+            0xFF7CFC00,     // LawnGreen
+            0xFFFFFACD,     // LemonChiffon
+            0xFFADD8E6,     // LightBlue
+            0xFFF08080,     // LightCoral
+            0xFFE0FFFF,     // LightCyan
+            0xFFFAFAD2,     // LightGoldenrodYellow
+            0xFFD3D3D3,     // LightGray
+            0xFF90EE90,     // LightGreen
+            0xFFFFB6C1,     // LightPink
+            0xFFFFA07A,     // LightSalmon
+            0xFF20B2AA,     // LightSeaGreen
+            0xFF87CEFA,     // LightSkyBlue
+            0xFF778899,     // LightSlateGray
+            0xFFB0C4DE,     // LightSteelBlue
+            0xFFFFFFE0,     // LightYellow
+            0xFF00FF00,     // Lime
+            0xFF32CD32,     // LimeGreen
+            0xFFFAF0E6,     // Linen
+            0xFFFF00FF,     // Magenta
+            0xFF800000,     // Maroon
+            0xFF66CDAA,     // MediumAquamarine
+            0xFF0000CD,     // MediumBlue
+            0xFFBA55D3,     // MediumOrchid
+            0xFF9370DB,     // MediumPurple
+            0xFF3CB371,     // MediumSeaGreen
+            0xFF7B68EE,     // MediumSlateBlue
+            0xFF00FA9A,     // MediumSpringGreen
+            0xFF48D1CC,     // MediumTurquoise
+            0xFFC71585,     // MediumVioletRed
+            0xFF191970,     // MidnightBlue
+            0xFFF5FFFA,     // MintCream
+            0xFFFFE4E1,     // MistyRose
+            0xFFFFE4B5,     // Moccasin
+            0xFFFFDEAD,     // NavajoWhite
+            0xFF000080,     // Navy
+            0xFFFDF5E6,     // OldLace
+            0xFF808000,     // Olive
+            0xFF6B8E23,     // OliveDrab
+            0xFFFFA500,     // Orange
+            0xFFFF4500,     // OrangeRed
+            0xFFDA70D6,     // Orchid
+            0xFFEEE8AA,     // PaleGoldenrod
+            0xFF98FB98,     // PaleGreen
+            0xFFAFEEEE,     // PaleTurquoise
+            0xFFDB7093,     // PaleVioletRed
+            0xFFFFEFD5,     // PapayaWhip
+            0xFFFFDAB9,     // PeachPuff
+            0xFFCD853F,     // Peru
+            0xFFFFC0CB,     // Pink
+            0xFFDDA0DD,     // Plum
+            0xFFB0E0E6,     // PowderBlue
+            0xFF800080,     // Purple
+            0xFFFF0000,     // Red
+            0xFFBC8F8F,     // RosyBrown
+            0xFF4169E1,     // RoyalBlue
+            0xFF8B4513,     // SaddleBrown
+            0xFFFA8072,     // Salmon
+            0xFFF4A460,     // SandyBrown
+            0xFF2E8B57,     // SeaGreen
+            0xFFFFF5EE,     // SeaShell
+            0xFFA0522D,     // Sienna
+            0xFFC0C0C0,     // Silver
+            0xFF87CEEB,     // SkyBlue
+            0xFF6A5ACD,     // SlateBlue
+            0xFF708090,     // SlateGray
+            0xFFFFFAFA,     // Snow
+            0xFF00FF7F,     // SpringGreen
+            0xFF4682B4,     // SteelBlue
+            0xFFD2B48C,     // Tan
+            0xFF008080,     // Teal
+            0xFFD8BFD8,     // Thistle
+            0xFFFF6347,     // Tomato
+            0xFF40E0D0,     // Turquoise
+            0xFFEE82EE,     // Violet
+            0xFFF5DEB3,     // Wheat
+            0xFFFFFFFF,     // White
+            0xFFF5F5F5,     // WhiteSmoke
+            0xFFFFFF00,     // Yellow
+            0xFF9ACD32,     // YellowGreen
+        };
 
-        public static Color ArgbToKnownColor(int targetARGB)
+        internal static Color ArgbToKnownColor(uint argb)
         {
-            EnsureColorTable();
-            for (int index = 0; index < s_colorTable.Length; ++index)
+            // Should be fully opaque (and as such we can skip the first entry
+            // which is transparent).
+            Debug.Assert((argb & Color.ARGBAlphaMask) == Color.ARGBAlphaMask);
+
+            for (int index = 1; index < s_colorTable.Length; ++index)
             {
-                int argb = s_colorTable[index];
-                if (argb == targetARGB)
+                if (s_colorTable[index] == argb)
                 {
-                    Color color = ColorUtil.FromKnownColor((KnownColor)index);
-                    if (!ColorUtil.IsSystemColor(color))
-                        return color;
+                    return Color.FromKnownColor((KnownColor)(index + (int)KnownColor.Transparent));
                 }
             }
 
-            return Color.FromArgb(targetARGB);
+            // Not a known color
+            return Color.FromArgb((int)argb);
         }
 
-        private static void EnsureColorTable()
+        public static uint KnownColorToArgb(KnownColor color)
         {
-            // no need to lock... worse case is a double create of the table...
-            //
-            if (s_colorTable == null)
-            {
-                InitColorTable();
-            }
-        }
-
-        private static void InitColorTable()
-        {
-            int[] values = new int[(unchecked((int)KnownColor.MenuHighlight)) + 1];
-
-            // When Microsoft.Win32.SystemEvents is available, we can react to the UserPreferenceChanging events by updating
-            // SystemColors. In order to avoid a static dependency on SystemEvents since it is not available on all platforms 
-            // and as such we don't want to bring it into the shared framework. We use the desktop identity for SystemEvents
-            // since it is stable and will remain stable for compatibility whereas the core identity could change.
-            Type systemEventsType = Type.GetType("Microsoft.Win32.SystemEvents, Microsoft.Win32.SystemEvents", throwOnError: false);
-            EventInfo upEventInfo = systemEventsType?.GetEvent("UserPreferenceChanging", BindingFlags.Public | BindingFlags.Static);
-
-            if (upEventInfo != null)
-            {
-                // Delegate TargetType
-                Type userPrefChangingDelegateType = Type.GetType("Microsoft.Win32.UserPreferenceChangingEventHandler, Microsoft.Win32.SystemEvents", throwOnError: false);
-                Debug.Assert(userPrefChangingDelegateType != null);
+            Debug.Assert(color > 0 && color <= KnownColor.MenuHighlight);
 
-                if (userPrefChangingDelegateType != null)
-                {
-                    // we are using MethodInfo overload because it allows relaxed signature binding i.e. the types dont need to be exact match. It allows base classes as well.
-                    MethodInfo mi = typeof(KnownColorTable).GetMethod(nameof(OnUserPreferenceChanging), BindingFlags.NonPublic | BindingFlags.Static);
-                    Debug.Assert(mi != null);
+            return Color.IsKnownColorSystem(color)
+                ? GetSystemColorArgb(color)
+                : s_colorTable[(int)color - (int)KnownColor.Transparent];
+        }
 
-                    if (mi != null)
-                    {
-                        // Creating a delegate to use it as event handler.
-                        Delegate handler = Delegate.CreateDelegate(userPrefChangingDelegateType, mi);
-                        upEventInfo.AddEventHandler(null, handler);
-                    }
+#if FEATURE_WINDOWS_SYSTEM_COLORS
 
-                    // Retrieving getter of the category property of the UserPreferenceChangingEventArgs.
-                    Type argsType = Type.GetType("Microsoft.Win32.UserPreferenceChangingEventArgs, Microsoft.Win32.SystemEvents", throwOnError: false);
-                    s_categoryGetter = argsType?.GetMethod("get_Category", BindingFlags.Instance | BindingFlags.Public);
-                    Debug.Assert(s_categoryGetter != null);
-                }
-            }
+        private static ReadOnlySpan<byte> SystemColorIdTable => new byte[]
+        {
+            // In order of definition in KnownColor enum
 
-            UpdateSystemColors(values);
+            // The original group of contiguous system KnownColors
+            (byte)Interop.User32.Win32SystemColors.ActiveBorder,
+            (byte)Interop.User32.Win32SystemColors.ActiveCaption,
+            (byte)Interop.User32.Win32SystemColors.ActiveCaptionText,
+            (byte)Interop.User32.Win32SystemColors.AppWorkspace,
+            (byte)Interop.User32.Win32SystemColors.Control,
+            (byte)Interop.User32.Win32SystemColors.ControlDark,
+            (byte)Interop.User32.Win32SystemColors.ControlDarkDark,
+            (byte)Interop.User32.Win32SystemColors.ControlLight,
+            (byte)Interop.User32.Win32SystemColors.ControlLightLight,
+            (byte)Interop.User32.Win32SystemColors.ControlText,
+            (byte)Interop.User32.Win32SystemColors.Desktop,
+            (byte)Interop.User32.Win32SystemColors.GrayText,
+            (byte)Interop.User32.Win32SystemColors.Highlight,
+            (byte)Interop.User32.Win32SystemColors.HighlightText,
+            (byte)Interop.User32.Win32SystemColors.HotTrack,
+            (byte)Interop.User32.Win32SystemColors.InactiveBorder,
+            (byte)Interop.User32.Win32SystemColors.InactiveCaption,
+            (byte)Interop.User32.Win32SystemColors.InactiveCaptionText,
+            (byte)Interop.User32.Win32SystemColors.Info,
+            (byte)Interop.User32.Win32SystemColors.InfoText,
+            (byte)Interop.User32.Win32SystemColors.Menu,
+            (byte)Interop.User32.Win32SystemColors.MenuText,
+            (byte)Interop.User32.Win32SystemColors.ScrollBar,
+            (byte)Interop.User32.Win32SystemColors.Window,
+            (byte)Interop.User32.Win32SystemColors.WindowFrame,
+            (byte)Interop.User32.Win32SystemColors.WindowText,
 
-            // just consts...
-            //
-            values[(int)KnownColor.Transparent] = 0x00FFFFFF;
-            values[(int)KnownColor.AliceBlue] = unchecked((int)0xFFF0F8FF);
-            values[(int)KnownColor.AntiqueWhite] = unchecked((int)0xFFFAEBD7);
-            values[(int)KnownColor.Aqua] = unchecked((int)0xFF00FFFF);
-            values[(int)KnownColor.Aquamarine] = unchecked((int)0xFF7FFFD4);
-            values[(int)KnownColor.Azure] = unchecked((int)0xFFF0FFFF);
-            values[(int)KnownColor.Beige] = unchecked((int)0xFFF5F5DC);
-            values[(int)KnownColor.Bisque] = unchecked(unchecked((int)0xFFFFE4C4));
-            values[(int)KnownColor.Black] = unchecked((int)0xFF000000);
-            values[(int)KnownColor.BlanchedAlmond] = unchecked((int)0xFFFFEBCD);
-            values[(int)KnownColor.Blue] = unchecked((int)0xFF0000FF);
-            values[(int)KnownColor.BlueViolet] = unchecked((int)0xFF8A2BE2);
-            values[(int)KnownColor.Brown] = unchecked((int)0xFFA52A2A);
-            values[(int)KnownColor.BurlyWood] = unchecked((int)0xFFDEB887);
-            values[(int)KnownColor.CadetBlue] = unchecked((int)0xFF5F9EA0);
-            values[(int)KnownColor.Chartreuse] = unchecked((int)0xFF7FFF00);
-            values[(int)KnownColor.Chocolate] = unchecked((int)0xFFD2691E);
-            values[(int)KnownColor.Coral] = unchecked((int)0xFFFF7F50);
-            values[(int)KnownColor.CornflowerBlue] = unchecked((int)0xFF6495ED);
-            values[(int)KnownColor.Cornsilk] = unchecked((int)0xFFFFF8DC);
-            values[(int)KnownColor.Crimson] = unchecked((int)0xFFDC143C);
-            values[(int)KnownColor.Cyan] = unchecked((int)0xFF00FFFF);
-            values[(int)KnownColor.DarkBlue] = unchecked((int)0xFF00008B);
-            values[(int)KnownColor.DarkCyan] = unchecked((int)0xFF008B8B);
-            values[(int)KnownColor.DarkGoldenrod] = unchecked((int)0xFFB8860B);
-            values[(int)KnownColor.DarkGray] = unchecked((int)0xFFA9A9A9);
-            values[(int)KnownColor.DarkGreen] = unchecked((int)0xFF006400);
-            values[(int)KnownColor.DarkKhaki] = unchecked((int)0xFFBDB76B);
-            values[(int)KnownColor.DarkMagenta] = unchecked((int)0xFF8B008B);
-            values[(int)KnownColor.DarkOliveGreen] = unchecked((int)0xFF556B2F);
-            values[(int)KnownColor.DarkOrange] = unchecked((int)0xFFFF8C00);
-            values[(int)KnownColor.DarkOrchid] = unchecked((int)0xFF9932CC);
-            values[(int)KnownColor.DarkRed] = unchecked((int)0xFF8B0000);
-            values[(int)KnownColor.DarkSalmon] = unchecked((int)0xFFE9967A);
-            values[(int)KnownColor.DarkSeaGreen] = unchecked((int)0xFF8FBC8B);
-            values[(int)KnownColor.DarkSlateBlue] = unchecked((int)0xFF483D8B);
-            values[(int)KnownColor.DarkSlateGray] = unchecked((int)0xFF2F4F4F);
-            values[(int)KnownColor.DarkTurquoise] = unchecked((int)0xFF00CED1);
-            values[(int)KnownColor.DarkViolet] = unchecked((int)0xFF9400D3);
-            values[(int)KnownColor.DeepPink] = unchecked((int)0xFFFF1493);
-            values[(int)KnownColor.DeepSkyBlue] = unchecked((int)0xFF00BFFF);
-            values[(int)KnownColor.DimGray] = unchecked((int)0xFF696969);
-            values[(int)KnownColor.DodgerBlue] = unchecked((int)0xFF1E90FF);
-            values[(int)KnownColor.Firebrick] = unchecked((int)0xFFB22222);
-            values[(int)KnownColor.FloralWhite] = unchecked((int)0xFFFFFAF0);
-            values[(int)KnownColor.ForestGreen] = unchecked((int)0xFF228B22);
-            values[(int)KnownColor.Fuchsia] = unchecked((int)0xFFFF00FF);
-            values[(int)KnownColor.Gainsboro] = unchecked((int)0xFFDCDCDC);
-            values[(int)KnownColor.GhostWhite] = unchecked((int)0xFFF8F8FF);
-            values[(int)KnownColor.Gold] = unchecked((int)0xFFFFD700);
-            values[(int)KnownColor.Goldenrod] = unchecked((int)0xFFDAA520);
-            values[(int)KnownColor.Gray] = unchecked((int)0xFF808080);
-            values[(int)KnownColor.Green] = unchecked((int)0xFF008000);
-            values[(int)KnownColor.GreenYellow] = unchecked((int)0xFFADFF2F);
-            values[(int)KnownColor.Honeydew] = unchecked((int)0xFFF0FFF0);
-            values[(int)KnownColor.HotPink] = unchecked((int)0xFFFF69B4);
-            values[(int)KnownColor.IndianRed] = unchecked((int)0xFFCD5C5C);
-            values[(int)KnownColor.Indigo] = unchecked((int)0xFF4B0082);
-            values[(int)KnownColor.Ivory] = unchecked((int)0xFFFFFFF0);
-            values[(int)KnownColor.Khaki] = unchecked((int)0xFFF0E68C);
-            values[(int)KnownColor.Lavender] = unchecked((int)0xFFE6E6FA);
-            values[(int)KnownColor.LavenderBlush] = unchecked((int)0xFFFFF0F5);
-            values[(int)KnownColor.LawnGreen] = unchecked((int)0xFF7CFC00);
-            values[(int)KnownColor.LemonChiffon] = unchecked((int)0xFFFFFACD);
-            values[(int)KnownColor.LightBlue] = unchecked((int)0xFFADD8E6);
-            values[(int)KnownColor.LightCoral] = unchecked((int)0xFFF08080);
-            values[(int)KnownColor.LightCyan] = unchecked((int)0xFFE0FFFF);
-            values[(int)KnownColor.LightGoldenrodYellow] = unchecked((int)0xFFFAFAD2);
-            values[(int)KnownColor.LightGray] = unchecked((int)0xFFD3D3D3);
-            values[(int)KnownColor.LightGreen] = unchecked((int)0xFF90EE90);
-            values[(int)KnownColor.LightPink] = unchecked((int)0xFFFFB6C1);
-            values[(int)KnownColor.LightSalmon] = unchecked((int)0xFFFFA07A);
-            values[(int)KnownColor.LightSeaGreen] = unchecked((int)0xFF20B2AA);
-            values[(int)KnownColor.LightSkyBlue] = unchecked((int)0xFF87CEFA);
-            values[(int)KnownColor.LightSlateGray] = unchecked((int)0xFF778899);
-            values[(int)KnownColor.LightSteelBlue] = unchecked((int)0xFFB0C4DE);
-            values[(int)KnownColor.LightYellow] = unchecked((int)0xFFFFFFE0);
-            values[(int)KnownColor.Lime] = unchecked((int)0xFF00FF00);
-            values[(int)KnownColor.LimeGreen] = unchecked((int)0xFF32CD32);
-            values[(int)KnownColor.Linen] = unchecked((int)0xFFFAF0E6);
-            values[(int)KnownColor.Magenta] = unchecked((int)0xFFFF00FF);
-            values[(int)KnownColor.Maroon] = unchecked((int)0xFF800000);
-            values[(int)KnownColor.MediumAquamarine] = unchecked((int)0xFF66CDAA);
-            values[(int)KnownColor.MediumBlue] = unchecked((int)0xFF0000CD);
-            values[(int)KnownColor.MediumOrchid] = unchecked((int)0xFFBA55D3);
-            values[(int)KnownColor.MediumPurple] = unchecked((int)0xFF9370DB);
-            values[(int)KnownColor.MediumSeaGreen] = unchecked((int)0xFF3CB371);
-            values[(int)KnownColor.MediumSlateBlue] = unchecked((int)0xFF7B68EE);
-            values[(int)KnownColor.MediumSpringGreen] = unchecked((int)0xFF00FA9A);
-            values[(int)KnownColor.MediumTurquoise] = unchecked((int)0xFF48D1CC);
-            values[(int)KnownColor.MediumVioletRed] = unchecked((int)0xFFC71585);
-            values[(int)KnownColor.MidnightBlue] = unchecked((int)0xFF191970);
-            values[(int)KnownColor.MintCream] = unchecked((int)0xFFF5FFFA);
-            values[(int)KnownColor.MistyRose] = unchecked((int)0xFFFFE4E1);
-            values[(int)KnownColor.Moccasin] = unchecked((int)0xFFFFE4B5);
-            values[(int)KnownColor.NavajoWhite] = unchecked((int)0xFFFFDEAD);
-            values[(int)KnownColor.Navy] = unchecked((int)0xFF000080);
-            values[(int)KnownColor.OldLace] = unchecked((int)0xFFFDF5E6);
-            values[(int)KnownColor.Olive] = unchecked((int)0xFF808000);
-            values[(int)KnownColor.OliveDrab] = unchecked((int)0xFF6B8E23);
-            values[(int)KnownColor.Orange] = unchecked((int)0xFFFFA500);
-            values[(int)KnownColor.OrangeRed] = unchecked((int)0xFFFF4500);
-            values[(int)KnownColor.Orchid] = unchecked((int)0xFFDA70D6);
-            values[(int)KnownColor.PaleGoldenrod] = unchecked((int)0xFFEEE8AA);
-            values[(int)KnownColor.PaleGreen] = unchecked((int)0xFF98FB98);
-            values[(int)KnownColor.PaleTurquoise] = unchecked((int)0xFFAFEEEE);
-            values[(int)KnownColor.PaleVioletRed] = unchecked((int)0xFFDB7093);
-            values[(int)KnownColor.PapayaWhip] = unchecked((int)0xFFFFEFD5);
-            values[(int)KnownColor.PeachPuff] = unchecked((int)0xFFFFDAB9);
-            values[(int)KnownColor.Peru] = unchecked((int)0xFFCD853F);
-            values[(int)KnownColor.Pink] = unchecked((int)0xFFFFC0CB);
-            values[(int)KnownColor.Plum] = unchecked((int)0xFFDDA0DD);
-            values[(int)KnownColor.PowderBlue] = unchecked((int)0xFFB0E0E6);
-            values[(int)KnownColor.Purple] = unchecked((int)0xFF800080);
-            values[(int)KnownColor.Red] = unchecked((int)0xFFFF0000);
-            values[(int)KnownColor.RosyBrown] = unchecked((int)0xFFBC8F8F);
-            values[(int)KnownColor.RoyalBlue] = unchecked((int)0xFF4169E1);
-            values[(int)KnownColor.SaddleBrown] = unchecked((int)0xFF8B4513);
-            values[(int)KnownColor.Salmon] = unchecked((int)0xFFFA8072);
-            values[(int)KnownColor.SandyBrown] = unchecked((int)0xFFF4A460);
-            values[(int)KnownColor.SeaGreen] = unchecked((int)0xFF2E8B57);
-            values[(int)KnownColor.SeaShell] = unchecked((int)0xFFFFF5EE);
-            values[(int)KnownColor.Sienna] = unchecked((int)0xFFA0522D);
-            values[(int)KnownColor.Silver] = unchecked((int)0xFFC0C0C0);
-            values[(int)KnownColor.SkyBlue] = unchecked((int)0xFF87CEEB);
-            values[(int)KnownColor.SlateBlue] = unchecked((int)0xFF6A5ACD);
-            values[(int)KnownColor.SlateGray] = unchecked((int)0xFF708090);
-            values[(int)KnownColor.Snow] = unchecked((int)0xFFFFFAFA);
-            values[(int)KnownColor.SpringGreen] = unchecked((int)0xFF00FF7F);
-            values[(int)KnownColor.SteelBlue] = unchecked((int)0xFF4682B4);
-            values[(int)KnownColor.Tan] = unchecked((int)0xFFD2B48C);
-            values[(int)KnownColor.Teal] = unchecked((int)0xFF008080);
-            values[(int)KnownColor.Thistle] = unchecked((int)0xFFD8BFD8);
-            values[(int)KnownColor.Tomato] = unchecked((int)0xFFFF6347);
-            values[(int)KnownColor.Turquoise] = unchecked((int)0xFF40E0D0);
-            values[(int)KnownColor.Violet] = unchecked((int)0xFFEE82EE);
-            values[(int)KnownColor.Wheat] = unchecked((int)0xFFF5DEB3);
-            values[(int)KnownColor.White] = unchecked((int)0xFFFFFFFF);
-            values[(int)KnownColor.WhiteSmoke] = unchecked((int)0xFFF5F5F5);
-            values[(int)KnownColor.Yellow] = unchecked((int)0xFFFFFF00);
-            values[(int)KnownColor.YellowGreen] = unchecked((int)0xFF9ACD32);
-            s_colorTable = values;
-        }
+            // The appended group of SystemColors (i.e. not sequential with WindowText above)
+            (byte)Interop.User32.Win32SystemColors.ButtonFace,
+            (byte)Interop.User32.Win32SystemColors.ButtonHighlight,
+            (byte)Interop.User32.Win32SystemColors.ButtonShadow,
+            (byte)Interop.User32.Win32SystemColors.GradientActiveCaption,
+            (byte)Interop.User32.Win32SystemColors.GradientInactiveCaption,
+            (byte)Interop.User32.Win32SystemColors.MenuBar,
+            (byte)Interop.User32.Win32SystemColors.MenuHighlight
+        };
 
-        private static void EnsureColorNameTable()
-        {
-            // no need to lock... worse case is a double create of the table...
-            //
-            if (s_colorNameTable == null)
-            {
-                InitColorNameTable();
-            }
-        }
+        public static uint GetSystemColorArgb(KnownColor color)
+            => ColorTranslator.COLORREFToARGB(Interop.User32.GetSysColor(GetSystemColorId(color)));
 
-        private static void InitColorNameTable()
+        private static int GetSystemColorId(KnownColor color)
         {
-            string[] values = new string[((int)KnownColor.MenuHighlight) + 1];
-
-            // just consts...
-            //
-            values[(int)KnownColor.ActiveBorder] = "ActiveBorder";
-            values[(int)KnownColor.ActiveCaption] = "ActiveCaption";
-            values[(int)KnownColor.ActiveCaptionText] = "ActiveCaptionText";
-            values[(int)KnownColor.AppWorkspace] = "AppWorkspace";
-            values[(int)KnownColor.ButtonFace] = "ButtonFace";
-            values[(int)KnownColor.ButtonHighlight] = "ButtonHighlight";
-            values[(int)KnownColor.ButtonShadow] = "ButtonShadow";
-            values[(int)KnownColor.Control] = "Control";
-            values[(int)KnownColor.ControlDark] = "ControlDark";
-            values[(int)KnownColor.ControlDarkDark] = "ControlDarkDark";
-            values[(int)KnownColor.ControlLight] = "ControlLight";
-            values[(int)KnownColor.ControlLightLight] = "ControlLightLight";
-            values[(int)KnownColor.ControlText] = "ControlText";
-            values[(int)KnownColor.Desktop] = "Desktop";
-            values[(int)KnownColor.GradientActiveCaption] = "GradientActiveCaption";
-            values[(int)KnownColor.GradientInactiveCaption] = "GradientInactiveCaption";
-            values[(int)KnownColor.GrayText] = "GrayText";
-            values[(int)KnownColor.Highlight] = "Highlight";
-            values[(int)KnownColor.HighlightText] = "HighlightText";
-            values[(int)KnownColor.HotTrack] = "HotTrack";
-            values[(int)KnownColor.InactiveBorder] = "InactiveBorder";
-            values[(int)KnownColor.InactiveCaption] = "InactiveCaption";
-            values[(int)KnownColor.InactiveCaptionText] = "InactiveCaptionText";
-            values[(int)KnownColor.Info] = "Info";
-            values[(int)KnownColor.InfoText] = "InfoText";
-            values[(int)KnownColor.Menu] = "Menu";
-            values[(int)KnownColor.MenuBar] = "MenuBar";
-            values[(int)KnownColor.MenuHighlight] = "MenuHighlight";
-            values[(int)KnownColor.MenuText] = "MenuText";
-            values[(int)KnownColor.ScrollBar] = "ScrollBar";
-            values[(int)KnownColor.Window] = "Window";
-            values[(int)KnownColor.WindowFrame] = "WindowFrame";
-            values[(int)KnownColor.WindowText] = "WindowText";
+            Debug.Assert(Color.IsKnownColorSystem(color));
 
-            values[(int)KnownColor.Transparent] = "Transparent";
-            values[(int)KnownColor.AliceBlue] = "AliceBlue";
-            values[(int)KnownColor.AntiqueWhite] = "AntiqueWhite";
-            values[(int)KnownColor.Aqua] = "Aqua";
-            values[(int)KnownColor.Aquamarine] = "Aquamarine";
-            values[(int)KnownColor.Azure] = "Azure";
-            values[(int)KnownColor.Beige] = "Beige";
-            values[(int)KnownColor.Bisque] = "Bisque";
-            values[(int)KnownColor.Black] = "Black";
-            values[(int)KnownColor.BlanchedAlmond] = "BlanchedAlmond";
-            values[(int)KnownColor.Blue] = "Blue";
-            values[(int)KnownColor.BlueViolet] = "BlueViolet";
-            values[(int)KnownColor.Brown] = "Brown";
-            values[(int)KnownColor.BurlyWood] = "BurlyWood";
-            values[(int)KnownColor.CadetBlue] = "CadetBlue";
-            values[(int)KnownColor.Chartreuse] = "Chartreuse";
-            values[(int)KnownColor.Chocolate] = "Chocolate";
-            values[(int)KnownColor.Coral] = "Coral";
-            values[(int)KnownColor.CornflowerBlue] = "CornflowerBlue";
-            values[(int)KnownColor.Cornsilk] = "Cornsilk";
-            values[(int)KnownColor.Crimson] = "Crimson";
-            values[(int)KnownColor.Cyan] = "Cyan";
-            values[(int)KnownColor.DarkBlue] = "DarkBlue";
-            values[(int)KnownColor.DarkCyan] = "DarkCyan";
-            values[(int)KnownColor.DarkGoldenrod] = "DarkGoldenrod";
-            values[(int)KnownColor.DarkGray] = "DarkGray";
-            values[(int)KnownColor.DarkGreen] = "DarkGreen";
-            values[(int)KnownColor.DarkKhaki] = "DarkKhaki";
-            values[(int)KnownColor.DarkMagenta] = "DarkMagenta";
-            values[(int)KnownColor.DarkOliveGreen] = "DarkOliveGreen";
-            values[(int)KnownColor.DarkOrange] = "DarkOrange";
-            values[(int)KnownColor.DarkOrchid] = "DarkOrchid";
-            values[(int)KnownColor.DarkRed] = "DarkRed";
-            values[(int)KnownColor.DarkSalmon] = "DarkSalmon";
-            values[(int)KnownColor.DarkSeaGreen] = "DarkSeaGreen";
-            values[(int)KnownColor.DarkSlateBlue] = "DarkSlateBlue";
-            values[(int)KnownColor.DarkSlateGray] = "DarkSlateGray";
-            values[(int)KnownColor.DarkTurquoise] = "DarkTurquoise";
-            values[(int)KnownColor.DarkViolet] = "DarkViolet";
-            values[(int)KnownColor.DeepPink] = "DeepPink";
-            values[(int)KnownColor.DeepSkyBlue] = "DeepSkyBlue";
-            values[(int)KnownColor.DimGray] = "DimGray";
-            values[(int)KnownColor.DodgerBlue] = "DodgerBlue";
-            values[(int)KnownColor.Firebrick] = "Firebrick";
-            values[(int)KnownColor.FloralWhite] = "FloralWhite";
-            values[(int)KnownColor.ForestGreen] = "ForestGreen";
-            values[(int)KnownColor.Fuchsia] = "Fuchsia";
-            values[(int)KnownColor.Gainsboro] = "Gainsboro";
-            values[(int)KnownColor.GhostWhite] = "GhostWhite";
-            values[(int)KnownColor.Gold] = "Gold";
-            values[(int)KnownColor.Goldenrod] = "Goldenrod";
-            values[(int)KnownColor.Gray] = "Gray";
-            values[(int)KnownColor.Green] = "Green";
-            values[(int)KnownColor.GreenYellow] = "GreenYellow";
-            values[(int)KnownColor.Honeydew] = "Honeydew";
-            values[(int)KnownColor.HotPink] = "HotPink";
-            values[(int)KnownColor.IndianRed] = "IndianRed";
-            values[(int)KnownColor.Indigo] = "Indigo";
-            values[(int)KnownColor.Ivory] = "Ivory";
-            values[(int)KnownColor.Khaki] = "Khaki";
-            values[(int)KnownColor.Lavender] = "Lavender";
-            values[(int)KnownColor.LavenderBlush] = "LavenderBlush";
-            values[(int)KnownColor.LawnGreen] = "LawnGreen";
-            values[(int)KnownColor.LemonChiffon] = "LemonChiffon";
-            values[(int)KnownColor.LightBlue] = "LightBlue";
-            values[(int)KnownColor.LightCoral] = "LightCoral";
-            values[(int)KnownColor.LightCyan] = "LightCyan";
-            values[(int)KnownColor.LightGoldenrodYellow] = "LightGoldenrodYellow";
-            values[(int)KnownColor.LightGray] = "LightGray";
-            values[(int)KnownColor.LightGreen] = "LightGreen";
-            values[(int)KnownColor.LightPink] = "LightPink";
-            values[(int)KnownColor.LightSalmon] = "LightSalmon";
-            values[(int)KnownColor.LightSeaGreen] = "LightSeaGreen";
-            values[(int)KnownColor.LightSkyBlue] = "LightSkyBlue";
-            values[(int)KnownColor.LightSlateGray] = "LightSlateGray";
-            values[(int)KnownColor.LightSteelBlue] = "LightSteelBlue";
-            values[(int)KnownColor.LightYellow] = "LightYellow";
-            values[(int)KnownColor.Lime] = "Lime";
-            values[(int)KnownColor.LimeGreen] = "LimeGreen";
-            values[(int)KnownColor.Linen] = "Linen";
-            values[(int)KnownColor.Magenta] = "Magenta";
-            values[(int)KnownColor.Maroon] = "Maroon";
-            values[(int)KnownColor.MediumAquamarine] = "MediumAquamarine";
-            values[(int)KnownColor.MediumBlue] = "MediumBlue";
-            values[(int)KnownColor.MediumOrchid] = "MediumOrchid";
-            values[(int)KnownColor.MediumPurple] = "MediumPurple";
-            values[(int)KnownColor.MediumSeaGreen] = "MediumSeaGreen";
-            values[(int)KnownColor.MediumSlateBlue] = "MediumSlateBlue";
-            values[(int)KnownColor.MediumSpringGreen] = "MediumSpringGreen";
-            values[(int)KnownColor.MediumTurquoise] = "MediumTurquoise";
-            values[(int)KnownColor.MediumVioletRed] = "MediumVioletRed";
-            values[(int)KnownColor.MidnightBlue] = "MidnightBlue";
-            values[(int)KnownColor.MintCream] = "MintCream";
-            values[(int)KnownColor.MistyRose] = "MistyRose";
-            values[(int)KnownColor.Moccasin] = "Moccasin";
-            values[(int)KnownColor.NavajoWhite] = "NavajoWhite";
-            values[(int)KnownColor.Navy] = "Navy";
-            values[(int)KnownColor.OldLace] = "OldLace";
-            values[(int)KnownColor.Olive] = "Olive";
-            values[(int)KnownColor.OliveDrab] = "OliveDrab";
-            values[(int)KnownColor.Orange] = "Orange";
-            values[(int)KnownColor.OrangeRed] = "OrangeRed";
-            values[(int)KnownColor.Orchid] = "Orchid";
-            values[(int)KnownColor.PaleGoldenrod] = "PaleGoldenrod";
-            values[(int)KnownColor.PaleGreen] = "PaleGreen";
-            values[(int)KnownColor.PaleTurquoise] = "PaleTurquoise";
-            values[(int)KnownColor.PaleVioletRed] = "PaleVioletRed";
-            values[(int)KnownColor.PapayaWhip] = "PapayaWhip";
-            values[(int)KnownColor.PeachPuff] = "PeachPuff";
-            values[(int)KnownColor.Peru] = "Peru";
-            values[(int)KnownColor.Pink] = "Pink";
-            values[(int)KnownColor.Plum] = "Plum";
-            values[(int)KnownColor.PowderBlue] = "PowderBlue";
-            values[(int)KnownColor.Purple] = "Purple";
-            values[(int)KnownColor.Red] = "Red";
-            values[(int)KnownColor.RosyBrown] = "RosyBrown";
-            values[(int)KnownColor.RoyalBlue] = "RoyalBlue";
-            values[(int)KnownColor.SaddleBrown] = "SaddleBrown";
-            values[(int)KnownColor.Salmon] = "Salmon";
-            values[(int)KnownColor.SandyBrown] = "SandyBrown";
-            values[(int)KnownColor.SeaGreen] = "SeaGreen";
-            values[(int)KnownColor.SeaShell] = "SeaShell";
-            values[(int)KnownColor.Sienna] = "Sienna";
-            values[(int)KnownColor.Silver] = "Silver";
-            values[(int)KnownColor.SkyBlue] = "SkyBlue";
-            values[(int)KnownColor.SlateBlue] = "SlateBlue";
-            values[(int)KnownColor.SlateGray] = "SlateGray";
-            values[(int)KnownColor.Snow] = "Snow";
-            values[(int)KnownColor.SpringGreen] = "SpringGreen";
-            values[(int)KnownColor.SteelBlue] = "SteelBlue";
-            values[(int)KnownColor.Tan] = "Tan";
-            values[(int)KnownColor.Teal] = "Teal";
-            values[(int)KnownColor.Thistle] = "Thistle";
-            values[(int)KnownColor.Tomato] = "Tomato";
-            values[(int)KnownColor.Turquoise] = "Turquoise";
-            values[(int)KnownColor.Violet] = "Violet";
-            values[(int)KnownColor.Wheat] = "Wheat";
-            values[(int)KnownColor.White] = "White";
-            values[(int)KnownColor.WhiteSmoke] = "WhiteSmoke";
-            values[(int)KnownColor.Yellow] = "Yellow";
-            values[(int)KnownColor.YellowGreen] = "YellowGreen";
-            s_colorNameTable = values;
+            return color < KnownColor.Transparent
+                ? SystemColorIdTable[(int)color - (int)KnownColor.ActiveBorder]
+                : SystemColorIdTable[(int)color - (int)KnownColor.ButtonFace + (int)KnownColor.WindowText];
         }
-
-        public static int KnownColorToArgb(KnownColor color)
+#else
+        private static readonly uint[] s_staticSystemColors = new uint[]
         {
-            Debug.Assert(color > 0 && color <= KnownColor.MenuHighlight);
-            EnsureColorTable();
-            return s_colorTable[unchecked((int)color)];
-        }
+            // Hard-coded constants, based on default Windows settings.
+            // (In order of definition in KnownColor enum.)
 
-        public static string KnownColorToName(KnownColor color)
-        {
-            Debug.Assert(color > 0 && color <= KnownColor.MenuHighlight);
-            EnsureColorNameTable();
-            return s_colorNameTable[unchecked((int)color)];
-        }
+            // First contiguous set.
 
-#if FEATURE_WINDOWS_SYSTEM_COLORS
-        private static int SystemColorToArgb(int index)
-        {
-            return FromWin32Value(Interop.User32.GetSysColor(index));
-        }
+            0xFFD4D0C8,     // ActiveBorder
+            0xFF0054E3,     // ActiveCaption
+            0xFFFFFFFF,     // ActiveCaptionText
+            0xFF808080,     // AppWorkspace
+            0xFFECE9D8,     // Control
+            0xFFACA899,     // ControlDark
+            0xFF716F64,     // ControlDarkDark
+            0xFFF1EFE2,     // ControlLight
+            0xFFFFFFFF,     // ControlLightLight
+            0xFF000000,     // ControlText
+            0xFF004E98,     // Desktop
+            0xFFACA899,     // GrayText
+            0xFF316AC5,     // Highlight
+            0xFFFFFFFF,     // HighlightText
+            0xFF000080,     // HotTrack
+            0xFFD4D0C8,     // InactiveBorder
+            0xFF7A96DF,     // InactiveCaption
+            0xFFD8E4F8,     // InactiveCaptionText
+            0xFFFFFFE1,     // Info
+            0xFF000000,     // InfoText
+            0xFFFFFFFF,     // Menu
+            0xFF000000,     // MenuText
+            0xFFD4D0C8,     // ScrollBar
+            0xFFFFFFFF,     // Window
+            0xFF000000,     // WindowFrame
+            0xFF000000,     // WindowText
 
-        private static int Encode(int alpha, int red, int green, int blue)
-        {
-            return red << RedShift | green << GreenShift | blue << BlueShift | alpha << AlphaShift;
-        }
+            // Second contiguous set.
 
-        private static int FromWin32Value(int value)
-        {
-            return Encode(255,
-                          (value >> Win32RedShift) & 0xFF,
-                          (value >> Win32GreenShift) & 0xFF,
-                          (value >> Win32BlueShift) & 0xFF);
-        }
-#endif
+            0xFFF0F0F0,     // ButtonFace
+            0xFFFFFFFF,     // ButtonHighlight
+            0xFFA0A0A0,     // ButtonShadow
+            0xFFB9D1EA,     // GradientActiveCaption
+            0xFFD7E4F2,     // GradientInactiveCaption
+            0xFFF0F0F0,     // MenuBar
+            0xFF3399FF,     // MenuHighlight
+        };
 
-        private static void OnUserPreferenceChanging(object sender, EventArgs args)
+        public static uint GetSystemColorArgb(KnownColor color)
         {
-            Debug.Assert(s_categoryGetter != null);
-            // Access UserPreferenceChangingEventArgs.Category value through cached MethodInfo.
-            if (s_colorTable != null && s_categoryGetter != null && (int)s_categoryGetter.Invoke(args, Array.Empty<object>()) == 2) // UserPreferenceCategory.Color = 2
-            {
-                UpdateSystemColors(s_colorTable);
-            }
-        }
+            Debug.Assert(Color.IsKnownColorSystem(color));
 
-        private static void UpdateSystemColors(int[] colorTable)
-        {
-#if FEATURE_WINDOWS_SYSTEM_COLORS
-            colorTable[(int)KnownColor.ActiveBorder] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ActiveBorder);
-            colorTable[(int)KnownColor.ActiveCaption] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ActiveCaption);
-            colorTable[(int)KnownColor.ActiveCaptionText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ActiveCaptionText);
-            colorTable[(int)KnownColor.AppWorkspace] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.AppWorkspace);
-            colorTable[(int)KnownColor.ButtonFace] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ButtonFace);
-            colorTable[(int)KnownColor.ButtonHighlight] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ButtonHighlight);
-            colorTable[(int)KnownColor.ButtonShadow] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ButtonShadow);
-            colorTable[(int)KnownColor.Control] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.Control);
-            colorTable[(int)KnownColor.ControlDark] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ControlDark);
-            colorTable[(int)KnownColor.ControlDarkDark] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ControlDarkDark);
-            colorTable[(int)KnownColor.ControlLight] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ControlLight);
-            colorTable[(int)KnownColor.ControlLightLight] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ControlLightLight);
-            colorTable[(int)KnownColor.ControlText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ControlText);
-            colorTable[(int)KnownColor.Desktop] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.Desktop);
-            colorTable[(int)KnownColor.GradientActiveCaption] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.GradientActiveCaption);
-            colorTable[(int)KnownColor.GradientInactiveCaption] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.GradientInactiveCaption);
-            colorTable[(int)KnownColor.GrayText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.GrayText);
-            colorTable[(int)KnownColor.Highlight] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.Highlight);
-            colorTable[(int)KnownColor.HighlightText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.HighlightText);
-            colorTable[(int)KnownColor.HotTrack] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.HotTrack);
-            colorTable[(int)KnownColor.InactiveBorder] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.InactiveBorder);
-            colorTable[(int)KnownColor.InactiveCaption] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.InactiveCaption);
-            colorTable[(int)KnownColor.InactiveCaptionText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.InactiveCaptionText);
-            colorTable[(int)KnownColor.Info] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.Info);
-            colorTable[(int)KnownColor.InfoText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.InfoText);
-            colorTable[(int)KnownColor.Menu] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.Menu);
-            colorTable[(int)KnownColor.MenuBar] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.MenuBar);
-            colorTable[(int)KnownColor.MenuHighlight] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.MenuHighlight);
-            colorTable[(int)KnownColor.MenuText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.MenuText);
-            colorTable[(int)KnownColor.ScrollBar] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.ScrollBar);
-            colorTable[(int)KnownColor.Window] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.Window);
-            colorTable[(int)KnownColor.WindowFrame] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.WindowFrame);
-            colorTable[(int)KnownColor.WindowText] = SystemColorToArgb((int)Interop.User32.Win32SystemColors.WindowText);
-#else
-            // Hard-coded constants, based on default Windows settings.
-            colorTable[(int)KnownColor.ActiveBorder] = unchecked((int)0xFFD4D0C8);
-            colorTable[(int)KnownColor.ActiveCaption] = unchecked((int)0xFF0054E3);
-            colorTable[(int)KnownColor.ActiveCaptionText] = unchecked((int)0xFFFFFFFF);
-            colorTable[(int)KnownColor.AppWorkspace] = unchecked((int)0xFF808080);
-            colorTable[(int)KnownColor.ButtonFace] = unchecked((int)0xFFF0F0F0);
-            colorTable[(int)KnownColor.ButtonHighlight] = unchecked((int)0xFFFFFFFF);
-            colorTable[(int)KnownColor.ButtonShadow] = unchecked((int)0xFFA0A0A0);
-            colorTable[(int)KnownColor.Control] = unchecked((int)0xFFECE9D8);
-            colorTable[(int)KnownColor.ControlDark] = unchecked((int)0xFFACA899);
-            colorTable[(int)KnownColor.ControlDarkDark] = unchecked((int)0xFF716F64);
-            colorTable[(int)KnownColor.ControlLight] = unchecked((int)0xFFF1EFE2);
-            colorTable[(int)KnownColor.ControlLightLight] = unchecked((int)0xFFFFFFFF);
-            colorTable[(int)KnownColor.ControlText] = unchecked((int)0xFF000000);
-            colorTable[(int)KnownColor.Desktop] = unchecked((int)0xFF004E98);
-            colorTable[(int)KnownColor.GradientActiveCaption] = unchecked((int)0xFFB9D1EA);
-            colorTable[(int)KnownColor.GradientInactiveCaption] = unchecked((int)0xFFD7E4F2);
-            colorTable[(int)KnownColor.GrayText] = unchecked((int)0xFFACA899);
-            colorTable[(int)KnownColor.Highlight] = unchecked((int)0xFF316AC5);
-            colorTable[(int)KnownColor.HighlightText] = unchecked((int)0xFFFFFFFF);
-            colorTable[(int)KnownColor.HotTrack] = unchecked((int)0xFF000080);
-            colorTable[(int)KnownColor.InactiveBorder] = unchecked((int)0xFFD4D0C8);
-            colorTable[(int)KnownColor.InactiveCaption] = unchecked((int)0xFF7A96DF);
-            colorTable[(int)KnownColor.InactiveCaptionText] = unchecked((int)0xFFD8E4F8);
-            colorTable[(int)KnownColor.Info] = unchecked((int)0xFFFFFFE1);
-            colorTable[(int)KnownColor.InfoText] = unchecked((int)0xFF000000);
-            colorTable[(int)KnownColor.Menu] = unchecked((int)0xFFFFFFFF);
-            colorTable[(int)KnownColor.MenuBar] = unchecked((int)0xFFF0F0F0);
-            colorTable[(int)KnownColor.MenuHighlight] = unchecked((int)0xFF3399FF);
-            colorTable[(int)KnownColor.MenuText] = unchecked((int)0xFF000000);
-            colorTable[(int)KnownColor.ScrollBar] = unchecked((int)0xFFD4D0C8);
-            colorTable[(int)KnownColor.Window] = unchecked((int)0xFFFFFFFF);
-            colorTable[(int)KnownColor.WindowFrame] = unchecked((int)0xFF000000);
-            colorTable[(int)KnownColor.WindowText] = unchecked((int)0xFF000000);
-#endif
+            return color < KnownColor.Transparent
+                ? s_staticSystemColors[(int)color - (int)KnownColor.ActiveBorder]
+                : s_staticSystemColors[(int)color - (int)KnownColor.ButtonFace + (int)KnownColor.WindowText];
         }
+#endif
     }
 }
index ca6ee2d..3583e4f 100644 (file)
@@ -6,47 +6,47 @@ namespace System.Drawing
 {
     public static class SystemColors
     {
-        public static Color ActiveBorder => ColorUtil.FromKnownColor(KnownColor.ActiveBorder);
-        public static Color ActiveCaption => ColorUtil.FromKnownColor(KnownColor.ActiveCaption);
-        public static Color ActiveCaptionText => ColorUtil.FromKnownColor(KnownColor.ActiveCaptionText);
-        public static Color AppWorkspace => ColorUtil.FromKnownColor(KnownColor.AppWorkspace);
-
-        public static Color ButtonFace => ColorUtil.FromKnownColor(KnownColor.ButtonFace);
-        public static Color ButtonHighlight => ColorUtil.FromKnownColor(KnownColor.ButtonHighlight);
-        public static Color ButtonShadow => ColorUtil.FromKnownColor(KnownColor.ButtonShadow);
-
-        public static Color Control => ColorUtil.FromKnownColor(KnownColor.Control);
-        public static Color ControlDark => ColorUtil.FromKnownColor(KnownColor.ControlDark);
-        public static Color ControlDarkDark => ColorUtil.FromKnownColor(KnownColor.ControlDarkDark);
-        public static Color ControlLight => ColorUtil.FromKnownColor(KnownColor.ControlLight);
-        public static Color ControlLightLight => ColorUtil.FromKnownColor(KnownColor.ControlLightLight);
-        public static Color ControlText => ColorUtil.FromKnownColor(KnownColor.ControlText);
-
-        public static Color Desktop => ColorUtil.FromKnownColor(KnownColor.Desktop);
-
-        public static Color GradientActiveCaption => ColorUtil.FromKnownColor(KnownColor.GradientActiveCaption);
-        public static Color GradientInactiveCaption => ColorUtil.FromKnownColor(KnownColor.GradientInactiveCaption);
-        public static Color GrayText => ColorUtil.FromKnownColor(KnownColor.GrayText);
-
-        public static Color Highlight => ColorUtil.FromKnownColor(KnownColor.Highlight);
-        public static Color HighlightText => ColorUtil.FromKnownColor(KnownColor.HighlightText);
-        public static Color HotTrack => ColorUtil.FromKnownColor(KnownColor.HotTrack);
-
-        public static Color InactiveBorder => ColorUtil.FromKnownColor(KnownColor.InactiveBorder);
-        public static Color InactiveCaption => ColorUtil.FromKnownColor(KnownColor.InactiveCaption);
-        public static Color InactiveCaptionText => ColorUtil.FromKnownColor(KnownColor.InactiveCaptionText);
-        public static Color Info => ColorUtil.FromKnownColor(KnownColor.Info);
-        public static Color InfoText => ColorUtil.FromKnownColor(KnownColor.InfoText);
-
-        public static Color Menu => ColorUtil.FromKnownColor(KnownColor.Menu);
-        public static Color MenuBar => ColorUtil.FromKnownColor(KnownColor.MenuBar);
-        public static Color MenuHighlight => ColorUtil.FromKnownColor(KnownColor.MenuHighlight);
-        public static Color MenuText => ColorUtil.FromKnownColor(KnownColor.MenuText);
-
-        public static Color ScrollBar => ColorUtil.FromKnownColor(KnownColor.ScrollBar);
-
-        public static Color Window => ColorUtil.FromKnownColor(KnownColor.Window);
-        public static Color WindowFrame => ColorUtil.FromKnownColor(KnownColor.WindowFrame);
-        public static Color WindowText => ColorUtil.FromKnownColor(KnownColor.WindowText);
+        public static Color ActiveBorder => Color.FromKnownColor(KnownColor.ActiveBorder);
+        public static Color ActiveCaption => Color.FromKnownColor(KnownColor.ActiveCaption);
+        public static Color ActiveCaptionText => Color.FromKnownColor(KnownColor.ActiveCaptionText);
+        public static Color AppWorkspace => Color.FromKnownColor(KnownColor.AppWorkspace);
+
+        public static Color ButtonFace => Color.FromKnownColor(KnownColor.ButtonFace);
+        public static Color ButtonHighlight => Color.FromKnownColor(KnownColor.ButtonHighlight);
+        public static Color ButtonShadow => Color.FromKnownColor(KnownColor.ButtonShadow);
+
+        public static Color Control => Color.FromKnownColor(KnownColor.Control);
+        public static Color ControlDark => Color.FromKnownColor(KnownColor.ControlDark);
+        public static Color ControlDarkDark => Color.FromKnownColor(KnownColor.ControlDarkDark);
+        public static Color ControlLight => Color.FromKnownColor(KnownColor.ControlLight);
+        public static Color ControlLightLight => Color.FromKnownColor(KnownColor.ControlLightLight);
+        public static Color ControlText => Color.FromKnownColor(KnownColor.ControlText);
+
+        public static Color Desktop => Color.FromKnownColor(KnownColor.Desktop);
+
+        public static Color GradientActiveCaption => Color.FromKnownColor(KnownColor.GradientActiveCaption);
+        public static Color GradientInactiveCaption => Color.FromKnownColor(KnownColor.GradientInactiveCaption);
+        public static Color GrayText => Color.FromKnownColor(KnownColor.GrayText);
+
+        public static Color Highlight => Color.FromKnownColor(KnownColor.Highlight);
+        public static Color HighlightText => Color.FromKnownColor(KnownColor.HighlightText);
+        public static Color HotTrack => Color.FromKnownColor(KnownColor.HotTrack);
+
+        public static Color InactiveBorder => Color.FromKnownColor(KnownColor.InactiveBorder);
+        public static Color InactiveCaption => Color.FromKnownColor(KnownColor.InactiveCaption);
+        public static Color InactiveCaptionText => Color.FromKnownColor(KnownColor.InactiveCaptionText);
+        public static Color Info => Color.FromKnownColor(KnownColor.Info);
+        public static Color InfoText => Color.FromKnownColor(KnownColor.InfoText);
+
+        public static Color Menu => Color.FromKnownColor(KnownColor.Menu);
+        public static Color MenuBar => Color.FromKnownColor(KnownColor.MenuBar);
+        public static Color MenuHighlight => Color.FromKnownColor(KnownColor.MenuHighlight);
+        public static Color MenuText => Color.FromKnownColor(KnownColor.MenuText);
+
+        public static Color ScrollBar => Color.FromKnownColor(KnownColor.ScrollBar);
+
+        public static Color Window => Color.FromKnownColor(KnownColor.Window);
+        public static Color WindowFrame => Color.FromKnownColor(KnownColor.WindowFrame);
+        public static Color WindowText => Color.FromKnownColor(KnownColor.WindowText);
     }
 }
index ca1a267..4d5da30 100644 (file)
     <Compile Include="System\Drawing\Imaging\ImageCodecInfo.cs" />
     <Compile Include="System\Drawing\Imaging\ImageCodecInfoPrivate.cs" />
     <Compile Include="System\Drawing\Imaging\MetafileFrameUnit.cs" />
-    <Compile Condition="'$(TargetGroup)' == 'netcoreapp2.0'" Include="$(CommonPath)\System\Drawing\ColorConverterCommon.cs">
-      <Link>System\Drawing\ColorConverterCommon.cs</Link>
-    </Compile>
-    <Compile Condition="'$(TargetGroup)' == 'netcoreapp2.0'" Include="$(CommonPath)\System\Drawing\ColorTable.cs">
-      <Link>System\Drawing\ColorTable.cs</Link>
-    </Compile>
-    <Compile Condition="'$(TargetGroup)' == 'netcoreapp2.0'" Include="$(CommonPath)\System\Drawing\ColorTranslator.cs">
-      <Link>System\Drawing\ColorTranslator.cs</Link>
-    </Compile>
-    <Compile Condition="'$(TargetGroup)' == 'netcoreapp2.0'" Include="$(CommonPath)\System\Drawing\ColorUtil.netcoreapp20.cs">
-      <Link>System\Drawing\ColorUtil.netcoreapp20.cs</Link>
-    </Compile>
-    <Compile Condition="'$(TargetGroup)' != 'netcoreapp2.0'" Include="$(CommonPath)\System\Drawing\ColorUtil.netcoreapp21.cs">
-      <Link>System\Drawing\ColorUtil.netcoreapp21.cs</Link>
-    </Compile>
-    <Compile Condition="'$(TargetGroup)' == 'netcoreapp2.0'" Include="$(CommonPath)\System\Drawing\KnownColorTable.cs">
-      <Link>System\Drawing\KnownColorTable.cs</Link>
-    </Compile>
     <EmbeddedResource Include="Resources\System\Drawing\DefaultComponent.bmp">
       <LogicalName>System.Drawing.DefaultComponent.bmp</LogicalName>
     </EmbeddedResource>
     <Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.GetProcAddress.cs">
       <Link>Common\Interop\Windows\Kernel32\Interop.GetProcAddress.cs</Link>
     </Compile>
-    <Compile Include="$(CommonPath)\Interop\Windows\User32\Interop.GetSysColor.cs">
-      <Link>Common\Interop\Windows\User32\Interop.GetSysColor.cs</Link>
-    </Compile>
-    <Compile Include="$(CommonPath)\Interop\Windows\User32\Interop.Win32SystemColors.cs">
-      <Link>Common\Interop\Windows\User32\Interop.Win32SystemColors.cs</Link>
-    </Compile>
     <Compile Include="$(CommonPath)\CoreLib\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs">
       <Link>Common\CoreLib\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs</Link>
     </Compile>
index 0ac7ba5..fe332cb 100644 (file)
@@ -66,7 +66,7 @@ namespace System.Drawing
             SetNativePen(pen);
 
 #if FEATURE_SYSTEM_EVENTS
-            if (ColorUtil.IsSystemColor(_color))
+            if (_color.IsSystemColor)
             {
                 SystemColorTracker.Add(this);
             }
@@ -590,7 +590,7 @@ namespace System.Drawing
 #if FEATURE_SYSTEM_EVENTS
                     // NOTE: We never remove pens from the active list, so if someone is
                     // changing their pen colors a lot, this could be a problem.
-                    if (ColorUtil.IsSystemColor(value) && !ColorUtil.IsSystemColor(oldColor))
+                    if (value.IsSystemColor && !oldColor.IsSystemColor)
                     {
                         SystemColorTracker.Add(this);
                     }
index 1903c13..891d0de 100644 (file)
@@ -32,7 +32,7 @@ namespace System.Drawing
             SetNativeBrushInternal(nativeBrush);
 
 #if FEATURE_SYSTEM_EVENTS
-            if (ColorUtil.IsSystemColor(_color))
+            if (_color.IsSystemColor)
             {
                 SystemColorTracker.Add(this);
             }
@@ -106,7 +106,7 @@ namespace System.Drawing
 #if FEATURE_SYSTEM_EVENTS
                     // NOTE: We never remove brushes from the active list, so if someone is
                     // changing their brush colors a lot, this could be a problem.
-                    if (ColorUtil.IsSystemColor(value) && !ColorUtil.IsSystemColor(oldColor))
+                    if (value.IsSystemColor && !oldColor.IsSystemColor)
                     {
                         SystemColorTracker.Add(this);
                     }
index 0bb1c26..8c0b87f 100644 (file)
@@ -56,7 +56,7 @@ namespace System.Drawing
 
         public static Brush FromSystemColor(Color c)
         {
-            if (!ColorUtil.IsSystemColor(c))
+            if (!c.IsSystemColor)
             {
                 throw new ArgumentException(SR.Format(SR.ColorNotSystemColor, c.ToString()));
             }
index 84615a6..aa91d64 100644 (file)
@@ -57,7 +57,7 @@ namespace System.Drawing
 
         public static Pen FromSystemColor(Color c)
         {
-            if (!ColorUtil.IsSystemColor(c))
+            if (!c.IsSystemColor)
             {
                 throw new ArgumentException(SR.Format(SR.ColorNotSystemColor, c.ToString()));
             }
index a2fd51e..fecccd3 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <OutputType>Library</OutputType>
     <RootNamespace>System.Drawing</RootNamespace>
     <Reference Include="System.Runtime.Extensions" />
     <Reference Include="System.Runtime.InteropServices" />
     <Reference Include="System.ComponentModel.Primitives" />
+    <Reference Include="Microsoft.Win32.SystemEvents" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="System\Drawing\KnownColorNames.cs" />
     <Compile Include="System\Drawing\Point.cs" />
     <Compile Include="System\Drawing\PointF.cs" />
     <Compile Include="System\Drawing\Rectangle.cs" />
@@ -34,9 +36,6 @@
     <Compile Include="$(CommonPath)\System\Drawing\ColorTranslator.cs">
       <Link>System\Drawing\ColorTranslator.cs</Link>
     </Compile>
-    <Compile Include="$(CommonPath)\System\Drawing\ColorUtil.netcoreapp21.cs">
-      <Link>System\Drawing\ColorUtil.netcoreapp21.cs</Link>
-    </Compile>
     <Compile Include="$(CommonPath)\System\Drawing\KnownColor.cs">
       <Link>System\Drawing\KnownColor.cs</Link>
     </Compile>
index 2b0554b..6793bc5 100644 (file)
@@ -3,7 +3,6 @@
 // See the LICENSE file in the project root for more information.
 
 using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
 using System.Numerics.Hashing;
 using System.Runtime.CompilerServices;
 
@@ -11,7 +10,7 @@ namespace System.Drawing
 {
     [DebuggerDisplay("{NameAndARGBValue}")]
     [Serializable]
-    [System.Runtime.CompilerServices.TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+    [TypeForwardedFrom("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
     public readonly struct Color : IEquatable<Color>
     {
         public static readonly Color Empty = new Color();
@@ -314,36 +313,30 @@ namespace System.Drawing
         private const short StateNameValid = 0x0008;
         private const long NotDefinedValue = 0;
 
-        /**
-         * Shift count and bit mask for A, R, G, B components in ARGB mode!
-         */
-        private const int ARGBAlphaShift = 24;
-        private const int ARGBRedShift = 16;
-        private const int ARGBGreenShift = 8;
-        private const int ARGBBlueShift = 0;
-        private const uint ARGBAlphaMask = 0xFFu << ARGBAlphaShift;
-        private const uint ARGBRedMask = 0xFFu << ARGBRedShift;
-        private const uint ARGBGreenMask = 0xFFu << ARGBGreenShift;
-        private const uint ARGBBlueMask = 0xFFu << ARGBBlueShift;
-
-        // user supplied name of color. Will not be filled in if
+        // Shift counts and bit masks for A, R, G, B components in ARGB mode
+
+        internal const int ARGBAlphaShift = 24;
+        internal const int ARGBRedShift = 16;
+        internal const int ARGBGreenShift = 8;
+        internal const int ARGBBlueShift = 0;
+        internal const uint ARGBAlphaMask = 0xFFu << ARGBAlphaShift;
+        internal const uint ARGBRedMask = 0xFFu << ARGBRedShift;
+        internal const uint ARGBGreenMask = 0xFFu << ARGBGreenShift;
+        internal const uint ARGBBlueMask = 0xFFu << ARGBBlueShift;
+
+        // User supplied name of color. Will not be filled in if
         // we map to a "knowncolor"
-        //
         private readonly string name; // Do not rename (binary serialization)
 
-        // will contain standard 32bit sRGB (ARGB)
-        //
+        // Standard 32bit sRGB (ARGB)
         private readonly long value; // Do not rename (binary serialization)
 
-        // ignored, unless "state" says it is valid
-        //
+        // Ignored, unless "state" says it is valid
         private readonly short knownColor; // Do not rename (binary serialization)
 
-        // implementation specific information
-        //
+        // State flags.
         private readonly short state; // Do not rename (binary serialization)
 
-
         internal Color(KnownColor knownColor)
         {
             value = 0;
@@ -374,13 +367,15 @@ namespace System.Drawing
 
         public bool IsNamedColor => ((state & StateNameValid) != 0) || IsKnownColor;
 
-        public bool IsSystemColor => IsKnownColor && (((KnownColor)knownColor <= KnownColor.WindowText) || ((KnownColor)knownColor > KnownColor.YellowGreen));
+        public bool IsSystemColor => IsKnownColor && IsKnownColorSystem((KnownColor)knownColor);
+
+        internal static bool IsKnownColorSystem(KnownColor knownColor)
+            => (knownColor <= KnownColor.WindowText) || (knownColor > KnownColor.YellowGreen);
+
+        // Used for the [DebuggerDisplay]. Inlining in the attribute is possible, but
+        // against best practices as the current project language parses the string with
+        // language specific heuristics.
 
-        // Not localized because it's only used for the DebuggerDisplayAttribute, and the values are
-        // programmatic items.
-        // Also, don't inline into the attribute for performance reasons.  This way means the debugger
-        // does 1 func-eval instead of 5.
-        [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters")]
         private string NameAndARGBValue => $"{{Name={Name}, ARGB=({A}, {R}, {G}, {B})}}";
 
         public string Name
@@ -394,7 +389,7 @@ namespace System.Drawing
 
                 if (IsKnownColor)
                 {
-                    string tablename = KnownColorTable.KnownColorToName((KnownColor)knownColor);
+                    string tablename = KnownColorNames.KnownColorToName((KnownColor)knownColor);
                     Debug.Assert(tablename != null, $"Could not find known color '{(KnownColor)knownColor}' in the KnownColorTable");
 
                     return tablename;
@@ -415,6 +410,7 @@ namespace System.Drawing
                     return value;
                 }
 
+                // This is the only place we have system colors value exposed
                 if (IsKnownColor)
                 {
                     return KnownColorTable.KnownColorToArgb((KnownColor)knownColor);
diff --git a/src/libraries/System.Drawing.Primitives/src/System/Drawing/KnownColorNames.cs b/src/libraries/System.Drawing.Primitives/src/System/Drawing/KnownColorNames.cs
new file mode 100644 (file)
index 0000000..0cd24ed
--- /dev/null
@@ -0,0 +1,195 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+
+namespace System.Drawing
+{
+    internal static class KnownColorNames
+    {
+        private static readonly string[] s_colorNameTable = new string[]
+        {
+            "ActiveBorder",
+            "ActiveCaption",
+            "ActiveCaptionText",
+            "AppWorkspace",
+            "Control",
+            "ControlDark",
+            "ControlDarkDark",
+            "ControlLight",
+            "ControlLightLight",
+            "ControlText",
+            "Desktop",
+            "GrayText",
+            "Highlight",
+            "HighlightText",
+            "HotTrack",
+            "InactiveBorder",
+            "InactiveCaption",
+            "InactiveCaptionText",
+            "Info",
+            "InfoText",
+            "Menu",
+            "MenuText",
+            "ScrollBar",
+            "Window",
+            "WindowFrame",
+            "WindowText",
+            "Transparent",
+            "AliceBlue",
+            "AntiqueWhite",
+            "Aqua",
+            "Aquamarine",
+            "Azure",
+            "Beige",
+            "Bisque",
+            "Black",
+            "BlanchedAlmond",
+            "Blue",
+            "BlueViolet",
+            "Brown",
+            "BurlyWood",
+            "CadetBlue",
+            "Chartreuse",
+            "Chocolate",
+            "Coral",
+            "CornflowerBlue",
+            "Cornsilk",
+            "Crimson",
+            "Cyan",
+            "DarkBlue",
+            "DarkCyan",
+            "DarkGoldenrod",
+            "DarkGray",
+            "DarkGreen",
+            "DarkKhaki",
+            "DarkMagenta",
+            "DarkOliveGreen",
+            "DarkOrange",
+            "DarkOrchid",
+            "DarkRed",
+            "DarkSalmon",
+            "DarkSeaGreen",
+            "DarkSlateBlue",
+            "DarkSlateGray",
+            "DarkTurquoise",
+            "DarkViolet",
+            "DeepPink",
+            "DeepSkyBlue",
+            "DimGray",
+            "DodgerBlue",
+            "Firebrick",
+            "FloralWhite",
+            "ForestGreen",
+            "Fuchsia",
+            "Gainsboro",
+            "GhostWhite",
+            "Gold",
+            "Goldenrod",
+            "Gray",
+            "Green",
+            "GreenYellow",
+            "Honeydew",
+            "HotPink",
+            "IndianRed",
+            "Indigo",
+            "Ivory",
+            "Khaki",
+            "Lavender",
+            "LavenderBlush",
+            "LawnGreen",
+            "LemonChiffon",
+            "LightBlue",
+            "LightCoral",
+            "LightCyan",
+            "LightGoldenrodYellow",
+            "LightGray",
+            "LightGreen",
+            "LightPink",
+            "LightSalmon",
+            "LightSeaGreen",
+            "LightSkyBlue",
+            "LightSlateGray",
+            "LightSteelBlue",
+            "LightYellow",
+            "Lime",
+            "LimeGreen",
+            "Linen",
+            "Magenta",
+            "Maroon",
+            "MediumAquamarine",
+            "MediumBlue",
+            "MediumOrchid",
+            "MediumPurple",
+            "MediumSeaGreen",
+            "MediumSlateBlue",
+            "MediumSpringGreen",
+            "MediumTurquoise",
+            "MediumVioletRed",
+            "MidnightBlue",
+            "MintCream",
+            "MistyRose",
+            "Moccasin",
+            "NavajoWhite",
+            "Navy",
+            "OldLace",
+            "Olive",
+            "OliveDrab",
+            "Orange",
+            "OrangeRed",
+            "Orchid",
+            "PaleGoldenrod",
+            "PaleGreen",
+            "PaleTurquoise",
+            "PaleVioletRed",
+            "PapayaWhip",
+            "PeachPuff",
+            "Peru",
+            "Pink",
+            "Plum",
+            "PowderBlue",
+            "Purple",
+            "Red",
+            "RosyBrown",
+            "RoyalBlue",
+            "SaddleBrown",
+            "Salmon",
+            "SandyBrown",
+            "SeaGreen",
+            "SeaShell",
+            "Sienna",
+            "Silver",
+            "SkyBlue",
+            "SlateBlue",
+            "SlateGray",
+            "Snow",
+            "SpringGreen",
+            "SteelBlue",
+            "Tan",
+            "Teal",
+            "Thistle",
+            "Tomato",
+            "Turquoise",
+            "Violet",
+            "Wheat",
+            "White",
+            "WhiteSmoke",
+            "Yellow",
+            "YellowGreen",
+            "ButtonFace",
+            "ButtonHighlight",
+            "ButtonShadow",
+            "GradientActiveCaption",
+            "GradientInactiveCaption",
+            "MenuBar",
+            "MenuHighlight"
+        };
+
+        public static string KnownColorToName(KnownColor color)
+        {
+            Debug.Assert(color > 0 && color <= KnownColor.MenuHighlight);
+            return s_colorNameTable[unchecked((int)color) - 1];
+        }
+    }
+}
index fd416d7..e34f126 100644 (file)
@@ -12,7 +12,7 @@ namespace System.Drawing.Primitives.Tests
 {
     public partial class ColorTests
     {
-        public static bool SupportsSystemEvents => PlatformDetection.IsWindows && !PlatformDetection.IsUap && PlatformDetection.IsNotWindowsNanoServer;
+        public static bool SupportsReadingUpdatedSystemColors => PlatformDetection.IsWindows && !PlatformDetection.IsUap && PlatformDetection.IsNotWindowsNanoServer;
 
         public static readonly IEnumerable<object[]> NamedArgbValues =
             new[]
@@ -493,7 +493,7 @@ namespace System.Drawing.Primitives.Tests
             DebuggerAttributes.ValidateDebuggerDisplayReferences(Color.FromArgb(4, 3, 2, 1));
         }
 
-        [ConditionalFact(nameof(SupportsSystemEvents))]
+        [ConditionalFact(nameof(SupportsReadingUpdatedSystemColors))]
         public void UserPreferenceChangingEventTest()
         {
             int element = 12; // Win32SystemColors.AppWorkSpace.
@@ -512,11 +512,7 @@ namespace System.Drawing.Primitives.Tests
             try
             {
                 Assert.Equal(1, SetSysColors(1, new int[] { element }, new int[] { newColorAbgr }));
-
-                RetryHelper.Execute(() =>
-                {
-                    Assert.Equal(newColorArgb, oldColor.ToArgb());
-                });
+                Assert.Equal(newColorArgb, oldColor.ToArgb());
             }
             finally
             {
diff --git a/src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs b/src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs
new file mode 100644 (file)
index 0000000..bc4c624
--- /dev/null
@@ -0,0 +1,267 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Common.Tests;
+using System.Globalization;
+using System.Reflection;
+using System.Threading;
+using Xunit;
+
+namespace System.Drawing.Tests
+{
+    public class ColorTranslatorTests
+    {
+        public static IEnumerable<(int, Color)> SystemColors_TestData()
+        {
+            yield return (unchecked((int)0x8000000A), SystemColors.ActiveBorder);
+            yield return (unchecked((int)0x80000002), SystemColors.ActiveCaption);
+            yield return (unchecked((int)0x80000009), SystemColors.ActiveCaptionText);
+            yield return (unchecked((int)0x8000000C), SystemColors.AppWorkspace);
+            yield return (unchecked((int)0x8000000F), SystemColors.Control);
+            yield return (unchecked((int)0x80000010), SystemColors.ControlDark);
+            yield return (unchecked((int)0x80000015), SystemColors.ControlDarkDark);
+            yield return (unchecked((int)0x80000016), SystemColors.ControlLight);
+            yield return (unchecked((int)0x80000014), SystemColors.ControlLightLight);
+            yield return (unchecked((int)0x80000012), SystemColors.ControlText);
+            yield return (unchecked((int)0x80000001), SystemColors.Desktop);
+            yield return (unchecked((int)0x8000001B), SystemColors.GradientActiveCaption);
+            yield return (unchecked((int)0x8000001C), SystemColors.GradientInactiveCaption);
+            yield return (unchecked((int)0x80000011), SystemColors.GrayText);
+            yield return (unchecked((int)0x8000000D), SystemColors.Highlight);
+            yield return (unchecked((int)0x8000000E), SystemColors.HighlightText);
+            yield return (unchecked((int)0x8000001A), SystemColors.HotTrack);
+            yield return (unchecked((int)0x8000000B), SystemColors.InactiveBorder);
+            yield return (unchecked((int)0x80000003), SystemColors.InactiveCaption);
+            yield return (unchecked((int)0x80000013), SystemColors.InactiveCaptionText);
+            yield return (unchecked((int)0x80000018), SystemColors.Info);
+            yield return (unchecked((int)0x80000017), SystemColors.InfoText);
+            yield return (unchecked((int)0x80000004), SystemColors.Menu);
+            yield return (unchecked((int)0x8000001E), SystemColors.MenuBar);
+            yield return (unchecked((int)0x8000001D), SystemColors.MenuHighlight);
+            yield return (unchecked((int)0x80000007), SystemColors.MenuText);
+            yield return (unchecked((int)0x80000000), SystemColors.ScrollBar);
+            yield return (unchecked((int)0x80000005), SystemColors.Window);
+            yield return (unchecked((int)0x80000006), SystemColors.WindowFrame);
+            yield return (unchecked((int)0x80000008), SystemColors.WindowText);
+        }
+
+        public static IEnumerable<object[]> ToWin32Color_TestData()
+        {
+            yield return new object[] { new Color(), 0 };
+            yield return new object[] { Color.Red, 255 };
+            yield return new object[] { Color.White, 16777215 };
+            yield return new object[] { Color.FromArgb(1, 2, 3), 197121 };
+        }
+
+        [Theory]
+        [MemberData(nameof(ToWin32Color_TestData))]
+        public void ToWin32Color_Color_ReturnsExpected(Color color, int expected)
+        {
+            Assert.Equal(expected, ColorTranslator.ToWin32(color));
+        }
+
+        public static IEnumerable<object[]> FromOle_TestData()
+        {
+            yield return new object[] { int.MinValue, SystemColors.ScrollBar };
+            yield return new object[] { -1, Color.White };
+            yield return new object[] { 0, Color.Black };
+            yield return new object[] { 197121, Color.FromArgb(1, 2, 3) };
+            yield return new object[] { 16777215, Color.White };
+            yield return new object[] { int.MaxValue, Color.White };
+            yield return new object[] { unchecked((int)0x8000001F), Color.FromArgb(255, 31, 0, 0) };
+            yield return new object[] { unchecked((int)0x80000019), Color.FromArgb(255, 25, 0, 0) };
+
+            foreach ((int oleColor, Color color) in SystemColors_TestData())
+            {
+                yield return new object[] { oleColor, color };
+            }
+        }
+
+        [Theory]
+        [MemberData(nameof(FromOle_TestData))]
+        public void FromOle_Color_ReturnsExpected(int oleColor, Color color)
+        {
+            Assert.Equal(color, ColorTranslator.FromOle(oleColor));
+            Assert.Equal(color, ColorTranslator.FromWin32(oleColor));
+        }
+
+        public static IEnumerable<object[]> ToOle_TestData()
+        {
+            yield return new object[] { new Color(), 0 };
+            yield return new object[] { Color.Red, 255 };
+            yield return new object[] { Color.White, 16777215 };
+            yield return new object[] { Color.FromArgb(1, 2, 3), 197121 };
+
+            foreach ((int oleColor, Color color) in SystemColors_TestData())
+            {
+                yield return new object[] { color, oleColor };
+            }
+
+            // These system colors are equivilent to Control, ControlLight and ControlDark.
+            yield return new object[] { SystemColors.ButtonFace, unchecked((int)0x8000000F) };
+            yield return new object[] { SystemColors.ButtonHighlight, unchecked((int)0x80000014) };
+            yield return new object[] { SystemColors.ButtonShadow, unchecked((int)0x80000010) };
+        }
+
+        [Theory]
+        [MemberData(nameof(ToOle_TestData))]
+        public void ToOle_Color_ReturnsExpected(Color color, int oleColor)
+        {
+            Assert.Equal(oleColor, ColorTranslator.ToOle(color));
+        }
+
+        public static IEnumerable<(string, Color)> HtmlColors_TestData()
+        {
+            yield return ("activeborder", SystemColors.ActiveBorder);
+            yield return ("activecaption", SystemColors.ActiveCaption);
+            yield return ("appworkspace", SystemColors.AppWorkspace);
+            yield return ("background", SystemColors.Desktop);
+            yield return ("buttonface", SystemColors.Control);
+            yield return ("buttonhighlight", SystemColors.ControlLightLight);
+            yield return ("buttonshadow", SystemColors.ControlDark);
+            yield return ("buttontext", SystemColors.ControlText);
+            yield return ("captiontext", SystemColors.ActiveCaptionText);
+            yield return ("graytext", SystemColors.GrayText);
+            yield return ("highlight", SystemColors.Highlight);
+            yield return ("highlighttext", SystemColors.HighlightText);
+            yield return ("inactiveborder", SystemColors.InactiveBorder);
+            yield return ("inactivecaption", SystemColors.InactiveCaption);
+            yield return ("inactivecaptiontext", SystemColors.InactiveCaptionText);
+            yield return ("infobackground", SystemColors.Info);
+            yield return ("infotext", SystemColors.InfoText);
+            yield return ("menu", SystemColors.Menu);
+            yield return ("menutext", SystemColors.MenuText);
+            yield return ("scrollbar", SystemColors.ScrollBar);
+            yield return ("window", SystemColors.Window);
+            yield return ("windowframe", SystemColors.WindowFrame);
+            yield return ("windowtext", SystemColors.WindowText);
+            yield return ("threeddarkshadow", SystemColors.ControlDarkDark);
+
+            yield return ("LightGrey", Color.LightGray);
+            yield return ("Blue", Color.Blue);
+            yield return ("#1F2E3D", Color.FromArgb(31, 46, 61));
+        }
+
+        public static IEnumerable<object[]> FromHtml_TestData()
+        {
+            yield return new object[] { null, Color.Empty };
+            yield return new object[] { "", Color.Empty };
+            yield return new object[] { "  ", Color.Empty };
+            yield return new object[] { "''", Color.FromName("") };
+            yield return new object[] { "\"\"", Color.FromName("") };
+
+            yield return new object[] { "#1B3", Color.FromArgb(17, 187, 51) };
+            yield return new object[] { "  #1F2E3D  ", Color.FromArgb(31, 46, 61) };
+
+            yield return new object[] { "ActiveBorder", SystemColors.ActiveBorder };
+            yield return new object[] { "ACTIVEBORDER", SystemColors.ActiveBorder };
+            yield return new object[] { "  Blue  ", Color.Blue };
+            yield return new object[] { "'Blue'", Color.Blue };
+            yield return new object[] { "\"Blue\"", Color.Blue };
+            yield return new object[] { "'None'", Color.FromName("None") };
+            yield return new object[] { "\"None\"", Color.FromName("None") };
+            yield return new object[] { "255,0,0", Color.Red };
+
+            // Color(argb)
+            yield return new object[] { 498, Color.FromArgb(0, 0, 1, 242) };
+            yield return new object[] { "&h1F2", Color.FromArgb(0, 0, 1, 242) };
+            yield return new object[] { "&h1F2", Color.FromArgb(0, 0, 1, 242) };
+
+            // Color(red, green, blue)
+            yield return new object[] { "1, 0x2, &h3", Color.FromArgb(1, 2, 3) };
+
+            // Color(alpha, red, green, blue)
+            yield return new object[] { "1, 2, 0x3, &h4", Color.FromArgb(1, 2, 3, 4) };
+
+            foreach ((string htmlColor, Color color) in HtmlColors_TestData())
+            {
+                yield return new object[] { htmlColor, color };
+            }
+
+            // Some of the SystemColors.Control colors don't roundtrip.
+            yield return new object[] { "threedface", SystemColors.Control };
+            yield return new object[] { "threedhighlight", SystemColors.ControlLight };
+            yield return new object[] { "threedlightshadow", SystemColors.ControlLightLight };
+        }
+
+        [Theory]
+        [MemberData(nameof(FromHtml_TestData))]
+        public void FromHtml_String_ReturnsExpected(string htmlColor, Color expected)
+        {
+            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
+            {
+                Assert.Equal(expected, ColorTranslator.FromHtml(htmlColor));
+            }
+        }
+
+        [Theory]
+        [InlineData("'")]
+        [InlineData("'\"")]
+        [InlineData("\"'")]
+        [InlineData("#")]
+        [InlineData("  #G12  ")]
+        [InlineData("  #G12345  ")]
+        [InlineData("#FFFFFFFFF")]
+        [InlineData("0x")]
+        [InlineData("0xFFFFFFFFF")]
+        [InlineData("0xG12")]
+        [InlineData("&h")]
+        [InlineData("&hG12")]
+        public void FromHtml_Invalid_Throws(string htmlColor)
+        {
+            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
+            {
+                Exception exception = AssertExtensions.Throws<ArgumentException, Exception>(() => ColorTranslator.FromHtml(htmlColor));
+                if (exception is ArgumentException argumentException)
+                    Assert.Equal("htmlColor", argumentException.ParamName);
+            }
+        }
+
+        [ConditionalTheory(Helpers.IsDrawingSupported)]
+        [InlineData("#G12", typeof(FormatException))]
+        [InlineData("#G12345", typeof(FormatException))]
+        [InlineData("1,2", typeof(ArgumentException))]
+        [InlineData("1,2,3,4,5", typeof(ArgumentException))]
+        [InlineData("-1,2,3", typeof(ArgumentException))]
+        [InlineData("256,2,3", typeof(ArgumentException))]
+        [InlineData("1,-1,3", typeof(ArgumentException))]
+        [InlineData("1,256,3", typeof(ArgumentException))]
+        [InlineData("1,2,-1", typeof(ArgumentException))]
+        [InlineData("1,2,256", typeof(ArgumentException))]
+        public void FromHtml_Invalid_Throw(string htmlColor, Type exception)
+        {
+            using (new ThreadCultureChange(CultureInfo.InvariantCulture))
+            {
+                Assert.Throws(exception, () => ColorTranslator.FromHtml(htmlColor));
+            }
+        }
+
+        public static IEnumerable<object[]> ToHtml_TestData()
+        {
+            yield return new object[] { Color.Empty, "" };
+
+            foreach ((string htmlColor, Color color) in HtmlColors_TestData())
+            {
+                yield return new object[] { color, htmlColor };
+            }
+
+            // SystemColors.ControlLight don't roundtrip.
+            yield return new object[] { SystemColors.ControlLight, "buttonface" };
+            yield return new object[] { SystemColors.GradientActiveCaption, "activecaption" };
+            yield return new object[] { SystemColors.HotTrack, "highlight" };
+            yield return new object[] { SystemColors.MenuHighlight, "highlighttext" };
+            yield return new object[] { SystemColors.GradientInactiveCaption, "inactivecaption" };
+            yield return new object[] { SystemColors.MenuBar, "menu" };
+            yield return new object[] { SystemColors.ButtonShadow, "" };
+        }
+
+        [Theory]
+        [MemberData(nameof(ToHtml_TestData))]
+        public void ToHtml_Color_ReturnsExpected(Color color, string expected)
+        {
+            Assert.Equal(expected, ColorTranslator.ToHtml(color));
+        }
+    }
+}
diff --git a/src/libraries/System.Drawing.Primitives/tests/Helpers.cs b/src/libraries/System.Drawing.Primitives/tests/Helpers.cs
new file mode 100644 (file)
index 0000000..8118a2a
--- /dev/null
@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Drawing.Tests
+{
+    public static class Helpers
+    {
+        public const string IsDrawingSupported = nameof(Helpers) + "." + nameof(GetIsDrawingSupported);
+
+        public static bool GetIsDrawingSupported() => /* ActiveIssue(24525) */ PlatformDetection.IsNotRedHatFamily6 && PlatformDetection.IsDrawingSupported;
+    }
+}
index 2e6caa5..188cdde 100644 (file)
@@ -1,10 +1,12 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <ProjectGuid>{CF54638C-A382-4A78-9AD6-2304CEEFEB01}</ProjectGuid>
     <Configurations>netcoreapp-Debug;netcoreapp-Release;uap-Debug;uap-Release</Configurations>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="ColorTranslatorTests.cs" />
     <Compile Include="DataContractSerializerTests.cs" />
+    <Compile Include="Helpers.cs" />
     <Compile Include="PointFTests.cs" />
     <Compile Include="PointTests.cs" />
     <Compile Include="RectangleFTests.cs" />
     <Compile Include="$(CommonTestPath)\System\Diagnostics\DebuggerAttributes.cs">
       <Link>Common\System\Diagnostics\DebuggerAttributes.cs</Link>
     </Compile>
-    <Compile Include="$(CommonTestPath)\System\Runtime\Serialization\DataContractSerializerHelper.cs" />
-    <Compile Include="$(CommonTestPath)\System\Runtime\Serialization\Utils.cs" />
+    <Compile Include="$(CommonTestPath)\System\ThreadCultureChange.cs">
+      <Link>Common\System\ThreadCultureChange.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonTestPath)\System\Runtime\Serialization\DataContractSerializerHelper.cs">
+      <Link>Common\System\Runtime\Serialization\DataContractSerializerHelper.cs</Link>
+    </Compile>
+    <Compile Include="$(CommonTestPath)\System\Runtime\Serialization\Utils.cs">
+      <Link>Common\System\Runtime\Serialization\Utils.cs</Link>
+    </Compile>
   </ItemGroup>
   <ItemGroup Condition="'$(TargetsNetCoreApp)' == 'true'">
     <Compile Include="SizeFTests.netcoreapp.cs" />