From e54d8fd00ba4c10592aa2fcfd5a659f08899b58a Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 22 May 2019 10:38:15 +0200 Subject: [PATCH] Rework implementation of Color based on CoreFX code, add direct conversion to system colors Co-Authored-By: Jiri Volejnik --- Shared.projitems | 1 + System.Drawing/Color.cs | 743 +++++++++++------------------- System.Drawing/ColorTable.cs | 37 ++ System.Drawing/Extensions.cs | 4 +- System.Drawing/Graphics.cs | 3 +- System.Drawing/KnownColors.cs | 74 +-- System.Drawing/KnownColors.ios.cs | 11 +- System.Drawing/KnownColors.mac.cs | 73 ++- System.Drawing/SolidBrush.cs | 6 +- Utilities/ConversionHelpers.cs | 17 +- 10 files changed, 393 insertions(+), 576 deletions(-) create mode 100644 System.Drawing/ColorTable.cs diff --git a/Shared.projitems b/Shared.projitems index 6fad14f..b7b0a2d 100644 --- a/Shared.projitems +++ b/Shared.projitems @@ -13,6 +13,7 @@ + diff --git a/System.Drawing/Color.cs b/System.Drawing/Color.cs index 0d67685..510464d 100644 --- a/System.Drawing/Color.cs +++ b/System.Drawing/Color.cs @@ -43,46 +43,79 @@ namespace System.Drawing [Serializable] [TypeConverter (typeof (ColorConverter))] public struct Color { - int value; + private const short StateKnownColorValid = 0x0001; + private const short StateARGBValueValid = 0x0002; + private const short StateValueMask = StateARGBValueValid; + private const short StateNameValid = 0x0008; + private const long NotDefinedValue = 0; + + // Do not rename (binary serialization) + private readonly string name; + private readonly long value; + private readonly short knownColor; + private readonly short state; + + internal Color (KnownColor knownColor) + { + value = 0; + state = StateKnownColorValid; + name = null; + this.knownColor = unchecked((short)knownColor); + } - internal Color (int value) + private Color (long value, short state, string name, KnownColor knownColor) { this.value = value; + this.state = state; + this.name = name; + this.knownColor = unchecked((short)knownColor); } -#region Unimplemented bloated properties - // - // These properties were implemented very poorly on Mono, this - // version will only store the int32 value and any helper properties - // like Name, IsKnownColor, IsSystemColor, IsNamedColor are not - // currently implemented, and would be implemented in the future - // using external tables/hastables/dictionaries, without bloating - // the Color structure - // public string Name { get { - return KnownColors.NameByArgb.TryGetValue ((uint)value, out string name) ? name : String.Empty; + if ((state & StateNameValid) != 0) { + return name; + } + + if (IsKnownColor) { + return KnownColors.GetName ((KnownColor)knownColor); + } + + return Convert.ToString(value, 16); + } + } + + internal long Value { + get { + if ((state & StateValueMask) != 0) { + return value; + } + + if (IsKnownColor) { + return KnownColors.GetValue ((KnownColor)knownColor); + } + + return NotDefinedValue; } } public bool IsKnownColor { get{ - return KnownColors.NameByArgb.ContainsKey ((uint)value); + return (state & StateKnownColorValid) != 0; } } public bool IsSystemColor { get{ - return false; + return IsKnownColor && (((KnownColor)knownColor <= KnownColor.WindowText) || ((KnownColor)knownColor > KnownColor.YellowGreen)); } } public bool IsNamedColor { - get{ - throw new NotImplementedException (); + get { + return ((state & StateNameValid) != 0) || IsKnownColor; } } -#endregion public static Color FromArgb (int red, int green, int blue) { @@ -91,23 +124,21 @@ public static Color FromArgb (int red, int green, int blue) public static Color FromArgb (int alpha, int red, int green, int blue) { - if((red > 255) || (red < 0)) - throw CreateColorArgumentException(red, "red"); - if((green > 255) || (green < 0)) - throw CreateColorArgumentException (green, "green"); - if((blue > 255) || (blue < 0)) - throw CreateColorArgumentException (blue, "blue"); - if((alpha > 255) || (alpha < 0)) - throw CreateColorArgumentException (alpha, "alpha"); - - Color color = new Color (); - color.value = (int)((uint) alpha << 24) + (red << 16) + (green << 8) + blue; - return color; + if ((red > 255) || (red < 0)) + throw CreateColorArgumentException(red, nameof(red)); + if ((green > 255) || (green < 0)) + throw CreateColorArgumentException (green, nameof(green)); + if ((blue > 255) || (blue < 0)) + throw CreateColorArgumentException (blue, nameof(blue)); + if ((alpha > 255) || (alpha < 0)) + throw CreateColorArgumentException (alpha, nameof(alpha)); + + return new Color (((uint) alpha << 24) + (red << 16) + (green << 8) + blue, StateARGBValueValid, null, (KnownColor)0); } public int ToArgb() { - return (int) value; + return (int) Value; } public static Color FromArgb (int alpha, Color baseColor) @@ -117,19 +148,25 @@ public static Color FromArgb (int alpha, Color baseColor) public static Color FromArgb (int argb) { - return new Color (argb); + return new Color (unchecked((uint)argb), StateARGBValueValid, null, (KnownColor)0); } public static Color FromKnownColor (KnownColor color) { - return KnownColors.FromKnownColor (color); + if (color <= 0 || color > KnownColor.MenuHighlight) { + return FromName (color.ToString()); + } + + return new Color (color); } public static Color FromName (string name) { - if (KnownColors.ArgbByName.TryGetValue (name, out uint argb)) - return new Color ((int)argb); - return new Color (); + if (ColorTable.TryGetNamedColor (name, out Color color)) { + return color; + } + + return new Color (NotDefinedValue, StateNameValid, name, (KnownColor)0); } @@ -137,26 +174,42 @@ public static Color FromName (string name) public static bool operator == (Color left, Color right) { - return left.value == right.value; + return + left.value == right.value && + left.state == right.state && + left.knownColor == right.knownColor && + left.name == right.name; } public static bool operator != (Color left, Color right) { - return left.value != right.value; + return !(left == right); } - + + private void GetRgbValues (out int r, out int g, out int b) + { + uint value = (uint)Value; + r = (byte) (value >> 16); + g = (byte) (value >> 8); + b = (byte) (value); + } + public float GetBrightness () { - byte minval = Math.Min (R, Math.Min (G, B)); - byte maxval = Math.Max (R, Math.Max (G, B)); + GetRgbValues (out int r, out int g, out int b); + + int minval = Math.Min (r, Math.Min (g, b)); + int maxval = Math.Max (r, Math.Max (g, b)); return (float)(maxval + minval) / 510; } public float GetSaturation () { - byte minval = (byte) Math.Min (R, Math.Min (G, B)); - byte maxval = (byte) Math.Max (R, Math.Max (G, B)); + GetRgbValues (out int r, out int g, out int b); + + int minval = Math.Min (r, Math.Min (g, b)); + int maxval = Math.Max (r, Math.Max (g, b)); if (maxval == minval) return 0.0f; @@ -170,9 +223,8 @@ public float GetSaturation () public float GetHue () { - int r = R; - int g = G; - int b = B; + GetRgbValues (out int r, out int g, out int b); + byte minval = (byte) Math.Min (r, Math.Min (g, b)); byte maxval = (byte) Math.Max (r, Math.Max (g, b)); @@ -199,30 +251,30 @@ public float GetHue () public KnownColor ToKnownColor () { - throw new NotImplementedException (); + return (KnownColor)knownColor; } public bool IsEmpty { get { - return value == 0; + return state == 0; } } public byte A { - get { return (byte) (value >> 24); } + get { return (byte) (Value >> 24); } } public byte R { - get { return (byte) (value >> 16); } + get { return (byte) (Value >> 16); } } public byte G { - get { return (byte) (value >> 8); } + get { return (byte) (Value >> 8); } } public byte B { - get { return (byte) value; } + get { return (byte) Value; } } public override bool Equals (object obj) @@ -233,19 +285,32 @@ public override bool Equals (object obj) return this == c; } + private static int CombineHashCode(int h1, int h2) + { + // RyuJIT optimizes this to use the ROL instruction + // Related GitHub pull request: dotnet/coreclr#1830 + uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); + return ((int)rol5 + h1) ^ h2; + } + public override int GetHashCode () { - return value; + if (name != null) + return name.GetHashCode (); + return CombineHashCode (CombineHashCode (value.GetHashCode (), knownColor.GetHashCode ()), state.GetHashCode ()); } public override string ToString () { - if (IsEmpty) - return "Color [Empty]"; - - return String.Format ("Color [A={0}, R={1}, G={2}, B={3}]", A, R, G, B); + if (IsNamedColor) { + return nameof(Color) + " [" + Name + "]"; + } else if ((state & StateValueMask) != 0) { + return nameof(Color) + " [A=" + A.ToString() + ", R=" + R.ToString() + ", G=" + G.ToString() + ", B=" + B.ToString() + "]"; + } else { + return nameof(Color) + " [Empty]"; + } } - + static ArgumentException CreateColorArgumentException (int value, string color) { return new ArgumentException (string.Format ("'{0}' is not a valid" @@ -253,568 +318,286 @@ static ArgumentException CreateColorArgumentException (int value, string color) + " less than or equal to 255.", value, color)); } - static public Color Transparent { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Transparent]); } - } + public static Color Transparent => new Color (KnownColor.Transparent); - static public Color AliceBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.AliceBlue]); } - } + public static Color AliceBlue => new Color (KnownColor.AliceBlue); - static public Color AntiqueWhite { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.AntiqueWhite]); } - } + public static Color AntiqueWhite => new Color (KnownColor.AntiqueWhite); - static public Color Aqua { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Aqua]); } - } + public static Color Aqua => new Color (KnownColor.Aqua); - static public Color Aquamarine { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Aquamarine]); } - } + public static Color Aquamarine => new Color (KnownColor.Aquamarine); - static public Color Azure { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Azure]); } - } + public static Color Azure => new Color (KnownColor.Azure); - static public Color Beige { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Beige]); } - } + public static Color Beige => new Color (KnownColor.Beige); - static public Color Bisque { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Bisque]); } - } + public static Color Bisque => new Color (KnownColor.Bisque); - static public Color Black { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Black]); } - } + public static Color Black => new Color (KnownColor.Black); - static public Color BlanchedAlmond { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.BlanchedAlmond]); } - } + public static Color BlanchedAlmond => new Color (KnownColor.BlanchedAlmond); - static public Color Blue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Blue]); } - } + public static Color Blue => new Color (KnownColor.Blue); - static public Color BlueViolet { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.BlueViolet]); } - } + public static Color BlueViolet => new Color (KnownColor.BlueViolet); - static public Color Brown { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Brown]); } - } + public static Color Brown => new Color (KnownColor.Brown); - static public Color BurlyWood { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.BurlyWood]); } - } + public static Color BurlyWood => new Color (KnownColor.BurlyWood); - static public Color CadetBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.CadetBlue]); } - } + public static Color CadetBlue => new Color (KnownColor.CadetBlue); - static public Color Chartreuse { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Chartreuse]); } - } + public static Color Chartreuse => new Color (KnownColor.Chartreuse); - static public Color Chocolate { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Chocolate]); } - } + public static Color Chocolate => new Color (KnownColor.Chocolate); - static public Color Coral { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Coral]); } - } + public static Color Coral => new Color (KnownColor.Coral); - static public Color CornflowerBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.CornflowerBlue]); } - } + public static Color CornflowerBlue => new Color (KnownColor.CornflowerBlue); - static public Color Cornsilk { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Cornsilk]); } - } + public static Color Cornsilk => new Color (KnownColor.Cornsilk); - static public Color Crimson { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Crimson]); } - } + public static Color Crimson => new Color (KnownColor.Crimson); - static public Color Cyan { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Cyan]); } - } + public static Color Cyan => new Color (KnownColor.Cyan); - static public Color DarkBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkBlue]); } - } + public static Color DarkBlue => new Color (KnownColor.DarkBlue); - static public Color DarkCyan { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkCyan]); } - } + public static Color DarkCyan => new Color (KnownColor.DarkCyan); - static public Color DarkGoldenrod { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkGoldenrod]); } - } + public static Color DarkGoldenrod => new Color (KnownColor.DarkGoldenrod); - static public Color DarkGray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkGray]); } - } + public static Color DarkGray => new Color (KnownColor.DarkGray); - static public Color DarkGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkGreen]); } - } + public static Color DarkGreen => new Color (KnownColor.DarkGreen); - static public Color DarkKhaki { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkKhaki]); } - } + public static Color DarkKhaki => new Color (KnownColor.DarkKhaki); - static public Color DarkMagenta { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkMagenta]); } - } + public static Color DarkMagenta => new Color (KnownColor.DarkMagenta); - static public Color DarkOliveGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkOliveGreen]); } - } + public static Color DarkOliveGreen => new Color (KnownColor.DarkOliveGreen); - static public Color DarkOrange { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkOrange]); } - } + public static Color DarkOrange => new Color (KnownColor.DarkOrange); - static public Color DarkOrchid { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkOrchid]); } - } + public static Color DarkOrchid => new Color (KnownColor.DarkOrchid); - static public Color DarkRed { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkRed]); } - } + public static Color DarkRed => new Color (KnownColor.DarkRed); - static public Color DarkSalmon { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkSalmon]); } - } + public static Color DarkSalmon => new Color (KnownColor.DarkSalmon); - static public Color DarkSeaGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkSeaGreen]); } - } + public static Color DarkSeaGreen => new Color (KnownColor.DarkSeaGreen); - static public Color DarkSlateBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkSlateBlue]); } - } + public static Color DarkSlateBlue => new Color (KnownColor.DarkSlateBlue); - static public Color DarkSlateGray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkSlateGray]); } - } + public static Color DarkSlateGray => new Color (KnownColor.DarkSlateGray); - static public Color DarkTurquoise { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkTurquoise]); } - } + public static Color DarkTurquoise => new Color (KnownColor.DarkTurquoise); - static public Color DarkViolet { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DarkViolet]); } - } + public static Color DarkViolet => new Color (KnownColor.DarkViolet); - static public Color DeepPink { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DeepPink]); } - } + public static Color DeepPink => new Color (KnownColor.DeepPink); - static public Color DeepSkyBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DeepSkyBlue]); } - } + public static Color DeepSkyBlue => new Color (KnownColor.DeepSkyBlue); - static public Color DimGray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DimGray]); } - } + public static Color DimGray => new Color (KnownColor.DimGray); - static public Color DodgerBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.DodgerBlue]); } - } + public static Color DodgerBlue => new Color (KnownColor.DodgerBlue); - static public Color Firebrick { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Firebrick]); } - } + public static Color Firebrick => new Color (KnownColor.Firebrick); - static public Color FloralWhite { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.FloralWhite]); } - } + public static Color FloralWhite => new Color (KnownColor.FloralWhite); - static public Color ForestGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.ForestGreen]); } - } + public static Color ForestGreen => new Color (KnownColor.ForestGreen); - static public Color Fuchsia { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Fuchsia]); } - } + public static Color Fuchsia => new Color (KnownColor.Fuchsia); - static public Color Gainsboro { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Gainsboro]); } - } + public static Color Gainsboro => new Color (KnownColor.Gainsboro); - static public Color GhostWhite { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.GhostWhite]); } - } + public static Color GhostWhite => new Color (KnownColor.GhostWhite); - static public Color Gold { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Gold]); } - } + public static Color Gold => new Color (KnownColor.Gold); - static public Color Goldenrod { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Goldenrod]); } - } + public static Color Goldenrod => new Color (KnownColor.Goldenrod); - static public Color Gray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Gray]); } - } + public static Color Gray => new Color (KnownColor.Gray); - static public Color Green { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Green]); } - } + public static Color Green => new Color (KnownColor.Green); - static public Color GreenYellow { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.GreenYellow]); } - } + public static Color GreenYellow => new Color (KnownColor.GreenYellow); - static public Color Honeydew { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Honeydew]); } - } + public static Color Honeydew => new Color (KnownColor.Honeydew); - static public Color HotPink { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.HotPink]); } - } + public static Color HotPink => new Color (KnownColor.HotPink); - static public Color IndianRed { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.IndianRed]); } - } + public static Color IndianRed => new Color (KnownColor.IndianRed); - static public Color Indigo { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Indigo]); } - } + public static Color Indigo => new Color (KnownColor.Indigo); - static public Color Ivory { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Ivory]); } - } + public static Color Ivory => new Color (KnownColor.Ivory); - static public Color Khaki { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Khaki]); } - } + public static Color Khaki => new Color (KnownColor.Khaki); - static public Color Lavender { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Lavender]); } - } + public static Color Lavender => new Color (KnownColor.Lavender); - static public Color LavenderBlush { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LavenderBlush]); } - } + public static Color LavenderBlush => new Color (KnownColor.LavenderBlush); - static public Color LawnGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LawnGreen]); } - } + public static Color LawnGreen => new Color (KnownColor.LawnGreen); - static public Color LemonChiffon { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LemonChiffon]); } - } + public static Color LemonChiffon => new Color (KnownColor.LemonChiffon); - static public Color LightBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightBlue]); } - } + public static Color LightBlue => new Color (KnownColor.LightBlue); - static public Color LightCoral { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightCoral]); } - } + public static Color LightCoral => new Color (KnownColor.LightCoral); - static public Color LightCyan { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightCyan]); } - } + public static Color LightCyan => new Color (KnownColor.LightCyan); - static public Color LightGoldenrodYellow { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightGoldenrodYellow]); } - } + public static Color LightGoldenrodYellow => new Color (KnownColor.LightGoldenrodYellow); - static public Color LightGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightGreen]); } - } + public static Color LightGreen => new Color (KnownColor.LightGreen); - static public Color LightGray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightGray]); } - } + public static Color LightGray => new Color (KnownColor.LightGray); - static public Color LightPink { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightPink]); } - } + public static Color LightPink => new Color (KnownColor.LightPink); - static public Color LightSalmon { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightSalmon]); } - } + public static Color LightSalmon => new Color (KnownColor.LightSalmon); - static public Color LightSeaGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightSeaGreen]); } - } + public static Color LightSeaGreen => new Color (KnownColor.LightSeaGreen); - static public Color LightSkyBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightSkyBlue]); } - } + public static Color LightSkyBlue => new Color (KnownColor.LightSkyBlue); - static public Color LightSlateGray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightSlateGray]); } - } + public static Color LightSlateGray => new Color (KnownColor.LightSlateGray); - static public Color LightSteelBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightSteelBlue]); } - } + public static Color LightSteelBlue => new Color (KnownColor.LightSteelBlue); - static public Color LightYellow { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LightYellow]); } - } + public static Color LightYellow => new Color (KnownColor.LightYellow); - static public Color Lime { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Lime]); } - } + public static Color Lime => new Color (KnownColor.Lime); - static public Color LimeGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.LimeGreen]); } - } + public static Color LimeGreen => new Color (KnownColor.LimeGreen); - static public Color Linen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Linen]); } - } + public static Color Linen => new Color (KnownColor.Linen); - static public Color Magenta { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Magenta]); } - } + public static Color Magenta => new Color (KnownColor.Magenta); - static public Color Maroon { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Maroon]); } - } + public static Color Maroon => new Color (KnownColor.Maroon); - static public Color MediumAquamarine { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumAquamarine]); } - } + public static Color MediumAquamarine => new Color (KnownColor.MediumAquamarine); - static public Color MediumBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumBlue]); } - } + public static Color MediumBlue => new Color (KnownColor.MediumBlue); - static public Color MediumOrchid { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumOrchid]); } - } + public static Color MediumOrchid => new Color (KnownColor.MediumOrchid); - static public Color MediumPurple { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumPurple]); } - } + public static Color MediumPurple => new Color (KnownColor.MediumPurple); - static public Color MediumSeaGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumSeaGreen]); } - } + public static Color MediumSeaGreen => new Color (KnownColor.MediumSeaGreen); - static public Color MediumSlateBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumSlateBlue]); } - } + public static Color MediumSlateBlue => new Color (KnownColor.MediumSlateBlue); - static public Color MediumSpringGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumSpringGreen]); } - } + public static Color MediumSpringGreen => new Color (KnownColor.MediumSpringGreen); - static public Color MediumTurquoise { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumTurquoise]); } - } + public static Color MediumTurquoise => new Color (KnownColor.MediumTurquoise); - static public Color MediumVioletRed { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MediumVioletRed]); } - } + public static Color MediumVioletRed => new Color (KnownColor.MediumVioletRed); - static public Color MidnightBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MidnightBlue]); } - } + public static Color MidnightBlue => new Color (KnownColor.MidnightBlue); - static public Color MintCream { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MintCream]); } - } + public static Color MintCream => new Color (KnownColor.MintCream); - static public Color MistyRose { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.MistyRose]); } - } + public static Color MistyRose => new Color (KnownColor.MistyRose); - static public Color Moccasin { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Moccasin]); } - } + public static Color Moccasin => new Color (KnownColor.Moccasin); - static public Color NavajoWhite { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.NavajoWhite]); } - } + public static Color NavajoWhite => new Color (KnownColor.NavajoWhite); - static public Color Navy { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Navy]); } - } + public static Color Navy => new Color (KnownColor.Navy); - static public Color OldLace { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.OldLace]); } - } + public static Color OldLace => new Color (KnownColor.OldLace); - static public Color Olive { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Olive]); } - } + public static Color Olive => new Color (KnownColor.Olive); - static public Color OliveDrab { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.OliveDrab]); } - } + public static Color OliveDrab => new Color (KnownColor.OliveDrab); - static public Color Orange { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Orange]); } - } + public static Color Orange => new Color (KnownColor.Orange); - static public Color OrangeRed { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.OrangeRed]); } - } + public static Color OrangeRed => new Color (KnownColor.OrangeRed); - static public Color Orchid { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Orchid]); } - } + public static Color Orchid => new Color (KnownColor.Orchid); - static public Color PaleGoldenrod { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PaleGoldenrod]); } - } + public static Color PaleGoldenrod => new Color (KnownColor.PaleGoldenrod); - static public Color PaleGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PaleGreen]); } - } + public static Color PaleGreen => new Color (KnownColor.PaleGreen); - static public Color PaleTurquoise { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PaleTurquoise]); } - } + public static Color PaleTurquoise => new Color (KnownColor.PaleTurquoise); - static public Color PaleVioletRed { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PaleVioletRed]); } - } + public static Color PaleVioletRed => new Color (KnownColor.PaleVioletRed); - static public Color PapayaWhip { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PapayaWhip]); } - } + public static Color PapayaWhip => new Color (KnownColor.PapayaWhip); - static public Color PeachPuff { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PeachPuff]); } - } + public static Color PeachPuff => new Color (KnownColor.PeachPuff); - static public Color Peru { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Peru]); } - } + public static Color Peru => new Color (KnownColor.Peru); - static public Color Pink { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Pink]); } - } + public static Color Pink => new Color (KnownColor.Pink); - static public Color Plum { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Plum]); } - } + public static Color Plum => new Color (KnownColor.Plum); - static public Color PowderBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.PowderBlue]); } - } + public static Color PowderBlue => new Color (KnownColor.PowderBlue); - static public Color Purple { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Purple]); } - } + public static Color Purple => new Color (KnownColor.Purple); - static public Color Red { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Red]); } - } + public static Color Red => new Color (KnownColor.Red); - static public Color RosyBrown { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.RosyBrown]); } - } + public static Color RosyBrown => new Color (KnownColor.RosyBrown); - static public Color RoyalBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.RoyalBlue]); } - } + public static Color RoyalBlue => new Color (KnownColor.RoyalBlue); - static public Color SaddleBrown { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SaddleBrown]); } - } + public static Color SaddleBrown => new Color (KnownColor.SaddleBrown); - static public Color Salmon { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Salmon]); } - } + public static Color Salmon => new Color (KnownColor.Salmon); - static public Color SandyBrown { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SandyBrown]); } - } + public static Color SandyBrown => new Color (KnownColor.SandyBrown); - static public Color SeaGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SeaGreen]); } - } + public static Color SeaGreen => new Color (KnownColor.SeaGreen); - static public Color SeaShell { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SeaShell]); } - } + public static Color SeaShell => new Color (KnownColor.SeaShell); - static public Color Sienna { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Sienna]); } - } + public static Color Sienna => new Color (KnownColor.Sienna); - static public Color Silver { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Silver]); } - } + public static Color Silver => new Color (KnownColor.Silver); - static public Color SkyBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SkyBlue]); } - } + public static Color SkyBlue => new Color (KnownColor.SkyBlue); - static public Color SlateBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SlateBlue]); } - } + public static Color SlateBlue => new Color (KnownColor.SlateBlue); - static public Color SlateGray { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SlateGray]); } - } + public static Color SlateGray => new Color (KnownColor.SlateGray); - static public Color Snow { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Snow]); } - } + public static Color Snow => new Color (KnownColor.Snow); - static public Color SpringGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SpringGreen]); } - } + public static Color SpringGreen => new Color (KnownColor.SpringGreen); - static public Color SteelBlue { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.SteelBlue]); } - } + public static Color SteelBlue => new Color (KnownColor.SteelBlue); - static public Color Tan { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Tan]); } - } + public static Color Tan => new Color (KnownColor.Tan); - static public Color Teal { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Teal]); } - } + public static Color Teal => new Color (KnownColor.Teal); - static public Color Thistle { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Thistle]); } - } + public static Color Thistle => new Color (KnownColor.Thistle); - static public Color Tomato { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Tomato]); } - } + public static Color Tomato => new Color (KnownColor.Tomato); - static public Color Turquoise { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Turquoise]); } - } + public static Color Turquoise => new Color (KnownColor.Turquoise); - static public Color Violet { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Violet]); } - } + public static Color Violet => new Color (KnownColor.Violet); - static public Color Wheat { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Wheat]); } - } + public static Color Wheat => new Color (KnownColor.Wheat); - static public Color White { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.White]); } - } + public static Color White => new Color (KnownColor.White); - static public Color WhiteSmoke { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.WhiteSmoke]); } - } + public static Color WhiteSmoke => new Color (KnownColor.WhiteSmoke); - static public Color Yellow { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.Yellow]); } - } + public static Color Yellow => new Color (KnownColor.Yellow); - static public Color YellowGreen { - get { return new Color((int)KnownColors.ArgbValues[(int)KnownColor.YellowGreen]); } - } + public static Color YellowGreen => new Color (KnownColor.YellowGreen); } } diff --git a/System.Drawing/ColorTable.cs b/System.Drawing/ColorTable.cs new file mode 100644 index 0000000..e1fda7f --- /dev/null +++ b/System.Drawing/ColorTable.cs @@ -0,0 +1,37 @@ +// 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.Reflection; + +namespace System.Drawing +{ + internal static class ColorTable + { + private static readonly Lazy> s_colorConstants = new Lazy>(GetColors); + + private static Dictionary GetColors() + { + var colors = new Dictionary(StringComparer.OrdinalIgnoreCase); + FillWithProperties(colors, typeof(Color)); + FillWithProperties(colors, typeof(SystemColors)); + return colors; + } + + private static void FillWithProperties(Dictionary dictionary, Type typeWithColors) + { + foreach (PropertyInfo prop in typeWithColors.GetProperties(BindingFlags.Public | BindingFlags.Static)) + { + if (prop.PropertyType == typeof(Color)) + dictionary[prop.Name] = (Color)prop.GetValue(null, null); + } + } + + internal static Dictionary Colors => s_colorConstants.Value; + + internal static bool TryGetNamedColor(string name, out Color result) => Colors.TryGetValue(name, out result); + + internal static bool IsKnownNamedColor(string name) => Colors.TryGetValue(name, out _); + } +} \ No newline at end of file diff --git a/System.Drawing/Extensions.cs b/System.Drawing/Extensions.cs index 302b63e..96ab71e 100644 --- a/System.Drawing/Extensions.cs +++ b/System.Drawing/Extensions.cs @@ -84,7 +84,7 @@ public static CTTextAlignment ToCTTextAlignment (this ContentAlignment a) public static CGColor ToCGColor (this Color c) { - return new CGColor (c.R / 255f, c.G / 255f, c.B / 255f, c.A / 255f); + return ConversionHelpers.ToCGColor (c); } public static NSData ToNSData (this Image image, Imaging.ImageFormat format) @@ -98,6 +98,6 @@ public static NSData ToNSData (this Image image, Imaging.ImageFormat format) public static Bitmap ToBitmap (this CGImage cgImage) { return new Bitmap (cgImage); - } + } } } diff --git a/System.Drawing/Graphics.cs b/System.Drawing/Graphics.cs index ec00477..e2decce 100644 --- a/System.Drawing/Graphics.cs +++ b/System.Drawing/Graphics.cs @@ -1292,8 +1292,7 @@ public void IntersectClip (Region region) public void Clear (Color color) { context.SaveState (); - //context.SetFillColorWithColor(new CGColor(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f)); - context.SetFillColor(new CGColor(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f)); + context.SetFillColor(color.ToCGColor()); context.FillRect(context.GetClipBoundingBox()); context.RestoreState (); } diff --git a/System.Drawing/KnownColors.cs b/System.Drawing/KnownColors.cs index 8fc4583..327f50c 100644 --- a/System.Drawing/KnownColors.cs +++ b/System.Drawing/KnownColors.cs @@ -37,7 +37,7 @@ namespace System.Drawing { internal static partial class KnownColors { - static internal uint[] ArgbValues = new uint[] { + static private uint[] ArgbValues = new uint[] { 0x00000000, /* 000 - Empty */ 0xFFD4D0C8, /* 001 - ActiveBorder */ 0xFF0054E3, /* 002 - ActiveCaption */ @@ -215,7 +215,7 @@ internal static partial class KnownColors 0xFF316AC5, /* 174 - MenuHighlight */ }; - static internal string[] Names = { + static private string[] Names = { String.Empty, "ActiveBorder", "ActiveCaption", @@ -393,68 +393,23 @@ internal static partial class KnownColors "MenuHighlight" }; - static Dictionary argbByName = null; - static Dictionary nameByArgb = null; - - static internal Dictionary ArgbByName + public static long GetValue (KnownColor kc) { - get - { - if (argbByName == null) - { - argbByName = new Dictionary(); - for (int i = 0; i < ArgbValues.Length; ++i) - argbByName[Names[i]] = ArgbValues[i]; - } - return argbByName; + if (kc >= KnownColor.ActiveBorder && kc <= KnownColor.WindowText) { + return FromSystemColor ((KnownColor)kc); } - } - - static internal Dictionary NameByArgb - { - get - { - if (nameByArgb == null) - { - nameByArgb = new Dictionary(); - for (int i = 0; i < Names.Length; ++i) - nameByArgb[ArgbValues[i]] = Names[i]; - } - return nameByArgb; + if (kc >= 0 && (int)kc < ArgbValues.Length) { + return ArgbValues[(int)kc]; } - } - - public static Color FromKnownColor (KnownColor kc) - { - Color c; - short n = (short)kc; - if ((n <= 0) || (n >= ArgbValues.Length)) - c = Color.FromArgb (0); - else - c = Color.FromArgb ((int)ArgbValues [n]); - return c; - } - - public static string GetName (short kc) - { - if (kc > 0 && kc < Names.Length) - return Names[kc]; - return String.Empty; + return 0; } public static string GetName (KnownColor kc) { - return GetName ((short)kc); - } - - public static Color FindColorMatch (Color c) - { - uint argb = (uint) c.ToArgb (); - for (int i = 0; i < KnownColors.ArgbValues.Length; i++) { - if (argb == KnownColors.ArgbValues [i]) - return KnownColors.FromKnownColor ((KnownColor)i); - } - return Color.Empty; + if (kc >= 0 && (int)kc < Names.Length) { + return Names[(int)kc]; + } + return String.Empty; } // When this method is called, we teach any new color(s) to the Color class @@ -464,10 +419,9 @@ public static void Update (int knownColor, int color) ArgbValues[knownColor] = (uint)color; } - static KnownColors() + static KnownColors () { - Update(); - WatchColorChanges (); + Update (); } } } diff --git a/System.Drawing/KnownColors.ios.cs b/System.Drawing/KnownColors.ios.cs index ccf20e6..8919efe 100644 --- a/System.Drawing/KnownColors.ios.cs +++ b/System.Drawing/KnownColors.ios.cs @@ -41,16 +41,15 @@ namespace System.Drawing internal static partial class KnownColors { - static void Update () - { - // note: Mono's SWF Theme class will call the static Update method to apply - // correct system colors outside Windows + static internal UIColor[] NativeColors = new UIColor[(int)KnownColor.WindowText + 1]; + static long FromSystemColor (KnownColor kc) + { + return ArgbValues[(int)kc]; } - static void WatchColorChanges () + static void Update () { - NSNotificationCenter.DefaultCenter.AddObserver (new NSString ("NSSystemColorsDidChangeNotification"), (obj) => { Update (); }); } } } diff --git a/System.Drawing/KnownColors.mac.cs b/System.Drawing/KnownColors.mac.cs index db32a9f..0c0430d 100644 --- a/System.Drawing/KnownColors.mac.cs +++ b/System.Drawing/KnownColors.mac.cs @@ -40,51 +40,82 @@ namespace System.Drawing internal static partial class KnownColors { + static internal NSColor[] NativeColors = new NSColor[(int)KnownColor.WindowText + 1]; + static void Update () { // note: Mono's SWF Theme class will call the static Update method to apply // correct system colors outside Windows - ArgbValues [(int)KnownColor.ActiveBorder] = NSColor.WindowFrame.ToUArgb (); + NativeColors[(int)KnownColor.ActiveBorder] = NSColor.WindowFrame; // KnownColor.ActiveCaption // KnownColor.ActiveCaptionText // KnownColor.AppWorkspace - ArgbValues [(int)KnownColor.Control] = NSColor.Control.ToUArgb (); - ArgbValues [(int)KnownColor.ControlText] = NSColor.ControlText.ToUArgb (); - ArgbValues [(int)KnownColor.ControlDark] = NSColor.ControlShadow.ToUArgb (); - ArgbValues [(int)KnownColor.ControlDarkDark] = NSColor.ControlDarkShadow.ToUArgb (); - ArgbValues [(int)KnownColor.ControlLight] = NSColor.ControlHighlight.ToUArgb (); - ArgbValues [(int)KnownColor.ControlLightLight] = NSColor.ControlLightHighlight.ToUArgb (); + NativeColors[(int)KnownColor.Control] = NSColor.Control; + NativeColors[(int)KnownColor.ControlText] = NSColor.ControlText; + NativeColors[(int)KnownColor.ControlDark] = NSColor.ControlShadow; + NativeColors[(int)KnownColor.ControlDarkDark] = NSColor.ControlDarkShadow; + NativeColors[(int)KnownColor.ControlLight] = NSColor.ControlHighlight; + NativeColors[(int)KnownColor.ControlLightLight] = NSColor.ControlLightHighlight; // KnownColor.Desktop - ArgbValues [(int)KnownColor.GrayText] = NSColor.DisabledControlText.ToUArgb (); + NativeColors[(int)KnownColor.GrayText] = NSColor.DisabledControlText; //ArgbValues[(int)KnownColor.Highlight] = NSColor.Highlight.ToUArgb(); - ArgbValues [(int)KnownColor.Highlight] = NSColor.SelectedTextBackground.ToUArgb (); - ArgbValues [(int)KnownColor.HighlightText] = NSColor.SelectedText.ToUArgb (); + NativeColors[(int)KnownColor.Highlight] = NSColor.SelectedTextBackground; + NativeColors[(int)KnownColor.HighlightText] = NSColor.SelectedText; // KnownColor.HighlightText // KnownColor.HotTrack // KnownColor.InactiveBorder // KnownColor.InactiveCaption // KnownColor.InactiveCaptionText - // KnownColor.Info - // KnownColor.InfoText + //NSColors[(int)KnownColor.Info] = NSColor.WindowBackground; + //NSColors[(int)KnownColor.InfoText] = NSColor.ControlText; // KnownColor.Menu // KnownColor.MenuText - ArgbValues [(int)KnownColor.ScrollBar] = NSColor.ScrollBar.ToUArgb (); - //ArgbValues[(int)KnownColor.Window] = NSColor.WindowBackground.ToUArgb(); - //ArgbValues[(int)KnownColor.WindowFrame] = NSColor.WindowFrame.ToUArgb(); - //ArgbValues[(int)KnownColor.WindowText] = NSColor.WindowFrameText.ToUArgb(); - ArgbValues [(int)KnownColor.ButtonFace] = NSColor.Control.ToUArgb (); - ArgbValues [(int)KnownColor.ButtonHighlight] = NSColor.ControlHighlight.ToUArgb (); - ArgbValues [(int)KnownColor.ButtonShadow] = NSColor.ControlShadow.ToUArgb (); + NativeColors[(int)KnownColor.ScrollBar] = NSColor.ScrollBar; + NativeColors[(int)KnownColor.Window] = NSColor.WindowBackground; + NativeColors[(int)KnownColor.WindowText] = NSColor.WindowFrameText; + NativeColors[(int)KnownColor.WindowFrame] = NSColor.WindowFrame; + NativeColors[(int)KnownColor.ButtonFace] = NSColor.Control; + NativeColors[(int)KnownColor.ButtonHighlight] = NSColor.ControlHighlight; + NativeColors[(int)KnownColor.ButtonShadow] = NSColor.ControlShadow; // KnownColor.GradientActiveCaption // KnownColor.GradientInactiveCaption // KnownColor.MenuBar // KnownColor.MenuHighlight } - static void WatchColorChanges () + static long ConvertComponent (nfloat c) { - NSNotificationCenter.DefaultCenter.AddObserver (new NSString ("NSSystemColorsDidChangeNotification"), (obj) => { Update (); }); + return (byte)(c * 255); + } + + static long FromSystemColor (KnownColor kc) + { + if (kc >= 0 && (int)kc <= NativeColors.Length && NativeColors[(int)kc] != null) { + nfloat r = 0, g = 0, b = 0, a = 0; + var rgba = NativeColors[(int)kc].UsingColorSpace (NSColorSpace.GenericRGBColorSpace); + if (rgba != null) { + rgba.GetRgba (out r, out g, out b, out a); + } else { + var cgc = NativeColors[(int)kc].CGColor; // 10.8+ + if (cgc != null) + { + // FIXME: CMYK, other color spaces? + if (cgc.NumberOfComponents == 4) { + a = (float)cgc.Components[3]; + r = (float)cgc.Components[0]; + g = (float)cgc.Components[1]; + b = (float)cgc.Components[2]; + } else if (cgc.NumberOfComponents == 2) { + a = (float)cgc.Components[1]; + r = g = b = (float)cgc.Components[0]; + } + } + } + return (ConvertComponent (a) << 24) + (ConvertComponent (r) << 16) + (ConvertComponent (g) << 8) + ConvertComponent (b); + } + + return ArgbValues[(int)kc]; } } } diff --git a/System.Drawing/SolidBrush.cs b/System.Drawing/SolidBrush.cs index 7cc3c56..74d04ed 100644 --- a/System.Drawing/SolidBrush.cs +++ b/System.Drawing/SolidBrush.cs @@ -60,10 +60,10 @@ internal override void Setup (Graphics graphics, bool fill) bool sourceCopy = graphics.CompositingMode == CompositingMode.SourceCopy; if (fill){ - graphics.context.SetFillColor(color.R / 255f, color.G/255f, color.B/255f, sourceCopy ? 1f : color.A/255f ); + graphics.context.SetFillColor (color.ToCGColor ()); } else { - graphics.context.SetStrokeColor(color.R / 255f, color.G/255f, color.B/255f, sourceCopy ? 1f : color.A/255f ); + graphics.context.SetStrokeColor (color.ToCGColor ()); } graphics.LastBrush = this; @@ -73,7 +73,7 @@ internal override void Setup (Graphics graphics, bool fill) graphics.lastBrushColor = color; } - public override bool Equals(object obj) + public override bool Equals(object obj) { return (obj is SolidBrush sb) && color.Equals(sb.Color); } diff --git a/Utilities/ConversionHelpers.cs b/Utilities/ConversionHelpers.cs index eb7395e..4b1675f 100644 --- a/Utilities/ConversionHelpers.cs +++ b/Utilities/ConversionHelpers.cs @@ -87,8 +87,21 @@ internal static RectangleF ToRectangleF (this Rectangle rect) } internal static CGColor ToCGColor (this Color color) - { - return new CGColor(color.R / 255f, color.G/255f, color.B/255f, color.A/255f ); + { + if (color.IsSystemColor) { + var knownColor = color.ToKnownColor (); + if (knownColor >= 0 && (int)knownColor < KnownColors.NativeColors.Length && KnownColors.NativeColors[(int)knownColor] != null) { + return KnownColors.NativeColors[(int)knownColor].CGColor; + } + } + + long value = color.Value; + byte a = (byte) (value >> 24); + byte r = (byte) (value >> 16); + byte g = (byte) (value >> 8); + byte b = (byte) (value); + + return new CGColor(r / 255f, g / 255f, b / 255f, a / 255f); } internal static float ToRadians (this float degrees)