// // System.Drawing.Color.cs // // Authors: // Dennis Hayes (dennish@raytek.com) // Ben Houston (ben@exocortex.org) // Gonzalo Paniagua (gonzalo@ximian.com) // Juraj Skripsky (juraj@hotfeet.ch) // Sebastien Pouliot // // (C) 2002 Dennis Hayes // (c) 2002 Ximian, Inc. (http://www.ximiam.com) // (C) 2005 HotFeet GmbH (http://www.hotfeet.ch) // Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System.ComponentModel; using System.Runtime.InteropServices; namespace System.Drawing { #if !MONOTOUCH && !MONOMAC && FEATURE_TYPECONVERTER [TypeConverter(typeof(ColorConverter))] [Editor ("System.Drawing.Design.ColorEditor, " + Consts.AssemblySystem_Drawing_Design, typeof (System.Drawing.Design.UITypeEditor))] #endif [Serializable] public struct Color { // Private transparency (A) and R,G,B fields. private long value; // The specs also indicate that all three of these properties are true // if created with FromKnownColor or FromNamedColor, false otherwise (FromARGB). // Per Microsoft and ECMA specs these varibles are set by which constructor is used, not by their values. [Flags] internal enum ColorType : short { Empty=0, Known=1, ARGB=2, Named=4, System=8 } internal short state; internal short knownColor; // #if ONLY_1_1 // Mono bug #324144 is holding this change // MS 1.1 requires this member to be present for serialization (not so in 2.0) // however it's bad to keep a string (reference) in a struct internal string name; // #endif public string Name { get { #if NET_2_0_ONCE_MONO_BUG_324144_IS_FIXED if (IsNamedColor) return KnownColors.GetName (knownColor); else return String.Format ("{0:x}", ToArgb ()); #else // name is required for serialization under 1.x, but not under 2.0 if (name == null) { // Can happen with stuff deserialized from MS if (IsNamedColor) name = KnownColors.GetName (knownColor); else name = String.Format ("{0:x}", ToArgb ()); } return name; #endif } } public bool IsKnownColor { get{ return (state & ((short) ColorType.Known)) != 0; } } public bool IsSystemColor { get{ return (state & ((short) ColorType.System)) != 0; } } public bool IsNamedColor { get{ return (state & (short)(ColorType.Known|ColorType.Named)) != 0; } } internal long Value { get { // Optimization for known colors that were deserialized // from an MS serialized stream. if (value == 0 && IsKnownColor) { value = FromKnownColor ((KnownColor)knownColor).ToArgb () & 0xFFFFFFFF; } return value; } set { this.value = value; } } public static Color FromArgb (int red, int green, int blue) { return FromArgb (255, red, green, blue); } public static Color FromArgb (int alpha, int red, int green, int blue) { CheckARGBValues (alpha, red, green, blue); Color color = new Color (); color.state = (short) ColorType.ARGB; color.Value = (int)((uint) alpha << 24) + (red << 16) + (green << 8) + blue; return color; } public int ToArgb() { return (int) Value; } public static Color FromArgb (int alpha, Color baseColor) { return FromArgb (alpha, baseColor.R, baseColor.G, baseColor.B); } public static Color FromArgb (int argb) { return FromArgb ((argb >> 24) & 0x0FF, (argb >> 16) & 0x0FF, (argb >> 8) & 0x0FF, argb & 0x0FF); } public static Color FromKnownColor (KnownColor color) { Color c; short n = (short)color; if ((n <= 0) || (n >= KnownColors.ArgbValues.Length)) { // This is what it returns! c = FromArgb (0, 0, 0, 0); c.state |= (short) ColorType.Named; } else { c = new Color (); c.state = (short) (ColorType.ARGB | ColorType.Known | ColorType.Named); if ((n < 27) || (n > 169)) c.state |= (short) ColorType.System; c.Value = KnownColors.ArgbValues [n]; } c.knownColor = n; return c; } public static Color FromName (string name) { try { KnownColor kc = (KnownColor) Enum.Parse (typeof (KnownColor), name, true); return FromKnownColor (kc); } catch { // This is what it returns! Color d = FromArgb (0, 0, 0, 0); d.name = name; d.state |= (short) ColorType.Named; return d; } } // ----------------------- // Public Shared Members // ----------------------- /// /// Empty Shared Field /// /// /// /// An uninitialized Color Structure /// public static readonly Color Empty; /// /// Equality Operator /// /// /// /// Compares two Color objects. The return value is /// based on the equivalence of the A,R,G,B properties /// of the two Colors. /// public static bool operator == (Color left, Color right) { if (left.Value != right.Value) return false; if (left.IsNamedColor != right.IsNamedColor) return false; if (left.IsSystemColor != right.IsSystemColor) return false; if (left.IsEmpty != right.IsEmpty) return false; if (left.IsNamedColor) { // then both are named (see previous check) and so we need to compare them // but otherwise we don't as it kills performance (Name calls String.Format) if (left.Name != right.Name) return false; } return true; } /// /// Inequality Operator /// /// /// /// Compares two Color objects. The return value is /// based on the equivalence of the A,R,G,B properties /// of the two colors. /// public static bool operator != (Color left, Color right) { return ! (left == right); } public float GetBrightness () { byte minval = Math.Min (R, Math.Min (G, B)); byte 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)); if (maxval == minval) return 0.0f; int sum = maxval + minval; if (sum > 255) sum = 510 - sum; return (float)(maxval - minval) / sum; } public float GetHue () { int r = R; int g = G; int b = B; byte minval = (byte) Math.Min (r, Math.Min (g, b)); byte maxval = (byte) Math.Max (r, Math.Max (g, b)); if (maxval == minval) return 0.0f; float diff = (float)(maxval - minval); float rnorm = (maxval - r) / diff; float gnorm = (maxval - g) / diff; float bnorm = (maxval - b) / diff; float hue = 0.0f; if (r == maxval) hue = 60.0f * (6.0f + bnorm - gnorm); if (g == maxval) hue = 60.0f * (2.0f + rnorm - bnorm); if (b == maxval) hue = 60.0f * (4.0f + gnorm - rnorm); if (hue > 360.0f) hue = hue - 360.0f; return hue; } // ----------------------- // Public Instance Members // ----------------------- /// /// ToKnownColor method /// /// /// /// Returns the KnownColor enum value for this color, 0 if is not known. /// public KnownColor ToKnownColor () { return (KnownColor) knownColor; } /// /// IsEmpty Property /// /// /// /// Indicates transparent black. R,G,B = 0; A=0? /// public bool IsEmpty { get { return state == (short) ColorType.Empty; } } public byte A { get { return (byte) (Value >> 24); } } public byte R { get { return (byte) (Value >> 16); } } public byte G { get { return (byte) (Value >> 8); } } public byte B { get { return (byte) Value; } } /// /// Equals Method /// /// /// /// Checks equivalence of this Color and another object. /// public override bool Equals (object obj) { if (!(obj is Color)) return false; Color c = (Color) obj; return this == c; } /// /// Reference Equals Method /// Is commented out because this is handled by the base class. /// TODO: Is it correct to let the base class handel reference equals /// /// /// /// Checks equivalence of this Color and another object. /// //public bool ReferenceEquals (object o) //{ // if (!(o is Color))return false; // return (this == (Color) o); //} /// /// GetHashCode Method /// /// /// /// Calculates a hashing value. /// public override int GetHashCode () { int hc = (int)(Value ^ (Value >> 32) ^ state ^ (knownColor >> 16)); if (IsNamedColor) hc ^= Name.GetHashCode (); return hc; } /// /// ToString Method /// /// /// /// Formats the Color as a string in ARGB notation. /// public override string ToString () { if (IsEmpty) return "Color [Empty]"; // Use the property here, not the field. if (IsNamedColor) return "Color [" + Name + "]"; return String.Format ("Color [A={0}, R={1}, G={2}, B={3}]", A, R, G, B); } private static void CheckRGBValues (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"); } private static ArgumentException CreateColorArgumentException (int value, string color) { return new ArgumentException (string.Format ("'{0}' is not a valid" + " value for '{1}'. '{1}' should be greater or equal to 0 and" + " less than or equal to 255.", value, color)); } private static void CheckARGBValues (int alpha,int red,int green,int blue) { if( (alpha > 255) || (alpha < 0)) throw CreateColorArgumentException (alpha, "alpha"); CheckRGBValues(red,green,blue); } static public Color Transparent { get { return FromKnownColor (KnownColor.Transparent); } } static public Color AliceBlue { get { return FromKnownColor (KnownColor.AliceBlue); } } static public Color AntiqueWhite { get { return FromKnownColor (KnownColor.AntiqueWhite); } } static public Color Aqua { get { return FromKnownColor (KnownColor.Aqua); } } static public Color Aquamarine { get { return FromKnownColor (KnownColor.Aquamarine); } } static public Color Azure { get { return FromKnownColor (KnownColor.Azure); } } static public Color Beige { get { return FromKnownColor (KnownColor.Beige); } } static public Color Bisque { get { return FromKnownColor (KnownColor.Bisque); } } static public Color Black { get { return FromKnownColor (KnownColor.Black); } } static public Color BlanchedAlmond { get { return FromKnownColor (KnownColor.BlanchedAlmond); } } static public Color Blue { get { return FromKnownColor (KnownColor.Blue); } } static public Color BlueViolet { get { return FromKnownColor (KnownColor.BlueViolet); } } static public Color Brown { get { return FromKnownColor (KnownColor.Brown); } } static public Color BurlyWood { get { return FromKnownColor (KnownColor.BurlyWood); } } static public Color CadetBlue { get { return FromKnownColor (KnownColor.CadetBlue); } } static public Color Chartreuse { get { return FromKnownColor (KnownColor.Chartreuse); } } static public Color Chocolate { get { return FromKnownColor (KnownColor.Chocolate); } } static public Color Coral { get { return FromKnownColor (KnownColor.Coral); } } static public Color CornflowerBlue { get { return FromKnownColor (KnownColor.CornflowerBlue); } } static public Color Cornsilk { get { return FromKnownColor (KnownColor.Cornsilk); } } static public Color Crimson { get { return FromKnownColor (KnownColor.Crimson); } } static public Color Cyan { get { return FromKnownColor (KnownColor.Cyan); } } static public Color DarkBlue { get { return FromKnownColor (KnownColor.DarkBlue); } } static public Color DarkCyan { get { return FromKnownColor (KnownColor.DarkCyan); } } static public Color DarkGoldenrod { get { return FromKnownColor (KnownColor.DarkGoldenrod); } } static public Color DarkGray { get { return FromKnownColor (KnownColor.DarkGray); } } static public Color DarkGreen { get { return FromKnownColor (KnownColor.DarkGreen); } } static public Color DarkKhaki { get { return FromKnownColor (KnownColor.DarkKhaki); } } static public Color DarkMagenta { get { return FromKnownColor (KnownColor.DarkMagenta); } } static public Color DarkOliveGreen { get { return FromKnownColor (KnownColor.DarkOliveGreen); } } static public Color DarkOrange { get { return FromKnownColor (KnownColor.DarkOrange); } } static public Color DarkOrchid { get { return FromKnownColor (KnownColor.DarkOrchid); } } static public Color DarkRed { get { return FromKnownColor (KnownColor.DarkRed); } } static public Color DarkSalmon { get { return FromKnownColor (KnownColor.DarkSalmon); } } static public Color DarkSeaGreen { get { return FromKnownColor (KnownColor.DarkSeaGreen); } } static public Color DarkSlateBlue { get { return FromKnownColor (KnownColor.DarkSlateBlue); } } static public Color DarkSlateGray { get { return FromKnownColor (KnownColor.DarkSlateGray); } } static public Color DarkTurquoise { get { return FromKnownColor (KnownColor.DarkTurquoise); } } static public Color DarkViolet { get { return FromKnownColor (KnownColor.DarkViolet); } } static public Color DeepPink { get { return FromKnownColor (KnownColor.DeepPink); } } static public Color DeepSkyBlue { get { return FromKnownColor (KnownColor.DeepSkyBlue); } } static public Color DimGray { get { return FromKnownColor (KnownColor.DimGray); } } static public Color DodgerBlue { get { return FromKnownColor (KnownColor.DodgerBlue); } } static public Color Firebrick { get { return FromKnownColor (KnownColor.Firebrick); } } static public Color FloralWhite { get { return FromKnownColor (KnownColor.FloralWhite); } } static public Color ForestGreen { get { return FromKnownColor (KnownColor.ForestGreen); } } static public Color Fuchsia { get { return FromKnownColor (KnownColor.Fuchsia); } } static public Color Gainsboro { get { return FromKnownColor (KnownColor.Gainsboro); } } static public Color GhostWhite { get { return FromKnownColor (KnownColor.GhostWhite); } } static public Color Gold { get { return FromKnownColor (KnownColor.Gold); } } static public Color Goldenrod { get { return FromKnownColor (KnownColor.Goldenrod); } } static public Color Gray { get { return FromKnownColor (KnownColor.Gray); } } static public Color Green { get { return FromKnownColor (KnownColor.Green); } } static public Color GreenYellow { get { return FromKnownColor (KnownColor.GreenYellow); } } static public Color Honeydew { get { return FromKnownColor (KnownColor.Honeydew); } } static public Color HotPink { get { return FromKnownColor (KnownColor.HotPink); } } static public Color IndianRed { get { return FromKnownColor (KnownColor.IndianRed); } } static public Color Indigo { get { return FromKnownColor (KnownColor.Indigo); } } static public Color Ivory { get { return FromKnownColor (KnownColor.Ivory); } } static public Color Khaki { get { return FromKnownColor (KnownColor.Khaki); } } static public Color Lavender { get { return FromKnownColor (KnownColor.Lavender); } } static public Color LavenderBlush { get { return FromKnownColor (KnownColor.LavenderBlush); } } static public Color LawnGreen { get { return FromKnownColor (KnownColor.LawnGreen); } } static public Color LemonChiffon { get { return FromKnownColor (KnownColor.LemonChiffon); } } static public Color LightBlue { get { return FromKnownColor (KnownColor.LightBlue); } } static public Color LightCoral { get { return FromKnownColor (KnownColor.LightCoral); } } static public Color LightCyan { get { return FromKnownColor (KnownColor.LightCyan); } } static public Color LightGoldenrodYellow { get { return FromKnownColor (KnownColor.LightGoldenrodYellow); } } static public Color LightGreen { get { return FromKnownColor (KnownColor.LightGreen); } } static public Color LightGray { get { return FromKnownColor (KnownColor.LightGray); } } static public Color LightPink { get { return FromKnownColor (KnownColor.LightPink); } } static public Color LightSalmon { get { return FromKnownColor (KnownColor.LightSalmon); } } static public Color LightSeaGreen { get { return FromKnownColor (KnownColor.LightSeaGreen); } } static public Color LightSkyBlue { get { return FromKnownColor (KnownColor.LightSkyBlue); } } static public Color LightSlateGray { get { return FromKnownColor (KnownColor.LightSlateGray); } } static public Color LightSteelBlue { get { return FromKnownColor (KnownColor.LightSteelBlue); } } static public Color LightYellow { get { return FromKnownColor (KnownColor.LightYellow); } } static public Color Lime { get { return FromKnownColor (KnownColor.Lime); } } static public Color LimeGreen { get { return FromKnownColor (KnownColor.LimeGreen); } } static public Color Linen { get { return FromKnownColor (KnownColor.Linen); } } static public Color Magenta { get { return FromKnownColor (KnownColor.Magenta); } } static public Color Maroon { get { return FromKnownColor (KnownColor.Maroon); } } static public Color MediumAquamarine { get { return FromKnownColor (KnownColor.MediumAquamarine); } } static public Color MediumBlue { get { return FromKnownColor (KnownColor.MediumBlue); } } static public Color MediumOrchid { get { return FromKnownColor (KnownColor.MediumOrchid); } } static public Color MediumPurple { get { return FromKnownColor (KnownColor.MediumPurple); } } static public Color MediumSeaGreen { get { return FromKnownColor (KnownColor.MediumSeaGreen); } } static public Color MediumSlateBlue { get { return FromKnownColor (KnownColor.MediumSlateBlue); } } static public Color MediumSpringGreen { get { return FromKnownColor (KnownColor.MediumSpringGreen); } } static public Color MediumTurquoise { get { return FromKnownColor (KnownColor.MediumTurquoise); } } static public Color MediumVioletRed { get { return FromKnownColor (KnownColor.MediumVioletRed); } } static public Color MidnightBlue { get { return FromKnownColor (KnownColor.MidnightBlue); } } static public Color MintCream { get { return FromKnownColor (KnownColor.MintCream); } } static public Color MistyRose { get { return FromKnownColor (KnownColor.MistyRose); } } static public Color Moccasin { get { return FromKnownColor (KnownColor.Moccasin); } } static public Color NavajoWhite { get { return FromKnownColor (KnownColor.NavajoWhite); } } static public Color Navy { get { return FromKnownColor (KnownColor.Navy); } } static public Color OldLace { get { return FromKnownColor (KnownColor.OldLace); } } static public Color Olive { get { return FromKnownColor (KnownColor.Olive); } } static public Color OliveDrab { get { return FromKnownColor (KnownColor.OliveDrab); } } static public Color Orange { get { return FromKnownColor (KnownColor.Orange); } } static public Color OrangeRed { get { return FromKnownColor (KnownColor.OrangeRed); } } static public Color Orchid { get { return FromKnownColor (KnownColor.Orchid); } } static public Color PaleGoldenrod { get { return FromKnownColor (KnownColor.PaleGoldenrod); } } static public Color PaleGreen { get { return FromKnownColor (KnownColor.PaleGreen); } } static public Color PaleTurquoise { get { return FromKnownColor (KnownColor.PaleTurquoise); } } static public Color PaleVioletRed { get { return FromKnownColor (KnownColor.PaleVioletRed); } } static public Color PapayaWhip { get { return FromKnownColor (KnownColor.PapayaWhip); } } static public Color PeachPuff { get { return FromKnownColor (KnownColor.PeachPuff); } } static public Color Peru { get { return FromKnownColor (KnownColor.Peru); } } static public Color Pink { get { return FromKnownColor (KnownColor.Pink); } } static public Color Plum { get { return FromKnownColor (KnownColor.Plum); } } static public Color PowderBlue { get { return FromKnownColor (KnownColor.PowderBlue); } } static public Color Purple { get { return FromKnownColor (KnownColor.Purple); } } static public Color Red { get { return FromKnownColor (KnownColor.Red); } } static public Color RosyBrown { get { return FromKnownColor (KnownColor.RosyBrown); } } static public Color RoyalBlue { get { return FromKnownColor (KnownColor.RoyalBlue); } } static public Color SaddleBrown { get { return FromKnownColor (KnownColor.SaddleBrown); } } static public Color Salmon { get { return FromKnownColor (KnownColor.Salmon); } } static public Color SandyBrown { get { return FromKnownColor (KnownColor.SandyBrown); } } static public Color SeaGreen { get { return FromKnownColor (KnownColor.SeaGreen); } } static public Color SeaShell { get { return FromKnownColor (KnownColor.SeaShell); } } static public Color Sienna { get { return FromKnownColor (KnownColor.Sienna); } } static public Color Silver { get { return FromKnownColor (KnownColor.Silver); } } static public Color SkyBlue { get { return FromKnownColor (KnownColor.SkyBlue); } } static public Color SlateBlue { get { return FromKnownColor (KnownColor.SlateBlue); } } static public Color SlateGray { get { return FromKnownColor (KnownColor.SlateGray); } } static public Color Snow { get { return FromKnownColor (KnownColor.Snow); } } static public Color SpringGreen { get { return FromKnownColor (KnownColor.SpringGreen); } } static public Color SteelBlue { get { return FromKnownColor (KnownColor.SteelBlue); } } static public Color Tan { get { return FromKnownColor (KnownColor.Tan); } } static public Color Teal { get { return FromKnownColor (KnownColor.Teal); } } static public Color Thistle { get { return FromKnownColor (KnownColor.Thistle); } } static public Color Tomato { get { return FromKnownColor (KnownColor.Tomato); } } static public Color Turquoise { get { return FromKnownColor (KnownColor.Turquoise); } } static public Color Violet { get { return FromKnownColor (KnownColor.Violet); } } static public Color Wheat { get { return FromKnownColor (KnownColor.Wheat); } } static public Color White { get { return FromKnownColor (KnownColor.White); } } static public Color WhiteSmoke { get { return FromKnownColor (KnownColor.WhiteSmoke); } } static public Color Yellow { get { return FromKnownColor (KnownColor.Yellow); } } static public Color YellowGreen { get { return FromKnownColor (KnownColor.YellowGreen); } } } }