**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Drawing / System.Drawing / ColorConverter.cs
blob900af938d4cf7bf6040b0adcc28e318b54d33608
1 //
2 // System.Drawing.ColorConverter
3 //
4 // Authors:
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Ravindra (rkumar@novell.com)
7 //
8 // Copyright (C) 2002 Ximian, Inc. http://www.ximian.com
9 // Copyright (C) 2004 Novell, Inc. http://www.novell.com
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System;
36 using System.Collections;
37 using System.ComponentModel;
38 using System.Globalization;
39 using System.Text;
41 namespace System.Drawing
43 public class ColorConverter : TypeConverter
45 static StandardValuesCollection cached;
46 static object creatingCached = new object ();
48 public ColorConverter () { }
50 public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
52 if (sourceType == typeof (string))
53 return true;
55 return base.CanConvertFrom (context, sourceType);
58 public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
60 if (destinationType == typeof (String))
61 return true;
63 return base.CanConvertTo (context, destinationType);
66 public override object ConvertFrom (ITypeDescriptorContext context,
67 CultureInfo culture,
68 object value)
70 string s = value as string;
71 if (s == null)
72 return base.ConvertFrom (context, culture, value);
74 object named = Color.NamedColors [s];
75 if (named != null)
76 return (Color) named;
78 named = Color.SystemColors [s];
79 if (named != null)
80 return (Color) named;
82 String numSeparator = culture.NumberFormat.NumberGroupSeparator;
84 int A, R, G, B;
85 if (s.IndexOf (numSeparator) > 0) { // "A, R, G, B" format
86 String [] components = s.Split (numSeparator.ToCharArray ());
87 if (components.Length == 3) {
88 A = 255;
89 R = GetNumber (components [0].Trim ());
90 G = GetNumber (components [1].Trim ());
91 B = GetNumber (components [2].Trim ());
93 else if (components.Length == 4) {
94 A = GetNumber (components [0].Trim ());
95 R = GetNumber (components [1].Trim ());
96 G = GetNumber (components [2].Trim ());
97 B = GetNumber (components [3].Trim ());
99 else
100 throw new ArgumentException (s + " is not a valid color value.");
102 else { // #RRGGBB format
103 int i = GetNumber (s.Trim ());
104 A = (int) (i >> 24) & 0xFF;
105 if (A == 0)
106 A = 255;
107 R = (i >> 16) & 0xFF;
108 G = (i >> 8) & 0xFF;
109 B = i & 0xFF;
112 Color result = Color.FromArgb (A, R, G, B);
113 // Look for a named or system color with those values
114 foreach (Color c in Color.NamedColors.Values) {
115 if (c == result)
116 return c;
119 foreach (Color c in Color.SystemColors.Values) {
120 if (c == result)
121 return c;
124 return result;
127 public override object ConvertTo (ITypeDescriptorContext context,
128 CultureInfo culture,
129 object value,
130 Type destinationType)
132 if ((destinationType == typeof (string)) && (value is Color)) {
133 Color color = (Color) value;
134 StringBuilder sb = new StringBuilder ();
135 sb.Append (color.A); sb.Append (", ");
136 sb.Append (color.R); sb.Append (", ");
137 sb.Append (color.G); sb.Append (", ");
138 sb.Append (color.B);
139 return sb.ToString ();
142 return base.ConvertTo (context, culture, value, destinationType);
145 public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context)
147 if (cached != null)
148 return cached;
150 lock (creatingCached)
152 if (cached != null)
153 return cached;
155 ICollection named = (ICollection) Color.NamedColors.Values;
156 ICollection system = (ICollection) Color.SystemColors.Values;
157 Array colors = Array.CreateInstance (typeof (Color), named.Count + system.Count);
158 named.CopyTo (colors, 0);
159 system.CopyTo (colors, named.Count);
160 Array.Sort (colors, 0, colors.Length, new CompareColors ());
161 cached = new StandardValuesCollection (colors);
164 return cached;
167 public override bool GetStandardValuesSupported (ITypeDescriptorContext context)
169 return true;
172 private int GetNumber (String str)
174 int number;
176 if (str.StartsWith ("#0x") || str.StartsWith ("#0X"))
177 // #0xRRGGBB format. Parse hex string.
178 number = Int32.Parse (str.Substring (3), NumberStyles.HexNumber);
180 else if (str [0] == '#')
181 // #RRGGBB format. Parse hex string.
182 number = Int32.Parse (str.Substring (1), NumberStyles.HexNumber);
184 else if (str.StartsWith ("0x") || str.StartsWith ("0X"))
185 // 0xRRGGBB format. Parse hex string.
186 number = Int32.Parse (str.Substring (2), NumberStyles.HexNumber);
188 else // if (str [0] == '-' || str [0] == '+' || Char.IsDigit (str [0]))
189 // [+/-]RRGGBB format. Parse decimal string.
190 number = Int32.Parse (str, NumberStyles.Integer);
192 return number;
195 class CompareColors : IComparer
197 public int Compare (object x, object y)
199 return String.Compare (((Color) x).Name, ((Color) y).Name);