Code

* src/dialogs/layers-panel.cpp: Compile fix from Mathieu Dimanche.
[inkscape.git] / src / libcroco / cr-rgb.c
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)
189         CRRgb *result = NULL;
191         result = g_try_malloc (sizeof (CRRgb));
193         if (result == NULL) {
194                 cr_utils_trace_info ("No more memory");
195                 return NULL;
196         }
198         memset (result, 0, sizeof (CRRgb));
200         return result;
203 /**
204  *A constructor of #CRRgb.
205  *@param a_red the red component of the color.
206  *@param a_green the green component of the color.
207  *@param a_blue the blue component of the color.
208  *@param a_unit the unit of the rgb values.
209  *(either percentage or integer values)
210  *@return the newly built instance of #CRRgb.
211  */
212 CRRgb *
213 cr_rgb_new_with_vals (gulong a_red, gulong a_green,
214                       gulong a_blue, gboolean a_is_percentage)
216         CRRgb *result = NULL;
218         result = cr_rgb_new ();
220         g_return_val_if_fail (result, NULL);
222         result->red = a_red;
223         result->green = a_green;
224         result->blue = a_blue;
225         result->is_percentage = a_is_percentage;
227         return result;
230 /**
231  *Serializes the rgb into a zero terminated string.
232  *@param a_this the instance of #CRRgb to serialize.
233  *@return the zero terminated string containing the serialized
234  *rgb. MUST BE FREED by the caller using g_free().
235  */
236 guchar *
237 cr_rgb_to_string (CRRgb * a_this)
239         guchar *result = NULL;
240         GString *str_buf = NULL;
242         str_buf = g_string_new (NULL);
243         g_return_val_if_fail (str_buf, NULL);
245         if (a_this->is_percentage == 1) {
246                 g_string_append_printf (str_buf, "%ld", a_this->red);
248                 g_string_append (str_buf, "%, ");
250                 g_string_append_printf (str_buf, "%ld", a_this->green);
251                 g_string_append (str_buf, "%, ");
253                 g_string_append_printf (str_buf, "%ld", a_this->blue);
254                 g_string_append_c (str_buf, '%');
255         } else {
256                 g_string_append_printf (str_buf, "%ld", a_this->red);
257                 g_string_append (str_buf, ", ");
259                 g_string_append_printf (str_buf, "%ld", a_this->green);
260                 g_string_append (str_buf, ", ");
262                 g_string_append_printf (str_buf, "%ld", a_this->blue);
263         }
265         if (str_buf) {
266                 result = str_buf->str;
267                 g_string_free (str_buf, FALSE);
268         }
270         return result;
273 /**
274  *Dumps the current instance of #CRRgb
275  *to a file.
276  *@param a_this the "this pointer" of
277  *the current instance of #CRRgb.
278  *@param a_fp the destination file pointer.
279  */
280 void
281 cr_rgb_dump (CRRgb * a_this, FILE * a_fp)
283         guchar *str = NULL;
285         g_return_if_fail (a_this);
287         str = cr_rgb_to_string (a_this);
289         if (str) {
290                 fprintf (a_fp, "%s", str);
291                 g_free (str);
292                 str = NULL;
293         }
296 /**
297  *If the rgb values are expressed in percentage,
298  *compute their real value.
299  *@param a_this the current instance of #CRRgb
300  *@return
301  */
302 enum CRStatus
303 cr_rgb_compute_from_percentage (CRRgb * a_this)
305         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
307         if (a_this->is_percentage == FALSE)
308                 return CR_OK;
309         a_this->red = a_this->red * 255 / 100;
310         a_this->green = a_this->green * 255 / 100;
311         a_this->blue = a_this->blue * 255 / 100;
312         a_this->is_percentage = FALSE;
313         return CR_OK;
316 /**
317  *Sets rgb values to the RGB.
318  *@param a_this the current instance of #CRRgb.
319  *@param a_red the red value.
320  *@param a_green the green value.
321  *@param a_blue the blue value.
322  *@return CR_OK upon successful completion, an error code
323  *otherwise.
324  */
325 enum CRStatus
326 cr_rgb_set (CRRgb * a_this, gulong a_red,
327             gulong a_green, gulong a_blue, gboolean a_is_percentage)
329         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
330         if (a_is_percentage != FALSE) {
331                 g_return_val_if_fail (a_red <= 100
332                                       && a_green <= 100
333                                       && a_blue <= 100, CR_BAD_PARAM_ERROR);
334         }
336         a_this->is_percentage = a_is_percentage;
338         a_this->red = a_red;
339         a_this->green = a_green;
340         a_this->blue = a_blue;
341         a_this->inherit = FALSE ;
342         a_this->is_transparent = FALSE ;
343         return CR_OK;
346 /**
347  *sets the value of the rgb to inherit.
348  *Look at the css spec from chapter 6.1 to 6.2 to understand
349  *the meaning of "inherit".
350  *@param a_this the current instance of #CRRgb
351  *
352  */
353 enum CRStatus 
354 cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit)
356         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
358         a_this->inherit = a_inherit ;
360         return CR_OK ;
363 gboolean
364 cr_rgb_is_set_to_inherit (CRRgb *a_this)
366         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
368         return a_this->inherit ;
371 /**
372  *Tests if the the rgb is set to the
373  *value "transparent" or not.
374  *@param a_this the current instance of
375  *#CRRgb
376  *@return TRUE if the rgb has been set to
377  *transparent, FALSE otherwise.
378  */
379 gboolean 
380 cr_rgb_is_set_to_transparent (CRRgb *a_this)
382         g_return_val_if_fail (a_this, FALSE) ;
383         return a_this->is_transparent ;
387 /**
388  *Sets the rgb to the "transparent" value (or not)
389  *@param a_this the current instance of #CRRgb
390  *@param a_is_transparent set to transparent or not.
391  */
392 enum CRStatus 
393 cr_rgb_set_to_transparent (CRRgb *a_this, 
394                            gboolean a_is_transparent)
396         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;        
397         a_this->is_transparent = a_is_transparent ;
398         return CR_OK ;
401 /**
402  *Sets the rgb from an other one.
403  *@param a_this the current instance of #CRRgb.
404  *@param a_rgb the rgb to "copy"
405  *@return CR_OK upon successful completion, an error code otherwise.
406  */
407 enum CRStatus
408 cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb * a_rgb)
410         g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR);
412         cr_rgb_copy (a_this, a_rgb) ;
414         return CR_OK;
417 enum CRStatus
418 cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name)
420         gulong i = 0;
421         enum CRStatus status = CR_OK;
423         g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR);
425         for (i = 0; i < sizeof (gv_standard_colors); i++) {
426                 if (!strcmp (a_color_name, gv_standard_colors[i].name)) {
427                         cr_rgb_set_from_rgb (a_this, &gv_standard_colors[i]);
428                         break;
429                 }
430         }
432         if (i < sizeof (gv_standard_colors))
433                 status = CR_OK;
434         else
435                status = CR_UNKNOWN_TYPE_ERROR;
437         return status;
440 enum CRStatus
441 cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex)
443         enum CRStatus status = CR_OK;
444         gulong i = 0;
445         guchar colors[3] = { 0 };
447         g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR);
449         if (strlen (a_hex) == 3) {
450                 for (i = 0; i < 3; i++) {
451                         if (a_hex[i] >= '0' && a_hex[i] <= '9') {
452                                 colors[i] = a_hex[i] - '0';
453                                 colors[i] = (colors[i] << 4) | colors[i];
454                         } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
455                                 colors[i] = 10 + a_hex[i] - 'a';
456                                 colors[i] = (colors[i] << 4) | colors[i];
457                         } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
458                                 colors[i] = 10 + a_hex[i] - 'A';
459                                 colors[i] = (colors[i] << 4) | colors[i];
460                         } else {
461                                 status = CR_UNKNOWN_TYPE_ERROR;
462                         }
463                 }
464         } else if (strlen (a_hex) == 6) {
465                 for (i = 0; i < 6; i++) {
466                         if (a_hex[i] >= '0' && a_hex[i] <= '9') {
467                                 colors[i / 2] <<= 4;
468                                 colors[i / 2] |= a_hex[i] - '0';
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 if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
475                                 colors[i / 2] <<= 4;
476                                 colors[i / 2] |= 10 + a_hex[i] - 'A';
477                                 status = CR_OK;
478                         } else {
479                                 status = CR_UNKNOWN_TYPE_ERROR;
480                         }
481                 }
482         } else {
483                 status = CR_UNKNOWN_TYPE_ERROR;
484         }
486         if (status == CR_OK) {
487                 status = cr_rgb_set (a_this, colors[0],
488                                      colors[1], colors[2], FALSE);
489                 cr_rgb_set_to_transparent (a_this, FALSE) ;
490         }
491         return status;
494 /**
495  *Set the rgb from a terminal symbol
496  *@param a_this the instance of #CRRgb to set
497  *@param a_value the terminal from which to set
498  */
499 enum CRStatus
500 cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value)
502         enum CRStatus status = CR_OK ;
503         g_return_val_if_fail (a_this && a_value,
504                               CR_BAD_PARAM_ERROR) ;
506         switch(a_value->type) {
507         case TERM_RGB:
508                 if (a_value->content.rgb) {
509                         cr_rgb_set_from_rgb
510                                 (a_this, a_value->content.rgb) ;
511                 }
512                 break ;
513         case TERM_IDENT:
514                 if (a_value->content.str
515                     && a_value->content.str->stryng
516                     && a_value->content.str->stryng->str) {
517                         if (!strncmp ("inherit",
518                                       a_value->content.str->stryng->str,
519                                       sizeof ("inherit")-1)) {
520                                 a_this->inherit = TRUE;
521                                 a_this->is_transparent = FALSE ;
522                         } else  {
523                                 status = cr_rgb_set_from_name
524                                         (a_this,
525                                          a_value->content.str->stryng->str) ;
526                         }
527                 } else {
528                         cr_utils_trace_info 
529                                 ("a_value has NULL string value") ;
530                 }
531                 break ;
532         case TERM_HASH:
533                 if (a_value->content.str
534                     && a_value->content.str->stryng
535                     && a_value->content.str->stryng->str) {
536                         status = cr_rgb_set_from_hex_str
537                                 (a_this, 
538                                  a_value->content.str->stryng->str) ;
539                 } else {
540                         cr_utils_trace_info
541                                 ("a_value has NULL string value") ;
542                 }
543                 break ;
544         default:
545                 status =  CR_UNKNOWN_TYPE_ERROR ;
546         }
547         return status ;
550 enum CRStatus 
551 cr_rgb_copy (CRRgb *a_dest, CRRgb*a_src)
553         g_return_val_if_fail (a_dest && a_src,
554                               CR_BAD_PARAM_ERROR) ;
556         memcpy (a_dest, a_src, sizeof (CRRgb)) ;
557         return CR_OK ;
560 /**
561  *Destructor of #CRRgb.
562  *@param a_this the "this pointer" of the
563  *current instance of #CRRgb.
564  */
565 void
566 cr_rgb_destroy (CRRgb * a_this)
568         g_return_if_fail (a_this);
569         g_free (a_this);
572 /**
573  *Parses a text buffer that contains a rgb color
574  *
575  *@param a_str a string that contains a color description
576  *@param a_enc the encoding of a_str
577  *@return the parsed color, or NULL in case of error
578  */
579 CRRgb *cr_rgb_parse_from_buf (const guchar *a_str,
580                               enum CREncoding a_enc)
582         enum CRStatus status = CR_OK ;
583         CRTerm *value = NULL ;
584         CRParser * parser = NULL;
585         CRRgb *result = NULL;
586         
587         g_return_val_if_fail (a_str, NULL);
588         
589         parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), 
590                                          a_enc, FALSE) ;
592         g_return_val_if_fail (parser, NULL);
594         status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
595         if (status != CR_OK)
596                 goto cleanup;
598         status = cr_parser_parse_term (parser, &value);
599         if (status != CR_OK)
600                 goto cleanup;
602         result = cr_rgb_new ();
603         if (!result)
604                 goto cleanup;
606         status = cr_rgb_set_from_term (result, value);
608 cleanup:
609         if (parser) {
610                 cr_parser_destroy (parser);
611                 parser = NULL;
612         }
613         if (value) {
614                 cr_term_destroy(value);
615                 value = NULL;
616         }
617         return result ;
619           
621