1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
3 /*
4 * This file is part of The Croco Library
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2.1 of the GNU Lesser General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 *
20 * Author: Dodji Seketeli
21 * See COPYRIGHTS file for copyrights information.
22 */
25 #include <stdio.h>
26 #include <string.h>
27 #include "cr-rgb.h"
28 #include "cr-term.h"
29 #include "cr-parser.h"
31 static CRRgb gv_standard_colors[] = {
32 {"aliceblue", 240, 248, 255, FALSE, FALSE, FALSE, {0,0,0}},
33 {"antiquewhite", 250, 235, 215, FALSE, FALSE, FALSE, {0,0,0}},
34 {"aqua", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
35 {"aquamarine", 127, 255, 212, FALSE, FALSE, FALSE, {0,0,0}},
36 {"azure", 240, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
37 {"beige", 245, 245, 220, FALSE, FALSE, FALSE, {0,0,0}},
38 {"bisque", 255, 228, 196, FALSE, FALSE, FALSE, {0,0,0}},
39 {"black", 0, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
40 {"blanchedalmond", 255, 235, 205, FALSE, FALSE, FALSE, {0,0,0}},
41 {"blue", 0, 0, 255, FALSE, FALSE, FALSE, {0,0,0}},
42 {"blueviolet", 138, 43, 226, FALSE, FALSE, FALSE, {0,0,0}},
43 {"brown", 165, 42, 42, FALSE, FALSE, FALSE, {0,0,0}},
44 {"burlywood", 222, 184, 135, FALSE, FALSE, FALSE, {0,0,0}},
45 {"cadetblue", 95, 158, 160, FALSE, FALSE, FALSE, {0,0,0}},
46 {"chartreuse", 127, 255, 0, FALSE, FALSE, FALSE, {0,0,0}},
47 {"chocolate", 210, 105, 30, FALSE, FALSE, FALSE, {0,0,0}},
48 {"coral", 255, 127, 80, FALSE, FALSE, FALSE, {0,0,0}},
49 {"cornflowerblue", 100, 149, 237, FALSE, FALSE, FALSE, {0,0,0}},
50 {"cornsilk", 255, 248, 220, FALSE, FALSE, FALSE, {0,0,0}},
51 {"crimson", 220, 20, 60, FALSE, FALSE, FALSE, {0,0,0}},
52 {"cyan", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
53 {"darkblue", 0, 0, 139, FALSE, FALSE, FALSE, {0,0,0}},
54 {"darkcyan", 0, 139, 139, FALSE, FALSE, FALSE, {0,0,0}},
55 {"darkgoldenrod", 184, 134, 11, FALSE, FALSE, FALSE, {0,0,0}},
56 {"darkgray", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}},
57 {"darkgreen", 0, 100, 0, FALSE, FALSE, FALSE, {0,0,0}},
58 {"darkgrey", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}},
59 {"darkkhaki", 189, 183, 107, FALSE, FALSE, FALSE, {0,0,0}},
60 {"darkmagenta", 139, 0, 139, FALSE, FALSE, FALSE, {0,0,0}},
61 {"darkolivegreen", 85, 107, 47, FALSE, FALSE, FALSE, {0,0,0}},
62 {"darkorange", 255, 140, 0, FALSE, FALSE, FALSE, {0,0,0}},
63 {"darkorchid", 153, 50, 204, FALSE, FALSE, FALSE, {0,0,0}},
64 {"darkred", 139, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
65 {"darksalmon", 233, 150, 122, FALSE, FALSE, FALSE, {0,0,0}},
66 {"darkseagreen", 143, 188, 143, FALSE, FALSE, FALSE, {0,0,0}},
67 {"darkslateblue", 72, 61, 139, FALSE, FALSE, FALSE, {0,0,0}},
68 {"darkslategray", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}},
69 {"darkslategrey", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}},
70 {"darkturquoise", 0, 206, 209, FALSE, FALSE, FALSE, {0,0,0}},
71 {"darkviolet", 148, 0, 211, FALSE, FALSE, FALSE, {0,0,0}},
72 {"deeppink", 255, 20, 147, FALSE, FALSE, FALSE, {0,0,0}},
73 {"deepskyblue", 0, 191, 255, FALSE, FALSE, FALSE, {0,0,0}},
74 {"dimgray", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}},
75 {"dimgrey", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}},
76 {"dodgerblue", 30, 144, 255, FALSE, FALSE, FALSE, {0,0,0}},
77 {"firebrick", 178, 34, 34, FALSE, FALSE, FALSE, {0,0,0}},
78 {"floralwhite", 255, 250, 240, FALSE, FALSE, FALSE, {0,0,0}},
79 {"forestgreen", 34, 139, 34, FALSE, FALSE, FALSE, {0,0,0}},
80 {"fuchsia", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}},
81 {"gainsboro", 220, 220, 220, FALSE, FALSE, FALSE, {0,0,0}},
82 {"ghostwhite", 248, 248, 255, FALSE, FALSE, FALSE, {0,0,0}},
83 {"gold", 255, 215, 0, FALSE, FALSE, FALSE, {0,0,0}},
84 {"goldenrod", 218, 165, 32, FALSE, FALSE, FALSE, {0,0,0}},
85 {"gray", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
86 {"grey", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
87 {"green", 0, 128, 0, FALSE, FALSE, FALSE, {0,0,0}},
88 {"greenyellow", 173, 255, 47, FALSE, FALSE, FALSE, {0,0,0}},
89 {"honeydew", 240, 255, 240, FALSE, FALSE, FALSE, {0,0,0}},
90 {"hotpink", 255, 105, 180, FALSE, FALSE, FALSE, {0,0,0}},
91 {"indianred", 205, 92, 92, FALSE, FALSE, FALSE, {0,0,0}},
92 {"indigo", 75, 0, 130, FALSE, FALSE, FALSE, {0,0,0}},
93 {"ivory", 255, 255, 240, FALSE, FALSE, FALSE, {0,0,0}},
94 {"khaki", 240, 230, 140, FALSE, FALSE, FALSE, {0,0,0}},
95 {"lavender", 230, 230, 250, FALSE, FALSE, FALSE, {0,0,0}},
96 {"lavenderblush", 255, 240, 245, FALSE, FALSE, FALSE, {0,0,0}},
97 {"lawngreen", 124, 252, 0, FALSE, FALSE, FALSE, {0,0,0}},
98 {"lemonchiffon", 255, 250, 205, FALSE, FALSE, FALSE, {0,0,0}},
99 {"lightblue", 173, 216, 230, FALSE, FALSE, FALSE, {0,0,0}},
100 {"lightcoral", 240, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
101 {"lightcyan", 224, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
102 {"lightgoldenrodyellow", 250, 250, 210, FALSE, FALSE, FALSE, {0,0,0}},
103 {"lightgray", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}},
104 {"lightgreen", 144, 238, 144, FALSE, FALSE, FALSE, {0,0,0}},
105 {"lightgrey", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}},
106 {"lightpink", 255, 182, 193, FALSE, FALSE, FALSE, {0,0,0}},
107 {"lightsalmon", 255, 160, 122, FALSE, FALSE, FALSE, {0,0,0}},
108 {"lightseagreen", 32, 178, 170, FALSE, FALSE, FALSE, {0,0,0}},
109 {"lightskyblue", 135, 206, 250, FALSE, FALSE, FALSE, {0,0,0}},
110 {"lightslategray", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}},
111 {"lightslategrey", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}},
112 {"lightsteelblue", 176, 196, 222, FALSE, FALSE, FALSE, {0,0,0}},
113 {"lightyellow", 255, 255, 224, FALSE, FALSE, FALSE, {0,0,0}},
114 {"lime", 0, 255, 0, FALSE, FALSE, FALSE, {0,0,0}},
115 {"limegreen", 50, 205, 50, FALSE, FALSE, FALSE, {0,0,0}},
116 {"linen", 250, 240, 230, FALSE, FALSE, FALSE, {0,0,0}},
117 {"magenta", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}},
118 {"maroon", 128, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
119 {"mediumaquamarine", 102, 205, 170, FALSE, FALSE, FALSE, {0,0,0}},
120 {"mediumblue", 0, 0, 205, FALSE, FALSE, FALSE, {0,0,0}},
121 {"mediumorchid", 186, 85, 211, FALSE, FALSE, FALSE, {0,0,0}},
122 {"mediumpurple", 147, 112, 219, FALSE, FALSE, FALSE, {0,0,0}},
123 {"mediumseagreen", 60, 179, 113, FALSE, FALSE, FALSE, {0,0,0}},
124 {"mediumslateblue", 123, 104, 238, FALSE, FALSE, FALSE, {0,0,0}},
125 {"mediumspringgreen", 0, 250, 154, FALSE, FALSE, FALSE, {0,0,0}},
126 {"mediumturquoise", 72, 209, 204, FALSE, FALSE, FALSE, {0,0,0}},
127 {"mediumvioletred", 199, 21, 133, FALSE, FALSE, FALSE, {0,0,0}},
128 {"midnightblue", 25, 25, 112, FALSE, FALSE, FALSE, {0,0,0}},
129 {"mintcream", 245, 255, 250, FALSE, FALSE, FALSE, {0,0,0}},
130 {"mistyrose", 255, 228, 225, FALSE, FALSE, FALSE, {0,0,0}},
131 {"moccasin", 255, 228, 181, FALSE, FALSE, FALSE, {0,0,0}},
132 {"navajowhite", 255, 222, 173, FALSE, FALSE, FALSE, {0,0,0}},
133 {"navy", 0, 0, 128, FALSE, FALSE, FALSE, {0,0,0}},
134 {"oldlace", 253, 245, 230, FALSE, FALSE, FALSE, {0,0,0}},
135 {"olive", 128, 128, 0, FALSE, FALSE, FALSE, {0,0,0}},
136 {"olivedrab", 107, 142, 35, FALSE, FALSE, FALSE, {0,0,0}},
137 {"orange", 255, 165, 0, FALSE, FALSE, FALSE, {0,0,0}},
138 {"orangered", 255, 69, 0, FALSE, FALSE, FALSE, {0,0,0}},
139 {"orchid", 218, 112, 214, FALSE, FALSE, FALSE, {0,0,0}},
140 {"palegoldenrod", 238, 232, 170, FALSE, FALSE, FALSE, {0,0,0}},
141 {"palegreen", 152, 251, 152, FALSE, FALSE, FALSE, {0,0,0}},
142 {"paleturquoise", 175, 238, 238, FALSE, FALSE, FALSE, {0,0,0}},
143 {"palevioletred", 219, 112, 147, FALSE, FALSE, FALSE, {0,0,0}},
144 {"papayawhip", 255, 239, 213, FALSE, FALSE, FALSE, {0,0,0}},
145 {"peachpuff", 255, 218, 185, FALSE, FALSE, FALSE, {0,0,0}},
146 {"peru", 205, 133, 63, FALSE, FALSE, FALSE, {0,0,0}},
147 {"pink", 255, 192, 203, FALSE, FALSE, FALSE, {0,0,0}},
148 {"plum", 221, 160, 221, FALSE, FALSE, FALSE, {0,0,0}},
149 {"powderblue", 176, 224, 230, FALSE, FALSE, FALSE, {0,0,0}},
150 {"purple", 128, 0, 128, FALSE, FALSE, FALSE, {0,0,0}},
151 {"red", 255, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
152 {"rosybrown", 188, 143, 143, FALSE, FALSE, FALSE, {0,0,0}},
153 {"royalblue", 65, 105, 225, FALSE, FALSE, FALSE, {0,0,0}},
154 {"saddlebrown", 139, 69, 19, FALSE, FALSE, FALSE, {0,0,0}},
155 {"salmon", 250, 128, 114, FALSE, FALSE, FALSE, {0,0,0}},
156 {"sandybrown", 244, 164, 96, FALSE, FALSE, FALSE, {0,0,0}},
157 {"seagreen", 46, 139, 87, FALSE, FALSE, FALSE, {0,0,0}},
158 {"seashell", 255, 245, 238, FALSE, FALSE, FALSE, {0,0,0}},
159 {"sienna", 160, 82, 45, FALSE, FALSE, FALSE, {0,0,0}},
160 {"silver", 192, 192, 192, FALSE, FALSE, FALSE, {0,0,0}},
161 {"skyblue", 135, 206, 235, FALSE, FALSE, FALSE, {0,0,0}},
162 {"slateblue", 106, 90, 205, FALSE, FALSE, FALSE, {0,0,0}},
163 {"slategray", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}},
164 {"slategrey", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}},
165 {"snow", 255, 250, 250, FALSE, FALSE, FALSE, {0,0,0}},
166 {"springgreen", 0, 255, 127, FALSE, FALSE, FALSE, {0,0,0}},
167 {"steelblue", 70, 130, 180, FALSE, FALSE, FALSE, {0,0,0}},
168 {"tan", 210, 180, 140, FALSE, FALSE, FALSE, {0,0,0}},
169 {"teal", 0, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
170 {"thistle", 216, 191, 216, FALSE, FALSE, FALSE, {0,0,0}},
171 {"tomato", 255, 99, 71, FALSE, FALSE, FALSE, {0,0,0}},
172 {"turquoise", 64, 224, 208, FALSE, FALSE, FALSE, {0,0,0}},
173 {"violet", 238, 130, 238, FALSE, FALSE, FALSE, {0,0,0}},
174 {"wheat", 245, 222, 179, FALSE, FALSE, FALSE, {0,0,0}},
175 {"white", 255, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
176 {"whitesmoke", 245, 245, 245, FALSE, FALSE, FALSE, {0,0,0}},
177 {"yellow", 255, 255, 0, FALSE, FALSE, FALSE, {0,0,0}},
178 {"yellowgreen", 154, 205, 50, FALSE, FALSE, FALSE, {0,0,0}},
179 {"transparent", 255, 255, 255, FALSE, FALSE, TRUE, {0,0,0}}
180 };
182 /**
183 *The default constructor of #CRRgb.
184 *@return the newly built instance of #CRRgb
185 */
186 CRRgb *
187 cr_rgb_new (void)
188 {
189 CRRgb *result = (CRRgb *)g_try_malloc (sizeof (CRRgb));
191 if (result == NULL) {
192 cr_utils_trace_info ("No more memory");
193 return NULL;
194 }
196 memset (result, 0, sizeof (CRRgb));
198 return result;
199 }
201 /**
202 *A constructor of #CRRgb.
203 *@param a_red the red component of the color.
204 *@param a_green the green component of the color.
205 *@param a_blue the blue component of the color.
206 *@param a_unit the unit of the rgb values.
207 *(either percentage or integer values)
208 *@return the newly built instance of #CRRgb.
209 */
210 CRRgb *
211 cr_rgb_new_with_vals (gulong a_red, gulong a_green,
212 gulong a_blue, gboolean a_is_percentage)
213 {
214 CRRgb *result = NULL;
216 result = cr_rgb_new ();
218 g_return_val_if_fail (result, NULL);
220 result->red = a_red;
221 result->green = a_green;
222 result->blue = a_blue;
223 result->is_percentage = a_is_percentage;
225 return result;
226 }
228 /**
229 *Serializes the rgb into a zero terminated string.
230 *@param a_this the instance of #CRRgb to serialize.
231 *@return the zero terminated string containing the serialized
232 *rgb. MUST BE FREED by the caller using g_free().
233 */
234 guchar *
235 cr_rgb_to_string (CRRgb * a_this)
236 {
237 gchar *result = NULL;
238 GString *str_buf = (GString *)g_string_new (NULL);
239 g_return_val_if_fail (str_buf, NULL);
241 if (a_this->is_percentage == 1) {
242 g_string_append_printf (str_buf, "%ld", a_this->red);
244 g_string_append (str_buf, "%, ");
246 g_string_append_printf (str_buf, "%ld", a_this->green);
247 g_string_append (str_buf, "%, ");
249 g_string_append_printf (str_buf, "%ld", a_this->blue);
250 g_string_append_c (str_buf, '%');
251 } else {
252 g_string_append_printf (str_buf, "%ld", a_this->red);
253 g_string_append (str_buf, ", ");
255 g_string_append_printf (str_buf, "%ld", a_this->green);
256 g_string_append (str_buf, ", ");
258 g_string_append_printf (str_buf, "%ld", a_this->blue);
259 }
261 if (str_buf) {
262 result = str_buf->str;
263 g_string_free (str_buf, FALSE);
264 }
266 return (guchar *)result;
267 }
269 /**
270 *Dumps the current instance of #CRRgb
271 *to a file.
272 *@param a_this the "this pointer" of
273 *the current instance of #CRRgb.
274 *@param a_fp the destination file pointer.
275 */
276 void
277 cr_rgb_dump (CRRgb * a_this, FILE * a_fp)
278 {
279 guchar *str = NULL;
281 g_return_if_fail (a_this);
283 str = cr_rgb_to_string (a_this);
285 if (str) {
286 fprintf (a_fp, "%s", str);
287 g_free (str);
288 str = NULL;
289 }
290 }
292 /**
293 *If the rgb values are expressed in percentage,
294 *compute their real value.
295 *@param a_this the current instance of #CRRgb
296 *@return
297 */
298 enum CRStatus
299 cr_rgb_compute_from_percentage (CRRgb * a_this)
300 {
301 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
303 if (a_this->is_percentage == FALSE)
304 return CR_OK;
305 a_this->red = a_this->red * 255 / 100;
306 a_this->green = a_this->green * 255 / 100;
307 a_this->blue = a_this->blue * 255 / 100;
308 a_this->is_percentage = FALSE;
309 return CR_OK;
310 }
312 /**
313 *Sets rgb values to the RGB.
314 *@param a_this the current instance of #CRRgb.
315 *@param a_red the red value.
316 *@param a_green the green value.
317 *@param a_blue the blue value.
318 *@return CR_OK upon successful completion, an error code
319 *otherwise.
320 */
321 enum CRStatus
322 cr_rgb_set (CRRgb * a_this, gulong a_red,
323 gulong a_green, gulong a_blue, gboolean a_is_percentage)
324 {
325 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
326 if (a_is_percentage != FALSE) {
327 g_return_val_if_fail (a_red <= 100
328 && a_green <= 100
329 && a_blue <= 100, CR_BAD_PARAM_ERROR);
330 }
332 a_this->is_percentage = a_is_percentage;
334 a_this->red = a_red;
335 a_this->green = a_green;
336 a_this->blue = a_blue;
337 a_this->inherit = FALSE ;
338 a_this->is_transparent = FALSE ;
339 return CR_OK;
340 }
342 /**
343 *sets the value of the rgb to inherit.
344 *Look at the css spec from chapter 6.1 to 6.2 to understand
345 *the meaning of "inherit".
346 *@param a_this the current instance of #CRRgb
347 *
348 */
349 enum CRStatus
350 cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit)
351 {
352 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
354 a_this->inherit = a_inherit ;
356 return CR_OK ;
357 }
359 gboolean
360 cr_rgb_is_set_to_inherit (CRRgb *a_this)
361 {
362 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
364 return a_this->inherit ;
365 }
367 /**
368 *Tests if the the rgb is set to the
369 *value "transparent" or not.
370 *@param a_this the current instance of
371 *#CRRgb
372 *@return TRUE if the rgb has been set to
373 *transparent, FALSE otherwise.
374 */
375 gboolean
376 cr_rgb_is_set_to_transparent (CRRgb *a_this)
377 {
378 g_return_val_if_fail (a_this, FALSE) ;
379 return a_this->is_transparent ;
380 }
383 /**
384 *Sets the rgb to the "transparent" value (or not)
385 *@param a_this the current instance of #CRRgb
386 *@param a_is_transparent set to transparent or not.
387 */
388 enum CRStatus
389 cr_rgb_set_to_transparent (CRRgb *a_this,
390 gboolean a_is_transparent)
391 {
392 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
393 a_this->is_transparent = a_is_transparent ;
394 return CR_OK ;
395 }
397 /**
398 *Sets the rgb from an other one.
399 *@param a_this the current instance of #CRRgb.
400 *@param a_rgb the rgb to "copy"
401 *@return CR_OK upon successful completion, an error code otherwise.
402 */
403 enum CRStatus
404 cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb * a_rgb)
405 {
406 g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR);
408 cr_rgb_copy (a_this, a_rgb) ;
410 return CR_OK;
411 }
413 enum CRStatus
414 cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name)
415 {
416 gulong i = 0;
417 enum CRStatus status = CR_OK;
419 g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR);
421 for (i = 0; i < sizeof (gv_standard_colors); i++) {
422 if (!strcmp ((char *)a_color_name, gv_standard_colors[i].name)) {
423 cr_rgb_set_from_rgb (a_this, &gv_standard_colors[i]);
424 break;
425 }
426 }
428 if (i < sizeof (gv_standard_colors))
429 status = CR_OK;
430 else
431 status = CR_UNKNOWN_TYPE_ERROR;
433 return status;
434 }
436 enum CRStatus
437 cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex)
438 {
439 enum CRStatus status = CR_OK;
440 gulong i = 0;
441 guchar colors[3] = { 0 };
443 g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR);
445 if (strlen ((char *)a_hex) == 3) {
446 for (i = 0; i < 3; i++) {
447 if (a_hex[i] >= '0' && a_hex[i] <= '9') {
448 colors[i] = a_hex[i] - '0';
449 colors[i] = (colors[i] << 4) | colors[i];
450 } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
451 colors[i] = 10 + a_hex[i] - 'a';
452 colors[i] = (colors[i] << 4) | colors[i];
453 } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
454 colors[i] = 10 + a_hex[i] - 'A';
455 colors[i] = (colors[i] << 4) | colors[i];
456 } else {
457 status = CR_UNKNOWN_TYPE_ERROR;
458 }
459 }
460 } else if (strlen ((char *)a_hex) == 6) {
461 for (i = 0; i < 6; i++) {
462 if (a_hex[i] >= '0' && a_hex[i] <= '9') {
463 colors[i / 2] <<= 4;
464 colors[i / 2] |= a_hex[i] - '0';
465 status = CR_OK;
466 } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
467 colors[i / 2] <<= 4;
468 colors[i / 2] |= 10 + a_hex[i] - 'a';
469 status = CR_OK;
470 } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
471 colors[i / 2] <<= 4;
472 colors[i / 2] |= 10 + a_hex[i] - 'A';
473 status = CR_OK;
474 } else {
475 status = CR_UNKNOWN_TYPE_ERROR;
476 }
477 }
478 } else {
479 status = CR_UNKNOWN_TYPE_ERROR;
480 }
482 if (status == CR_OK) {
483 status = cr_rgb_set (a_this, colors[0],
484 colors[1], colors[2], FALSE);
485 cr_rgb_set_to_transparent (a_this, FALSE) ;
486 }
487 return status;
488 }
490 /**
491 *Set the rgb from a terminal symbol
492 *@param a_this the instance of #CRRgb to set
493 *@param a_value the terminal from which to set
494 */
495 enum CRStatus
496 cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value)
497 {
498 enum CRStatus status = CR_OK ;
499 g_return_val_if_fail (a_this && a_value,
500 CR_BAD_PARAM_ERROR) ;
502 switch(a_value->type) {
503 case TERM_RGB:
504 if (a_value->content.rgb) {
505 cr_rgb_set_from_rgb
506 (a_this, a_value->content.rgb) ;
507 }
508 break ;
509 case TERM_IDENT:
510 if (a_value->content.str
511 && a_value->content.str->stryng
512 && a_value->content.str->stryng->str) {
513 if (!strncmp ("inherit",
514 a_value->content.str->stryng->str,
515 sizeof ("inherit")-1)) {
516 a_this->inherit = TRUE;
517 a_this->is_transparent = FALSE ;
518 } else {
519 status = cr_rgb_set_from_name
520 (a_this,
521 (guchar *)a_value->content.str->stryng->str) ;
522 }
523 } else {
524 cr_utils_trace_info
525 ("a_value has NULL string value") ;
526 }
527 break ;
528 case TERM_HASH:
529 if (a_value->content.str
530 && a_value->content.str->stryng
531 && a_value->content.str->stryng->str) {
532 status = cr_rgb_set_from_hex_str
533 (a_this,
534 (guchar *)a_value->content.str->stryng->str) ;
535 } else {
536 cr_utils_trace_info
537 ("a_value has NULL string value") ;
538 }
539 break ;
540 default:
541 status = CR_UNKNOWN_TYPE_ERROR ;
542 }
543 return status ;
544 }
546 enum CRStatus
547 cr_rgb_copy (CRRgb *a_dest, CRRgb*a_src)
548 {
549 g_return_val_if_fail (a_dest && a_src,
550 CR_BAD_PARAM_ERROR) ;
552 memcpy (a_dest, a_src, sizeof (CRRgb)) ;
553 return CR_OK ;
554 }
556 /**
557 *Destructor of #CRRgb.
558 *@param a_this the "this pointer" of the
559 *current instance of #CRRgb.
560 */
561 void
562 cr_rgb_destroy (CRRgb * a_this)
563 {
564 g_return_if_fail (a_this);
565 g_free (a_this);
566 }
568 /**
569 *Parses a text buffer that contains a rgb color
570 *
571 *@param a_str a string that contains a color description
572 *@param a_enc the encoding of a_str
573 *@return the parsed color, or NULL in case of error
574 */
575 CRRgb *cr_rgb_parse_from_buf (const guchar *a_str,
576 enum CREncoding a_enc)
577 {
578 enum CRStatus status = CR_OK ;
579 CRTerm *value = NULL ;
580 CRParser * parser = NULL;
581 CRRgb *result = NULL;
583 g_return_val_if_fail (a_str, NULL);
585 parser = cr_parser_new_from_buf ((guchar *)a_str, strlen ((char *)a_str),
586 a_enc, FALSE) ;
588 g_return_val_if_fail (parser, NULL);
590 status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
591 if (status != CR_OK)
592 goto cleanup;
594 status = cr_parser_parse_term (parser, &value);
595 if (status != CR_OK)
596 goto cleanup;
598 result = cr_rgb_new ();
599 if (!result)
600 goto cleanup;
602 status = cr_rgb_set_from_term (result, value);
604 cleanup:
605 if (parser) {
606 cr_parser_destroy (parser);
607 parser = NULL;
608 }
609 if (value) {
610 cr_term_destroy(value);
611 value = NULL;
612 }
613 return result ;
614 }