~ubuntu-branches/ubuntu/karmic/moon/karmic

« back to all changes in this revision

Viewing changes to src/color.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-14 12:01:08 UTC
  • Revision ID: james.westby@ubuntu.com-20090214120108-06539vb25vhbd8bn
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * color.cpp: Colors
 
3
 *
 
4
 * Contact:
 
5
 *   Moonlight List (moonlight-list@lists.ximian.com)
 
6
 *
 
7
 * Copyright 2007 Novell, Inc. (http://www.novell.com)
 
8
 *
 
9
 * See the LICENSE file included with the distribution for details.
 
10
 * 
 
11
 */
 
12
 
 
13
#include <config.h>
 
14
#include <string.h>
 
15
#include <stdlib.h>
 
16
#include <math.h>
 
17
 
 
18
#include "color.h"
 
19
 
 
20
// match System.Windows.Media.Colors properties
 
21
typedef struct {
 
22
        const char *name;
 
23
        const unsigned int color;
 
24
} named_colors_t;
 
25
 
 
26
named_colors_t named_colors [] = {
 
27
        // NOTE: samples shows that XAML supports more than the colors defined in System.Windows.Media.Colors
 
28
        // in fact tests shows that all System.Drawing.Color seems to be available
 
29
        { "transparent",                0x00FFFFFF },
 
30
        { "aliceblue",                  0xFFF0F8FF },
 
31
        { "antiquewhite",               0xFFFAEBD7 },
 
32
        { "aqua",                       0xFF00FFFF },
 
33
        { "aquamarine",                 0xFF7FFFD4 },
 
34
        { "azure",                      0xFFF0FFFF },
 
35
        { "beige",                      0xFFF5F5DC },
 
36
        { "bisque",                     0xFFFFE4C4 },
 
37
        { "black",                      0xFF000000 },
 
38
        { "blanchedalmond",             0xFFFFEBCD },
 
39
        { "blue",                       0xFF0000FF },
 
40
        { "blueviolet",                 0xFF8A2BE2 },
 
41
        { "brown",                      0xFFA52A2A },
 
42
        { "burlywood",                  0xFFDEB887 },
 
43
        { "cadetblue",                  0xFF5F9EA0 },
 
44
        { "chartreuse",                 0xFF7FFF00 },
 
45
        { "chocolate",                  0xFFD2691E },
 
46
        { "coral",                      0xFFFF7F50 },
 
47
        { "cornflowerblue",             0xFF6495ED },
 
48
        { "cornsilk",                   0xFFFFF8DC },
 
49
        { "crimson",                    0xFFDC143C },
 
50
        { "cyan",                       0xFF00FFFF },
 
51
        { "darkblue",                   0xFF00008B },
 
52
        { "darkcyan",                   0xFF008B8B },
 
53
        { "darkgoldenrod",              0xFFB8860B },
 
54
        { "darkgray",                   0xFFA9A9A9 },
 
55
        { "darkgreen",                  0xFF006400 },
 
56
        { "darkkhaki",                  0xFFBDB76B },
 
57
        { "darkmagenta",                0xFF8B008B },
 
58
        { "darkolivegreen",             0xFF556B2F },
 
59
        { "darkorange",                 0xFFFF8C00 },
 
60
        { "darkorchid",                 0xFF9932CC },
 
61
        { "darkred",                    0xFF8B0000 },
 
62
        { "darksalmon",                 0xFFE9967A },
 
63
        { "darkseagreen",               0xFF8FBC8B },
 
64
        { "darkslateblue",              0xFF483D8B },
 
65
        { "darkslategray",              0xFF2F4F4F },
 
66
        { "darkturquoise",              0xFF00CED1 },
 
67
        { "darkviolet",                 0xFF9400D3 },
 
68
        { "deeppink",                   0xFFFF1493 },
 
69
        { "deepskyblue",                0xFF00BFFF },
 
70
        { "dimgray",                    0xFF696969 },
 
71
        { "dodgerblue",                 0xFF1E90FF },
 
72
        { "firebrick",                  0xFFB22222 },
 
73
        { "floralwhite",                0xFFFFFAF0 },
 
74
        { "forestgreen",                0xFF228B22 },
 
75
        { "fuchsia",                    0xFFFF00FF },
 
76
        { "gainsboro",                  0xFFDCDCDC },
 
77
        { "ghostwhite",                 0xFFF8F8FF },
 
78
        { "gold",                       0xFFFFD700 },
 
79
        { "goldenrod",                  0xFFDAA520 },
 
80
        { "gray",                       0xFF808080 },
 
81
        { "green",                      0xFF008000 },
 
82
        { "greenyellow",                0xFFADFF2F },
 
83
        { "honeydew",                   0xFFF0FFF0 },
 
84
        { "hotpink",                    0xFFFF69B4 },
 
85
        { "indianred",                  0xFFCD5C5C },
 
86
        { "indigo",                     0xFF4B0082 },
 
87
        { "ivory",                      0xFFFFFFF0 },
 
88
        { "khaki",                      0xFFF0E68C },
 
89
        { "lavender",                   0xFFE6E6FA },
 
90
        { "lavenderblush",              0xFFFFF0F5 },
 
91
        { "lawngreen",                  0xFF7CFC00 },
 
92
        { "lemonchiffon",               0xFFFFFACD },
 
93
        { "lightblue",                  0xFFADD8E6 },
 
94
        { "lightcoral",                 0xFFF08080 },
 
95
        { "lightcyan",                  0xFFE0FFFF },
 
96
        { "lightgoldenrodyellow",       0xFFFAFAD2 },
 
97
        { "lightgreen",                 0xFF90EE90 },
 
98
        { "lightgray",                  0xFFD3D3D3 },
 
99
        { "lightpink",                  0xFFFFB6C1 },
 
100
        { "lightsalmon",                0xFFFFA07A },
 
101
        { "lightseagreen",              0xFF20B2AA },
 
102
        { "lightskyblue",               0xFF87CEFA },
 
103
        { "lightslategray",             0xFF778899 },
 
104
        { "lightsteelblue",             0xFFB0C4DE },
 
105
        { "lightyellow",                0xFFFFFFE0 },
 
106
        { "lime",                       0xFF00FF00 },
 
107
        { "limegreen",                  0xFF32CD32 },
 
108
        { "linen",                      0xFFFAF0E6 },
 
109
        { "magenta",                    0xFFFF00FF },
 
110
        { "maroon",                     0xFF800000 },
 
111
        { "mediumaquamarine",           0xFF66CDAA },
 
112
        { "mediumblue",                 0xFF0000CD },
 
113
        { "mediumorchid",               0xFFBA55D3 },
 
114
        { "mediumpurple",               0xFF9370DB },
 
115
        { "mediumseagreen",             0xFF3CB371 },
 
116
        { "mediumslateblue",            0xFF7B68EE },
 
117
        { "mediumspringgreen",          0xFF00FA9A },
 
118
        { "mediumturquoise",            0xFF48D1CC },
 
119
        { "mediumvioletred",            0xFFC71585 },
 
120
        { "midnightblue",               0xFF191970 },
 
121
        { "mintcream",                  0xFFF5FFFA },
 
122
        { "mistyrose",                  0xFFFFE4E1 },
 
123
        { "moccasin",                   0xFFFFE4B5 },
 
124
        { "navajowhite",                0xFFFFDEAD },
 
125
        { "navy",                       0xFF000080 },
 
126
        { "oldlace",                    0xFFFDF5E6 },
 
127
        { "olive",                      0xFF808000 },
 
128
        { "olivedrab",                  0xFF6B8E23 },
 
129
        { "orange",                     0xFFFFA500 },
 
130
        { "orangered",                  0xFFFF4500 },
 
131
        { "orchid",                     0xFFDA70D6 },
 
132
        { "palegoldenrod",              0xFFEEE8AA },
 
133
        { "palegreen",                  0xFF98FB98 },
 
134
        { "paleturquoise",              0xFFAFEEEE },
 
135
        { "palevioletred",              0xFFDB7093 },
 
136
        { "papayawhip",                 0xFFFFEFD5 },
 
137
        { "peachpuff",                  0xFFFFDAB9 },
 
138
        { "peru",                       0xFFCD853F },
 
139
        { "pink",                       0xFFFFC0CB },
 
140
        { "plum",                       0xFFDDA0DD },
 
141
        { "powderblue",                 0xFFB0E0E6 },
 
142
        { "purple",                     0xFF800080 },
 
143
        { "red",                        0xFFFF0000 },
 
144
        { "rosybrown",                  0xFFBC8F8F },
 
145
        { "royalblue",                  0xFF4169E1 },
 
146
        { "saddlebrown",                0xFF8B4513 },
 
147
        { "salmon",                     0xFFFA8072 },
 
148
        { "sandybrown",                 0xFFF4A460 },
 
149
        { "seagreen",                   0xFF2E8B57 },
 
150
        { "seashell",                   0xFFFFF5EE },
 
151
        { "sienna",                     0xFFA0522D },
 
152
        { "silver",                     0xFFC0C0C0 },
 
153
        { "skyblue",                    0xFF87CEEB },
 
154
        { "slateblue",                  0xFF6A5ACD },
 
155
        { "slategray",                  0xFF708090 },
 
156
        { "snow",                       0xFFFFFAFA },
 
157
        { "springgreen",                0xFF00FF7F },
 
158
        { "steelblue",                  0xFF4682B4 },
 
159
        { "tan",                        0xFFD2B48C },
 
160
        { "teal",                       0xFF008080 },
 
161
        { "thistle",                    0xFFD8BFD8 },
 
162
        { "tomato",                     0xFFFF6347 },
 
163
        { "turquoise",                  0xFF40E0D0 },
 
164
        { "violet",                     0xFFEE82EE },
 
165
        { "wheat",                      0xFFF5DEB3 },
 
166
        { "white",                      0xFFFFFFFF },
 
167
        { "whitesmoke",                 0xFFF5F5F5 },
 
168
        { "yellow",                     0xFFFFFF00 },
 
169
        { "yellowgreen",                0xFF9ACD32 },
 
170
        { NULL, 0 }
 
171
};
 
172
 
 
173
/* Safely read next double from string checking for NULL's
 
174
 * etc. Returns 0.0 if can't read. Modifies passed str to point
 
175
 * at next character after the coma (,) following the number
 
176
 * (if it makes sense). */
 
177
static double
 
178
read_next_double (char **str)
 
179
{
 
180
        if (str == NULL)
 
181
                return 0.0;
 
182
 
 
183
        char *iter = *str;
 
184
 
 
185
        if (iter) {
 
186
                double v = strtod (iter, &iter);
 
187
                if (iter)
 
188
                        iter = strchr (iter, ',');
 
189
                if (iter)
 
190
                        iter++;
 
191
                *str = iter;
 
192
                return v;
 
193
        } else {
 
194
                return 0.0;
 
195
        }
 
196
}
 
197
 
 
198
/**
 
199
 * see: http://msdn2.microsoft.com/en-us/library/system.windows.media.solidcolorbrush.aspx
 
200
 *
 
201
 * If no color is found, NULL is returned.
 
202
 */
 
203
Color *
 
204
color_from_str (const char *name)
 
205
{
 
206
        size_t len;
 
207
        
 
208
        if (!name)
 
209
                return new Color (0x00FFFFFF);
 
210
        
 
211
        if ((len = strlen (name)) == 0)
 
212
                return new Color (0x00000000);
 
213
        
 
214
        if (name [0] == '#') {
 
215
                char a [3] = "FF";
 
216
                char r [3] = "FF";
 
217
                char g [3] = "FF";
 
218
                char b [3] = "FF";
 
219
                
 
220
                // Relaxed parsing with some it's-the-web-and-it's-broken
 
221
                // "error tolerance"
 
222
                int real_len = len - 1;
 
223
                if (real_len >= 8) {
 
224
                        // aarrggbb
 
225
                        a [0] = name [1]; a [1] = name [2];
 
226
                        r [0] = name [3]; r [1] = name [4];
 
227
                        g [0] = name [5]; g [1] = name [6];
 
228
                        b [0] = name [7]; b [1] = name [8];
 
229
                } else if (real_len >= 6) {
 
230
                        // rrggbb
 
231
                        r [0] = name [1]; r [1] = name [2];
 
232
                        g [0] = name [3]; g [1] = name [4];
 
233
                        b [0] = name [5]; b [1] = name [6];
 
234
                } else if (real_len >= 4) {
 
235
                        // argb
 
236
                        a [1] = a [0] = name [1];
 
237
                        r [1] = r [0] = name [2];
 
238
                        g [1] = g [0] = name [3];
 
239
                        b [1] = b [0] = name [4];
 
240
                } else if (real_len == 3) {
 
241
                        // rgb
 
242
                        r [1] = r [0] = name [1];
 
243
                        g [1] = g [0] = name [2];
 
244
                        b [1] = b [0] = name [3];
 
245
                }
 
246
                
 
247
                return new Color (strtol (r, NULL, 16) / 255.0F, strtol (g, NULL, 16) / 255.0F,
 
248
                                  strtol (b, NULL, 16) / 255.0F, strtol (a, NULL, 16) / 255.0F);
 
249
        }
 
250
        
 
251
        if (name [0] == 's' && name [1] == 'c' && name [2] == '#') {
 
252
                char *iter = (char *) name + 3;
 
253
                double a = read_next_double (&iter);
 
254
                double r = read_next_double (&iter);
 
255
                double g = read_next_double (&iter);
 
256
                double b = read_next_double (&iter);
 
257
 
 
258
                /* Clamp values. scRGB theoretically supports negative numbers
 
259
                 * ('darker than black') as a refference to another source but here
 
260
                 * it doesn't make too much sense. */
 
261
                r = MIN (1.0, r); r = MAX (0.0, r);
 
262
                g = MIN (1.0, g); g = MAX (0.0, g);
 
263
                b = MIN (1.0, b); b = MAX (0.0, b);
 
264
                a = MIN (1.0, a); a = MAX (0.0, a);
 
265
 
 
266
                /* NOTE: This is not a fully accurate scRGB -> sRGB conversion.
 
267
                 * The real stuff has slightly different/more complex band shaping.
 
268
                 * But I'd call it "good enough" for now. */
 
269
                r = powf (r, 0.4545);
 
270
                g = powf (g, 0.46);
 
271
                b = powf (b, 0.4545);
 
272
 
 
273
                return new Color (r, g, b, a);
 
274
        }
 
275
        
 
276
        if (name[0] >= '0' && name[0] <= '9') {
 
277
                guint32 color = strtoul (name, NULL, 10);
 
278
                
 
279
                return new Color (color);
 
280
        }
 
281
        
 
282
        for (int i = 0; named_colors [i].name; i++) {
 
283
                if (!g_strcasecmp (named_colors [i].name, name))
 
284
                        return new Color (named_colors [i].color);
 
285
        }
 
286
        
 
287
        return NULL;
 
288
}
 
289
 
 
290
 
 
291
const char *
 
292
color_to_string (Color *color)
 
293
{
 
294
        static char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
295
        static char buf[10];
 
296
        guint8 v;
 
297
        
 
298
        buf[0] = '#';
 
299
        
 
300
        v = (guint8) (color->r * 256);
 
301
        buf[1] = hex[(v >> 4) & 0x0f];
 
302
        buf[2] = hex[v & 0x0f];
 
303
        
 
304
        v = (guint8) (color->g * 256);
 
305
        buf[3] = hex[(v >> 4) & 0x0f];
 
306
        buf[4] = hex[v & 0x0f];
 
307
        
 
308
        v = (guint8) (color->b * 256);
 
309
        buf[5] = hex[(v >> 4) & 0x0f];
 
310
        buf[6] = hex[v & 0x0f];
 
311
        
 
312
        v = (guint8) (color->a * 256);
 
313
        if (v > 0) {
 
314
                buf[7] = hex[(v >> 4) & 0x0f];
 
315
                buf[8] = hex[v & 0x0f];
 
316
        } else {
 
317
                buf[7] = '\0';
 
318
                buf[8] = '\0';
 
319
        }
 
320
        
 
321
        buf[9] = '\0';
 
322
        
 
323
        return buf;
 
324
}