Libcroco
cr-rgb.c
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
2 
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  */
23 
24 #include "config.h"
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include "cr-rgb.h"
30 #include "cr-term.h"
31 #include "cr-parser.h"
32 
33 static const CRRgb gv_standard_colors[] = {
34  {(const guchar*)"aliceblue", 240, 248, 255, FALSE, FALSE, FALSE, {0,0,0}},
35  {(const guchar*)"antiquewhite", 250, 235, 215, FALSE, FALSE, FALSE, {0,0,0}},
36  {(const guchar*)"aqua", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
37  {(const guchar*)"aquamarine", 127, 255, 212, FALSE, FALSE, FALSE, {0,0,0}},
38  {(const guchar*)"azure", 240, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
39  {(const guchar*)"beige", 245, 245, 220, FALSE, FALSE, FALSE, {0,0,0}},
40  {(const guchar*)"bisque", 255, 228, 196, FALSE, FALSE, FALSE, {0,0,0}},
41  {(const guchar*)"black", 0, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
42  {(const guchar*)"blanchedalmond", 255, 235, 205, FALSE, FALSE, FALSE, {0,0,0}},
43  {(const guchar*)"blue", 0, 0, 255, FALSE, FALSE, FALSE, {0,0,0}},
44  {(const guchar*)"blueviolet", 138, 43, 226, FALSE, FALSE, FALSE, {0,0,0}},
45  {(const guchar*)"brown", 165, 42, 42, FALSE, FALSE, FALSE, {0,0,0}},
46  {(const guchar*)"burlywood", 222, 184, 135, FALSE, FALSE, FALSE, {0,0,0}},
47  {(const guchar*)"cadetblue", 95, 158, 160, FALSE, FALSE, FALSE, {0,0,0}},
48  {(const guchar*)"chartreuse", 127, 255, 0, FALSE, FALSE, FALSE, {0,0,0}},
49  {(const guchar*)"chocolate", 210, 105, 30, FALSE, FALSE, FALSE, {0,0,0}},
50  {(const guchar*)"coral", 255, 127, 80, FALSE, FALSE, FALSE, {0,0,0}},
51  {(const guchar*)"cornflowerblue", 100, 149, 237, FALSE, FALSE, FALSE, {0,0,0}},
52  {(const guchar*)"cornsilk", 255, 248, 220, FALSE, FALSE, FALSE, {0,0,0}},
53  {(const guchar*)"crimson", 220, 20, 60, FALSE, FALSE, FALSE, {0,0,0}},
54  {(const guchar*)"cyan", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
55  {(const guchar*)"darkblue", 0, 0, 139, FALSE, FALSE, FALSE, {0,0,0}},
56  {(const guchar*)"darkcyan", 0, 139, 139, FALSE, FALSE, FALSE, {0,0,0}},
57  {(const guchar*)"darkgoldenrod", 184, 134, 11, FALSE, FALSE, FALSE, {0,0,0}},
58  {(const guchar*)"darkgray", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}},
59  {(const guchar*)"darkgreen", 0, 100, 0, FALSE, FALSE, FALSE, {0,0,0}},
60  {(const guchar*)"darkgrey", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}},
61  {(const guchar*)"darkkhaki", 189, 183, 107, FALSE, FALSE, FALSE, {0,0,0}},
62  {(const guchar*)"darkmagenta", 139, 0, 139, FALSE, FALSE, FALSE, {0,0,0}},
63  {(const guchar*)"darkolivegreen", 85, 107, 47, FALSE, FALSE, FALSE, {0,0,0}},
64  {(const guchar*)"darkorange", 255, 140, 0, FALSE, FALSE, FALSE, {0,0,0}},
65  {(const guchar*)"darkorchid", 153, 50, 204, FALSE, FALSE, FALSE, {0,0,0}},
66  {(const guchar*)"darkred", 139, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
67  {(const guchar*)"darksalmon", 233, 150, 122, FALSE, FALSE, FALSE, {0,0,0}},
68  {(const guchar*)"darkseagreen", 143, 188, 143, FALSE, FALSE, FALSE, {0,0,0}},
69  {(const guchar*)"darkslateblue", 72, 61, 139, FALSE, FALSE, FALSE, {0,0,0}},
70  {(const guchar*)"darkslategray", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}},
71  {(const guchar*)"darkslategrey", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}},
72  {(const guchar*)"darkturquoise", 0, 206, 209, FALSE, FALSE, FALSE, {0,0,0}},
73  {(const guchar*)"darkviolet", 148, 0, 211, FALSE, FALSE, FALSE, {0,0,0}},
74  {(const guchar*)"deeppink", 255, 20, 147, FALSE, FALSE, FALSE, {0,0,0}},
75  {(const guchar*)"deepskyblue", 0, 191, 255, FALSE, FALSE, FALSE, {0,0,0}},
76  {(const guchar*)"dimgray", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}},
77  {(const guchar*)"dimgrey", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}},
78  {(const guchar*)"dodgerblue", 30, 144, 255, FALSE, FALSE, FALSE, {0,0,0}},
79  {(const guchar*)"firebrick", 178, 34, 34, FALSE, FALSE, FALSE, {0,0,0}},
80  {(const guchar*)"floralwhite", 255, 250, 240, FALSE, FALSE, FALSE, {0,0,0}},
81  {(const guchar*)"forestgreen", 34, 139, 34, FALSE, FALSE, FALSE, {0,0,0}},
82  {(const guchar*)"fuchsia", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}},
83  {(const guchar*)"gainsboro", 220, 220, 220, FALSE, FALSE, FALSE, {0,0,0}},
84  {(const guchar*)"ghostwhite", 248, 248, 255, FALSE, FALSE, FALSE, {0,0,0}},
85  {(const guchar*)"gold", 255, 215, 0, FALSE, FALSE, FALSE, {0,0,0}},
86  {(const guchar*)"goldenrod", 218, 165, 32, FALSE, FALSE, FALSE, {0,0,0}},
87  {(const guchar*)"gray", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
88  {(const guchar*)"green", 0, 128, 0, FALSE, FALSE, FALSE, {0,0,0}},
89  {(const guchar*)"greenyellow", 173, 255, 47, FALSE, FALSE, FALSE, {0,0,0}},
90  {(const guchar*)"grey", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
91  {(const guchar*)"honeydew", 240, 255, 240, FALSE, FALSE, FALSE, {0,0,0}},
92  {(const guchar*)"hotpink", 255, 105, 180, FALSE, FALSE, FALSE, {0,0,0}},
93  {(const guchar*)"indianred", 205, 92, 92, FALSE, FALSE, FALSE, {0,0,0}},
94  {(const guchar*)"indigo", 75, 0, 130, FALSE, FALSE, FALSE, {0,0,0}},
95  {(const guchar*)"ivory", 255, 255, 240, FALSE, FALSE, FALSE, {0,0,0}},
96  {(const guchar*)"khaki", 240, 230, 140, FALSE, FALSE, FALSE, {0,0,0}},
97  {(const guchar*)"lavender", 230, 230, 250, FALSE, FALSE, FALSE, {0,0,0}},
98  {(const guchar*)"lavenderblush", 255, 240, 245, FALSE, FALSE, FALSE, {0,0,0}},
99  {(const guchar*)"lawngreen", 124, 252, 0, FALSE, FALSE, FALSE, {0,0,0}},
100  {(const guchar*)"lemonchiffon", 255, 250, 205, FALSE, FALSE, FALSE, {0,0,0}},
101  {(const guchar*)"lightblue", 173, 216, 230, FALSE, FALSE, FALSE, {0,0,0}},
102  {(const guchar*)"lightcoral", 240, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
103  {(const guchar*)"lightcyan", 224, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
104  {(const guchar*)"lightgoldenrodyellow", 250, 250, 210, FALSE, FALSE, FALSE, {0,0,0}},
105  {(const guchar*)"lightgray", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}},
106  {(const guchar*)"lightgreen", 144, 238, 144, FALSE, FALSE, FALSE, {0,0,0}},
107  {(const guchar*)"lightgrey", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}},
108  {(const guchar*)"lightpink", 255, 182, 193, FALSE, FALSE, FALSE, {0,0,0}},
109  {(const guchar*)"lightsalmon", 255, 160, 122, FALSE, FALSE, FALSE, {0,0,0}},
110  {(const guchar*)"lightseagreen", 32, 178, 170, FALSE, FALSE, FALSE, {0,0,0}},
111  {(const guchar*)"lightskyblue", 135, 206, 250, FALSE, FALSE, FALSE, {0,0,0}},
112  {(const guchar*)"lightslategray", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}},
113  {(const guchar*)"lightslategrey", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}},
114  {(const guchar*)"lightsteelblue", 176, 196, 222, FALSE, FALSE, FALSE, {0,0,0}},
115  {(const guchar*)"lightyellow", 255, 255, 224, FALSE, FALSE, FALSE, {0,0,0}},
116  {(const guchar*)"lime", 0, 255, 0, FALSE, FALSE, FALSE, {0,0,0}},
117  {(const guchar*)"limegreen", 50, 205, 50, FALSE, FALSE, FALSE, {0,0,0}},
118  {(const guchar*)"linen", 250, 240, 230, FALSE, FALSE, FALSE, {0,0,0}},
119  {(const guchar*)"magenta", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}},
120  {(const guchar*)"maroon", 128, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
121  {(const guchar*)"mediumaquamarine", 102, 205, 170, FALSE, FALSE, FALSE, {0,0,0}},
122  {(const guchar*)"mediumblue", 0, 0, 205, FALSE, FALSE, FALSE, {0,0,0}},
123  {(const guchar*)"mediumorchid", 186, 85, 211, FALSE, FALSE, FALSE, {0,0,0}},
124  {(const guchar*)"mediumpurple", 147, 112, 219, FALSE, FALSE, FALSE, {0,0,0}},
125  {(const guchar*)"mediumseagreen", 60, 179, 113, FALSE, FALSE, FALSE, {0,0,0}},
126  {(const guchar*)"mediumslateblue", 123, 104, 238, FALSE, FALSE, FALSE, {0,0,0}},
127  {(const guchar*)"mediumspringgreen", 0, 250, 154, FALSE, FALSE, FALSE, {0,0,0}},
128  {(const guchar*)"mediumturquoise", 72, 209, 204, FALSE, FALSE, FALSE, {0,0,0}},
129  {(const guchar*)"mediumvioletred", 199, 21, 133, FALSE, FALSE, FALSE, {0,0,0}},
130  {(const guchar*)"midnightblue", 25, 25, 112, FALSE, FALSE, FALSE, {0,0,0}},
131  {(const guchar*)"mintcream", 245, 255, 250, FALSE, FALSE, FALSE, {0,0,0}},
132  {(const guchar*)"mistyrose", 255, 228, 225, FALSE, FALSE, FALSE, {0,0,0}},
133  {(const guchar*)"moccasin", 255, 228, 181, FALSE, FALSE, FALSE, {0,0,0}},
134  {(const guchar*)"navajowhite", 255, 222, 173, FALSE, FALSE, FALSE, {0,0,0}},
135  {(const guchar*)"navy", 0, 0, 128, FALSE, FALSE, FALSE, {0,0,0}},
136  {(const guchar*)"oldlace", 253, 245, 230, FALSE, FALSE, FALSE, {0,0,0}},
137  {(const guchar*)"olive", 128, 128, 0, FALSE, FALSE, FALSE, {0,0,0}},
138  {(const guchar*)"olivedrab", 107, 142, 35, FALSE, FALSE, FALSE, {0,0,0}},
139  {(const guchar*)"orange", 255, 165, 0, FALSE, FALSE, FALSE, {0,0,0}},
140  {(const guchar*)"orangered", 255, 69, 0, FALSE, FALSE, FALSE, {0,0,0}},
141  {(const guchar*)"orchid", 218, 112, 214, FALSE, FALSE, FALSE, {0,0,0}},
142  {(const guchar*)"palegoldenrod", 238, 232, 170, FALSE, FALSE, FALSE, {0,0,0}},
143  {(const guchar*)"palegreen", 152, 251, 152, FALSE, FALSE, FALSE, {0,0,0}},
144  {(const guchar*)"paleturquoise", 175, 238, 238, FALSE, FALSE, FALSE, {0,0,0}},
145  {(const guchar*)"palevioletred", 219, 112, 147, FALSE, FALSE, FALSE, {0,0,0}},
146  {(const guchar*)"papayawhip", 255, 239, 213, FALSE, FALSE, FALSE, {0,0,0}},
147  {(const guchar*)"peachpuff", 255, 218, 185, FALSE, FALSE, FALSE, {0,0,0}},
148  {(const guchar*)"peru", 205, 133, 63, FALSE, FALSE, FALSE, {0,0,0}},
149  {(const guchar*)"pink", 255, 192, 203, FALSE, FALSE, FALSE, {0,0,0}},
150  {(const guchar*)"plum", 221, 160, 221, FALSE, FALSE, FALSE, {0,0,0}},
151  {(const guchar*)"powderblue", 176, 224, 230, FALSE, FALSE, FALSE, {0,0,0}},
152  {(const guchar*)"purple", 128, 0, 128, FALSE, FALSE, FALSE, {0,0,0}},
153  {(const guchar*)"red", 255, 0, 0, FALSE, FALSE, FALSE, {0,0,0}},
154  {(const guchar*)"rosybrown", 188, 143, 143, FALSE, FALSE, FALSE, {0,0,0}},
155  {(const guchar*)"royalblue", 65, 105, 225, FALSE, FALSE, FALSE, {0,0,0}},
156  {(const guchar*)"saddlebrown", 139, 69, 19, FALSE, FALSE, FALSE, {0,0,0}},
157  {(const guchar*)"salmon", 250, 128, 114, FALSE, FALSE, FALSE, {0,0,0}},
158  {(const guchar*)"sandybrown", 244, 164, 96, FALSE, FALSE, FALSE, {0,0,0}},
159  {(const guchar*)"seagreen", 46, 139, 87, FALSE, FALSE, FALSE, {0,0,0}},
160  {(const guchar*)"seashell", 255, 245, 238, FALSE, FALSE, FALSE, {0,0,0}},
161  {(const guchar*)"sienna", 160, 82, 45, FALSE, FALSE, FALSE, {0,0,0}},
162  {(const guchar*)"silver", 192, 192, 192, FALSE, FALSE, FALSE, {0,0,0}},
163  {(const guchar*)"skyblue", 135, 206, 235, FALSE, FALSE, FALSE, {0,0,0}},
164  {(const guchar*)"slateblue", 106, 90, 205, FALSE, FALSE, FALSE, {0,0,0}},
165  {(const guchar*)"slategray", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}},
166  {(const guchar*)"slategrey", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}},
167  {(const guchar*)"snow", 255, 250, 250, FALSE, FALSE, FALSE, {0,0,0}},
168  {(const guchar*)"springgreen", 0, 255, 127, FALSE, FALSE, FALSE, {0,0,0}},
169  {(const guchar*)"steelblue", 70, 130, 180, FALSE, FALSE, FALSE, {0,0,0}},
170  {(const guchar*)"tan", 210, 180, 140, FALSE, FALSE, FALSE, {0,0,0}},
171  {(const guchar*)"teal", 0, 128, 128, FALSE, FALSE, FALSE, {0,0,0}},
172  {(const guchar*)"thistle", 216, 191, 216, FALSE, FALSE, FALSE, {0,0,0}},
173  {(const guchar*)"tomato", 255, 99, 71, FALSE, FALSE, FALSE, {0,0,0}},
174  {(const guchar*)"transparent", 255, 255, 255, FALSE, FALSE, TRUE, {0,0,0}},
175  {(const guchar*)"turquoise", 64, 224, 208, FALSE, FALSE, FALSE, {0,0,0}},
176  {(const guchar*)"violet", 238, 130, 238, FALSE, FALSE, FALSE, {0,0,0}},
177  {(const guchar*)"wheat", 245, 222, 179, FALSE, FALSE, FALSE, {0,0,0}},
178  {(const guchar*)"white", 255, 255, 255, FALSE, FALSE, FALSE, {0,0,0}},
179  {(const guchar*)"whitesmoke", 245, 245, 245, FALSE, FALSE, FALSE, {0,0,0}},
180  {(const guchar*)"yellow", 255, 255, 0, FALSE, FALSE, FALSE, {0,0,0}},
181  {(const guchar*)"yellowgreen", 154, 205, 50, FALSE, FALSE, FALSE, {0,0,0}}
182 };
183 
184 /**
185  * cr_rgb_new:
186  *
187  *The default constructor of #CRRgb.
188  *
189  *Returns the newly built instance of #CRRgb
190  */
191 CRRgb *
193 {
194  CRRgb *result = NULL;
195 
196  result = g_try_malloc (sizeof (CRRgb));
197 
198  if (result == NULL) {
199  cr_utils_trace_info ("No more memory");
200  return NULL;
201  }
202 
203  memset (result, 0, sizeof (CRRgb));
204 
205  return result;
206 }
207 
208 /**
209  * cr_rgb_new_with_vals:
210  *@a_red: the red component of the color.
211  *@a_green: the green component of the color.
212  *@a_blue: the blue component of the color.
213  *@a_unit: the unit of the rgb values.
214  *(either percentage or integer values)
215  *
216  *A constructor of #CRRgb.
217  *
218  *Returns the newly built instance of #CRRgb.
219  */
220 CRRgb *
221 cr_rgb_new_with_vals (gulong a_red, gulong a_green,
222  gulong a_blue, gboolean a_is_percentage)
223 {
224  CRRgb *result = NULL;
225 
226  result = cr_rgb_new ();
227 
228  g_return_val_if_fail (result, NULL);
229 
230  result->red = a_red;
231  result->green = a_green;
232  result->blue = a_blue;
233  result->is_percentage = a_is_percentage;
234 
235  return result;
236 }
237 
238 /**
239  * cr_rgb_to_string:
240  *@a_this: the instance of #CRRgb to serialize.
241  *
242  *Serializes the rgb into a zero terminated string.
243  *
244  *Returns the zero terminated string containing the serialized
245  *rgb. MUST BE FREED by the caller using g_free().
246  */
247 guchar *
248 cr_rgb_to_string (CRRgb const * a_this)
249 {
250  guchar *result = NULL;
251  GString *str_buf = NULL;
252 
253  str_buf = g_string_new (NULL);
254  g_return_val_if_fail (str_buf, NULL);
255 
256  if (a_this->is_percentage == 1) {
257  g_string_append_printf (str_buf, "%ld", a_this->red);
258 
259  g_string_append (str_buf, "%, ");
260 
261  g_string_append_printf (str_buf, "%ld", a_this->green);
262  g_string_append (str_buf, "%, ");
263 
264  g_string_append_printf (str_buf, "%ld", a_this->blue);
265  g_string_append_c (str_buf, '%');
266  } else {
267  g_string_append_printf (str_buf, "%ld", a_this->red);
268  g_string_append (str_buf, ", ");
269 
270  g_string_append_printf (str_buf, "%ld", a_this->green);
271  g_string_append (str_buf, ", ");
272 
273  g_string_append_printf (str_buf, "%ld", a_this->blue);
274  }
275 
276  if (str_buf) {
277  result = (guchar *) str_buf->str;
278  g_string_free (str_buf, FALSE);
279  }
280 
281  return result;
282 }
283 
284 /**
285  * cr_rgb_dump:
286  *@a_this: the "this pointer" of
287  *the current instance of #CRRgb.
288  *@a_fp: the destination file pointer.
289  *
290  *Dumps the current instance of #CRRgb
291  *to a file.
292  */
293 void
294 cr_rgb_dump (CRRgb const * a_this, FILE * a_fp)
295 {
296  guchar *str = NULL;
297 
298  g_return_if_fail (a_this);
299 
300  str = cr_rgb_to_string (a_this);
301 
302  if (str) {
303  fprintf (a_fp, "%s", str);
304  g_free (str);
305  str = NULL;
306  }
307 }
308 
309 /**
310  * cr_rgb_compute_from_percentage:
311  *@a_this: the current instance of #CRRgb
312  *
313  *If the rgb values are expressed in percentage,
314  *compute their real value.
315  *
316  *Returns CR_OK upon successful completion, an error code otherwise.
317  */
318 enum CRStatus
320 {
321  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
322 
323  if (a_this->is_percentage == FALSE)
324  return CR_OK;
325  a_this->red = a_this->red * 255 / 100;
326  a_this->green = a_this->green * 255 / 100;
327  a_this->blue = a_this->blue * 255 / 100;
328  a_this->is_percentage = FALSE;
329  return CR_OK;
330 }
331 
332 /**
333  * cr_rgb_set:
334  *@a_this: the current instance of #CRRgb.
335  *@a_red: the red value.
336  *@a_green: the green value.
337  *@a_blue: the blue value.
338  *
339  *Sets rgb values to the RGB.
340  *
341  *Returns CR_OK upon successful completion, an error code
342  *otherwise.
343  */
344 enum CRStatus
345 cr_rgb_set (CRRgb * a_this, gulong a_red,
346  gulong a_green, gulong a_blue, gboolean a_is_percentage)
347 {
348  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
349  if (a_is_percentage != FALSE) {
350  g_return_val_if_fail (a_red <= 100
351  && a_green <= 100
352  && a_blue <= 100, CR_BAD_PARAM_ERROR);
353  }
354 
355  a_this->is_percentage = a_is_percentage;
356 
357  a_this->red = a_red;
358  a_this->green = a_green;
359  a_this->blue = a_blue;
360  a_this->inherit = FALSE ;
361  a_this->is_transparent = FALSE ;
362  return CR_OK;
363 }
364 
365 /**
366  * cr_rgb_set_to_inherit:
367  *@a_this: the current instance of #CRRgb
368  *
369  *sets the value of the rgb to inherit.
370  *Look at the css spec from chapter 6.1 to 6.2 to understand
371  *the meaning of "inherit".
372  *
373  * Returns CR_OK upon succesful completion, an error code otherwise.
374  */
375 enum CRStatus
376 cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit)
377 {
378  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
379 
380  a_this->inherit = a_inherit ;
381 
382  return CR_OK ;
383 }
384 
385 /**
386  * cr_rgb_is_set_to_inherit:
387  *
388  * @a_this: the current instance of #CRRgb.
389  *
390  * Returns TRUE if the rgb is set to the value "inherit", FALSE otherwise.
391  */
392 gboolean
394 {
395  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
396 
397  return a_this->inherit ;
398 }
399 
400 /**
401  * cr_rgb_is_set_to_transparent:
402  *@a_this: the current instance of
403  *#CRRgb
404  *
405  *Tests if the the rgb is set to the
406  *value "transparent" or not.
407  *
408  *Returns TRUE if the rgb has been set to
409  *transparent, FALSE otherwise.
410  */
411 gboolean
413 {
414  g_return_val_if_fail (a_this, FALSE) ;
415  return a_this->is_transparent ;
416 }
417 
418 
419 /**
420  * cr_rgb_set_to_transparent:
421  *@a_this: the current instance of #CRRgb
422  *@a_is_transparent: set to transparent or not.
423  *
424  *Sets the rgb to the "transparent" value (or not)
425  *Returns CR_OK upon successfull completion, an error code otherwise.
426  */
427 enum CRStatus
429  gboolean a_is_transparent)
430 {
431  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
432  a_this->is_transparent = a_is_transparent ;
433  return CR_OK ;
434 }
435 
436 /**
437  * cr_rgb_set_from_rgb:
438  *@a_this: the current instance of #CRRgb.
439  *@a_rgb: the rgb to "copy"
440  *
441  *Sets the rgb from an other one.
442  *
443  *Returns CR_OK upon successful completion, an error code otherwise.
444  */
445 enum CRStatus
446 cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb const * a_rgb)
447 {
448  g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR);
449 
450  cr_rgb_copy (a_this, a_rgb) ;
451 
452  return CR_OK;
453 }
454 
455 static int
456 cr_rgb_color_name_compare (const void *a,
457  const void *b)
458 {
459  const char *a_color_name = a;
460  const CRRgb *rgb = b;
461 
462  return g_ascii_strcasecmp (a_color_name, (const char *) rgb->name);
463 }
464 
465 /**
466  * cr_rgb_set_from_name:
467  * @a_this: the current instance of #CRRgb
468  * @a_color_name: the color name
469  *
470  * Returns CR_OK upon successful completion, an error code otherwise.
471  */
472 enum CRStatus
473 cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name)
474 {
475  enum CRStatus status = CR_OK;
476  CRRgb *result;
477 
478  g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR);
479 
480  result = bsearch (a_color_name,
481  gv_standard_colors,
482  G_N_ELEMENTS (gv_standard_colors),
483  sizeof (gv_standard_colors[0]),
484  cr_rgb_color_name_compare);
485  if (result != NULL)
486  cr_rgb_set_from_rgb (a_this, result);
487  else
488  status = CR_UNKNOWN_TYPE_ERROR;
489 
490  return status;
491 }
492 
493 /**
494  * cr_rgb_set_from_hex_str:
495  * @a_this: the current instance of #CRRgb
496  * @a_hex: the hexadecimal value to set.
497  *
498  * Returns CR_OK upon successful completion.
499  */
500 enum CRStatus
501 cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex)
502 {
503  enum CRStatus status = CR_OK;
504  gulong i = 0;
505  guchar colors[3] = { 0 };
506 
507  g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR);
508 
509  if (strlen ((const char *) a_hex) == 3) {
510  for (i = 0; i < 3; i++) {
511  if (a_hex[i] >= '0' && a_hex[i] <= '9') {
512  colors[i] = a_hex[i] - '0';
513  colors[i] = (colors[i] << 4) | colors[i];
514  } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
515  colors[i] = 10 + a_hex[i] - 'a';
516  colors[i] = (colors[i] << 4) | colors[i];
517  } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
518  colors[i] = 10 + a_hex[i] - 'A';
519  colors[i] = (colors[i] << 4) | colors[i];
520  } else {
521  status = CR_UNKNOWN_TYPE_ERROR;
522  }
523  }
524  } else if (strlen ((const char *) a_hex) == 6) {
525  for (i = 0; i < 6; i++) {
526  if (a_hex[i] >= '0' && a_hex[i] <= '9') {
527  colors[i / 2] <<= 4;
528  colors[i / 2] |= a_hex[i] - '0';
529  status = CR_OK;
530  } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
531  colors[i / 2] <<= 4;
532  colors[i / 2] |= 10 + a_hex[i] - 'a';
533  status = CR_OK;
534  } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
535  colors[i / 2] <<= 4;
536  colors[i / 2] |= 10 + a_hex[i] - 'A';
537  status = CR_OK;
538  } else {
539  status = CR_UNKNOWN_TYPE_ERROR;
540  }
541  }
542  } else {
543  status = CR_UNKNOWN_TYPE_ERROR;
544  }
545 
546  if (status == CR_OK) {
547  status = cr_rgb_set (a_this, colors[0],
548  colors[1], colors[2], FALSE);
549  cr_rgb_set_to_transparent (a_this, FALSE) ;
550  }
551  return status;
552 }
553 
554 /**
555  * cr_rgb_set_from_term:
556  *@a_this: the instance of #CRRgb to set
557  *@a_value: the terminal from which to set
558  *
559  *Set the rgb from a terminal symbol
560  *
561  * Returns CR_OK upon successful completion, an error code otherwise.
562  */
563 enum CRStatus
564 cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value)
565 {
566  enum CRStatus status = CR_OK ;
567  g_return_val_if_fail (a_this && a_value,
569 
570  switch(a_value->type) {
571  case TERM_RGB:
572  if (a_value->content.rgb) {
574  (a_this, a_value->content.rgb) ;
575  }
576  break ;
577  case TERM_IDENT:
578  if (a_value->content.str
579  && a_value->content.str->stryng
580  && a_value->content.str->stryng->str) {
581  if (!strncmp ("inherit",
582  a_value->content.str->stryng->str,
583  sizeof ("inherit")-1)) {
584  a_this->inherit = TRUE;
585  a_this->is_transparent = FALSE ;
586  } else {
587  status = cr_rgb_set_from_name
588  (a_this,
589  (const guchar *) a_value->content.str->stryng->str) ;
590  }
591  } else {
593  ("a_value has NULL string value") ;
594  }
595  break ;
596  case TERM_HASH:
597  if (a_value->content.str
598  && a_value->content.str->stryng
599  && a_value->content.str->stryng->str) {
600  status = cr_rgb_set_from_hex_str
601  (a_this,
602  (const guchar *) a_value->content.str->stryng->str) ;
603  } else {
605  ("a_value has NULL string value") ;
606  }
607  break ;
608  default:
609  status = CR_UNKNOWN_TYPE_ERROR ;
610  }
611  return status ;
612 }
613 
614 enum CRStatus
615 cr_rgb_copy (CRRgb *a_dest, CRRgb const *a_src)
616 {
617  g_return_val_if_fail (a_dest && a_src,
619 
620  memcpy (a_dest, a_src, sizeof (CRRgb)) ;
621  return CR_OK ;
622 }
623 
624 /**
625  * cr_rgb_destroy:
626  *@a_this: the "this pointer" of the
627  *current instance of #CRRgb.
628  *
629  *Destructor of #CRRgb.
630  */
631 void
633 {
634  g_return_if_fail (a_this);
635  g_free (a_this);
636 }
637 
638 /**
639  * cr_rgb_parse_from_buf:
640  *@a_str: a string that contains a color description
641  *@a_enc: the encoding of a_str
642  *
643  *Parses a text buffer that contains a rgb color
644  *
645  *Returns the parsed color, or NULL in case of error
646  */
647 CRRgb *
648 cr_rgb_parse_from_buf (const guchar *a_str,
649  enum CREncoding a_enc)
650 {
651  enum CRStatus status = CR_OK ;
652  CRTerm *value = NULL ;
653  CRParser * parser = NULL;
654  CRRgb *result = NULL;
655 
656  g_return_val_if_fail (a_str, NULL);
657 
658  parser = cr_parser_new_from_buf ((guchar *) a_str, strlen ((const char *) a_str), a_enc, FALSE);
659 
660  g_return_val_if_fail (parser, NULL);
661 
663  if (status != CR_OK)
664  goto cleanup;
665 
666  status = cr_parser_parse_term (parser, &value);
667  if (status != CR_OK)
668  goto cleanup;
669 
670  result = cr_rgb_new ();
671  if (!result)
672  goto cleanup;
673 
674  status = cr_rgb_set_from_term (result, value);
675 
676 cleanup:
677  if (parser) {
678  cr_parser_destroy (parser);
679  parser = NULL;
680  }
681  if (value) {
682  cr_term_destroy(value);
683  value = NULL;
684  }
685  return result ;
686 }
687 
enum CRStatus cr_rgb_set(CRRgb *a_this, gulong a_red, gulong a_green, gulong a_blue, gboolean a_is_percentage)
cr_rgb_set: @a_this: the current instance of CRRgb.
Definition: cr-rgb.c:345
gboolean cr_rgb_is_set_to_inherit(CRRgb const *a_this)
cr_rgb_is_set_to_inherit:
Definition: cr-rgb.c:393
typedefG_BEGIN_DECLS struct _CRRgb CRRgb
Definition: cr-rgb.h:34
enum CRTermType type
The type of the term.
Definition: cr-term.h:87
The implementation of the SAC parser.
Definition: cr-parser.h:51
enum CRStatus cr_rgb_compute_from_percentage(CRRgb *a_this)
cr_rgb_compute_from_percentage: @a_this: the current instance of CRRgb
Definition: cr-rgb.c:319
enum CRStatus cr_rgb_set_to_transparent(CRRgb *a_this, gboolean a_is_transparent)
cr_rgb_set_to_transparent: @a_this: the current instance of CRRgb @a_is_transparent: set to transpare...
Definition: cr-rgb.c:428
CRString * str
Definition: cr-term.h:109
enum CRStatus cr_rgb_set_from_term(CRRgb *a_this, const struct _CRTerm *a_value)
cr_rgb_set_from_term: @a_this: the instance of CRRgb to set @a_value: the terminal from which to set
Definition: cr-rgb.c:564
enum CRStatus cr_rgb_set_from_name(CRRgb *a_this, const guchar *a_color_name)
cr_rgb_set_from_name: @a_this: the current instance of CRRgb @a_color_name: the color name
Definition: cr-rgb.c:473
union _CRTerm::@2 content
The content of the term.
CREncoding
Encoding values.
Definition: cr-utils.h:84
enum CRStatus cr_parser_try_to_skip_spaces_and_comments(CRParser *a_this)
cr_parser_try_to_skip_spaces_and_comments: @a_this: the current instance of CRParser.
Definition: cr-parser.c:621
CRStatus
The status type returned by the methods of the croco library.
Definition: cr-utils.h:43
void cr_rgb_dump(CRRgb const *a_this, FILE *a_fp)
cr_rgb_dump: @a_this: the "this pointer" of the current instance of CRRgb.
Definition: cr-rgb.c:294
CRRgb * cr_rgb_new_with_vals(gulong a_red, gulong a_green, gulong a_blue, gboolean a_is_percentage)
cr_rgb_new_with_vals: @a_red: the red component of the color.
Definition: cr-rgb.c:221
Definition: cr-utils.h:44
enum CRStatus cr_rgb_set_from_hex_str(CRRgb *a_this, const guchar *a_hex)
cr_rgb_set_from_hex_str: @a_this: the current instance of CRRgb @a_hex: the hexadecimal value to set.
Definition: cr-rgb.c:501
enum CRStatus cr_rgb_set_to_inherit(CRRgb *a_this, gboolean a_inherit)
cr_rgb_set_to_inherit: @a_this: the current instance of CRRgb
Definition: cr-rgb.c:376
CRRgb * cr_rgb_parse_from_buf(const guchar *a_str, enum CREncoding a_enc)
cr_rgb_parse_from_buf: @a_str: a string that contains a color description @a_enc: the encoding of a_s...
Definition: cr-rgb.c:648
CRParser * cr_parser_new_from_buf(guchar *a_buf, gulong a_len, enum CREncoding a_enc, gboolean a_free_buf)
cr_parser_new_from_buf: @a_buf: the buffer to parse.
Definition: cr-parser.c:2784
void cr_rgb_destroy(CRRgb *a_this)
cr_rgb_destroy: @a_this: the "this pointer" of the current instance of CRRgb.
Definition: cr-rgb.c:632
enum CRStatus cr_rgb_copy(CRRgb *a_dest, CRRgb const *a_src)
Definition: cr-rgb.c:615
gboolean cr_rgb_is_set_to_transparent(CRRgb const *a_this)
cr_rgb_is_set_to_transparent: @a_this: the current instance of CRRgb
Definition: cr-rgb.c:412
guchar * cr_rgb_to_string(CRRgb const *a_this)
cr_rgb_to_string: @a_this: the instance of CRRgb to serialize.
Definition: cr-rgb.c:248
enum CRStatus cr_parser_parse_term(CRParser *a_this, CRTerm **a_term)
cr_parser_parse_term: @a_term: out parameter.
Definition: cr-parser.c:1507
An abstraction of a css2 term as defined in the CSS2 spec in appendix D.1: term ::= [ NUMBER S* | PER...
Definition: cr-term.h:82
enum CRStatus cr_rgb_set_from_rgb(CRRgb *a_this, CRRgb const *a_rgb)
cr_rgb_set_from_rgb: @a_this: the current instance of CRRgb.
Definition: cr-rgb.c:446
The declaration file of the CRParser class.
void cr_parser_destroy(CRParser *a_this)
cr_parser_destroy: @a_this: the current instance of CRParser to destroy.
Definition: cr-parser.c:4498
Declaration of the #CRTem class.
CRRgb * cr_rgb_new(void)
cr_rgb_new:
Definition: cr-rgb.c:192
void cr_term_destroy(CRTerm *a_this)
The destructor of the the CRTerm class.
Definition: cr-term.c:775
CRRgb * rgb
Definition: cr-term.h:110
#define cr_utils_trace_info(a_msg)
Traces an info message.
Definition: cr-utils.h:127