1
/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
4
* This file is part of The Croco Library
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.
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.
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
20
* Author: Dodji Seketeli
21
* See COPYRIGHTS file for copyrights information.
29
#include "cr-parser.h"
31
static CRRgb gv_standard_colors[] = {
32
{"aliceblue", 240, 248, 255, 0,},
33
{"antiquewhite", 250, 235, 215, 0},
34
{"aqua", 0, 255, 255, 0},
35
{"aquamarine", 127, 255, 212, 0},
36
{"azure", 240, 255, 255, 0},
37
{"beige", 245, 245, 220, 0},
38
{"bisque", 255, 228, 196, 0},
39
{"black", 0, 0, 0, 0},
40
{"blanchedalmond", 255, 235, 205, 0},
41
{"blue", 0, 0, 255, 0},
42
{"blueviolet", 138, 43, 226, 0},
43
{"brown", 165, 42, 42, 0},
44
{"burlywood", 222, 184, 135, 0},
45
{"cadetblue", 95, 158, 160, 0},
46
{"chartreuse", 127, 255, 0, 0},
47
{"chocolate", 210, 105, 30, 0},
48
{"coral", 255, 127, 80, 0},
49
{"cornflowerblue", 100, 149, 237, 0},
50
{"cornsilk", 255, 248, 220, 0},
51
{"crimson", 220, 20, 60, 0},
52
{"cyan", 0, 255, 255, 0},
53
{"darkblue", 0, 0, 139, 0},
54
{"darkcyan", 0, 139, 139, 0},
55
{"darkgoldenrod", 184, 134, 11, 0},
56
{"darkgray", 169, 169, 169, 0},
57
{"darkgreen", 0, 100, 0, 0},
58
{"darkgrey", 169, 169, 169, 0},
59
{"darkkhaki", 189, 183, 107, 0},
60
{"darkmagenta", 139, 0, 139, 0},
61
{"darkolivegreen", 85, 107, 47, 0},
62
{"darkorange", 255, 140, 0, 0},
63
{"darkorchid", 153, 50, 204, 0},
64
{"darkred", 139, 0, 0, 0},
65
{"darksalmon", 233, 150, 122, 0},
66
{"darkseagreen", 143, 188, 143, 0},
67
{"darkslateblue", 72, 61, 139, 0},
68
{"darkslategray", 47, 79, 79, 0},
69
{"darkslategrey", 47, 79, 79, 0},
70
{"darkturquoise", 0, 206, 209, 0},
71
{"darkviolet", 148, 0, 211, 0},
72
{"deeppink", 255, 20, 147, 0},
73
{"deepskyblue", 0, 191, 255, 0},
74
{"dimgray", 105, 105, 105, 0},
75
{"dimgrey", 105, 105, 105, 0},
76
{"dodgerblue", 30, 144, 255, 0},
77
{"firebrick", 178, 34, 34, 0},
78
{"floralwhite", 255, 250, 240, 0},
79
{"forestgreen", 34, 139, 34, 0},
80
{"fuchsia", 255, 0, 255, 0},
81
{"gainsboro", 220, 220, 220, 0},
82
{"ghostwhite", 248, 248, 255, 0},
83
{"gold", 255, 215, 0, 0},
84
{"goldenrod", 218, 165, 32, 0},
85
{"gray", 128, 128, 128, 0},
86
{"grey", 128, 128, 128, 0},
87
{"green", 0, 128, 0, 0},
88
{"greenyellow", 173, 255, 47, 0},
89
{"honeydew", 240, 255, 240, 0},
90
{"hotpink", 255, 105, 180, 0},
91
{"indianred", 205, 92, 92, 0},
92
{"indigo", 75, 0, 130, 0},
93
{"ivory", 255, 255, 240, 0},
94
{"khaki", 240, 230, 140, 0},
95
{"lavender", 230, 230, 250, 0},
96
{"lavenderblush", 255, 240, 245, 0},
97
{"lawngreen", 124, 252, 0, 0},
98
{"lemonchiffon", 255, 250, 205, 0},
99
{"lightblue", 173, 216, 230, 0},
100
{"lightcoral", 240, 128, 128, 0},
101
{"lightcyan", 224, 255, 255, 0},
102
{"lightgoldenrodyellow", 250, 250, 210, 0},
103
{"lightgray", 211, 211, 211, 0},
104
{"lightgreen", 144, 238, 144, 0},
105
{"lightgrey", 211, 211, 211, 0},
106
{"lightpink", 255, 182, 193, 0},
107
{"lightsalmon", 255, 160, 122, 0},
108
{"lightseagreen", 32, 178, 170, 0},
109
{"lightskyblue", 135, 206, 250, 0},
110
{"lightslategray", 119, 136, 153, 0},
111
{"lightslategrey", 119, 136, 153, 0},
112
{"lightsteelblue", 176, 196, 222, 0},
113
{"lightyellow", 255, 255, 224, 0},
114
{"lime", 0, 255, 0, 0},
115
{"limegreen", 50, 205, 50, 0},
116
{"linen", 250, 240, 230, 0},
117
{"magenta", 255, 0, 255, 0},
118
{"maroon", 128, 0, 0, 0},
119
{"mediumaquamarine", 102, 205, 170, 0},
120
{"mediumblue", 0, 0, 205, 0},
121
{"mediumorchid", 186, 85, 211, 0},
122
{"mediumpurple", 147, 112, 219, 0},
123
{"mediumseagreen", 60, 179, 113, 0},
124
{"mediumslateblue", 123, 104, 238, 0},
125
{"mediumspringgreen", 0, 250, 154, 0},
126
{"mediumturquoise", 72, 209, 204, 0},
127
{"mediumvioletred", 199, 21, 133, 0},
128
{"midnightblue", 25, 25, 112, 0},
129
{"mintcream", 245, 255, 250, 0},
130
{"mistyrose", 255, 228, 225, 0},
131
{"moccasin", 255, 228, 181, 0},
132
{"navajowhite", 255, 222, 173, 0},
133
{"navy", 0, 0, 128, 0},
134
{"oldlace", 253, 245, 230, 0},
135
{"olive", 128, 128, 0, 0},
136
{"olivedrab", 107, 142, 35, 0},
137
{"orange", 255, 165, 0, 0},
138
{"orangered", 255, 69, 0, 0},
139
{"orchid", 218, 112, 214, 0},
140
{"palegoldenrod", 238, 232, 170, 0},
141
{"palegreen", 152, 251, 152, 0},
142
{"paleturquoise", 175, 238, 238, 0},
143
{"palevioletred", 219, 112, 147, 0},
144
{"papayawhip", 255, 239, 213, 0},
145
{"peachpuff", 255, 218, 185, 0},
146
{"peru", 205, 133, 63, 0},
147
{"pink", 255, 192, 203, 0},
148
{"plum", 221, 160, 221, 0},
149
{"powderblue", 176, 224, 230, 0},
150
{"purple", 128, 0, 128, 0},
151
{"red", 255, 0, 0, 0},
152
{"rosybrown", 188, 143, 143, 0},
153
{"royalblue", 65, 105, 225, 0},
154
{"saddlebrown", 139, 69, 19, 0},
155
{"salmon", 250, 128, 114, 0},
156
{"sandybrown", 244, 164, 96, 0},
157
{"seagreen", 46, 139, 87, 0},
158
{"seashell", 255, 245, 238, 0},
159
{"sienna", 160, 82, 45, 0},
160
{"silver", 192, 192, 192, 0},
161
{"skyblue", 135, 206, 235, 0},
162
{"slateblue", 106, 90, 205, 0},
163
{"slategray", 112, 128, 144, 0},
164
{"slategrey", 112, 128, 144, 0},
165
{"snow", 255, 250, 250, 0},
166
{"springgreen", 0, 255, 127, 0},
167
{"steelblue", 70, 130, 180, 0},
168
{"tan", 210, 180, 140, 0},
169
{"teal", 0, 128, 128, 0},
170
{"thistle", 216, 191, 216, 0},
171
{"tomato", 255, 99, 71, 0},
172
{"turquoise", 64, 224, 208, 0},
173
{"violet", 238, 130, 238, 0},
174
{"wheat", 245, 222, 179, 0},
175
{"white", 255, 255, 255, 0},
176
{"whitesmoke", 245, 245, 245, 0,},
177
{"yellow", 255, 255, 0, 0,},
178
{"yellowgreen", 154, 205, 50, 0,},
179
{"transparent", 255, 255, 255, 0, 0, 1}
185
*The default constructor of #CRRgb.
187
*Returns the newly built instance of #CRRgb
192
CRRgb *result = NULL;
194
result = g_try_malloc (sizeof (CRRgb));
196
if (result == NULL) {
197
cr_utils_trace_info ("No more memory");
201
memset (result, 0, sizeof (CRRgb));
207
* cr_rgb_new_with_vals:
208
*@a_red: the red component of the color.
209
*@a_green: the green component of the color.
210
*@a_blue: the blue component of the color.
211
*@a_unit: the unit of the rgb values.
212
*(either percentage or integer values)
214
*A constructor of #CRRgb.
216
*Returns the newly built instance of #CRRgb.
219
cr_rgb_new_with_vals (gulong a_red, gulong a_green,
220
gulong a_blue, gboolean a_is_percentage)
222
CRRgb *result = NULL;
224
result = cr_rgb_new ();
226
g_return_val_if_fail (result, NULL);
229
result->green = a_green;
230
result->blue = a_blue;
231
result->is_percentage = a_is_percentage;
238
*@a_this: the instance of #CRRgb to serialize.
240
*Serializes the rgb into a zero terminated string.
242
*Returns the zero terminated string containing the serialized
243
*rgb. MUST BE FREED by the caller using g_free().
246
cr_rgb_to_string (CRRgb * a_this)
248
guchar *result = NULL;
249
GString *str_buf = NULL;
251
str_buf = g_string_new (NULL);
252
g_return_val_if_fail (str_buf, NULL);
254
if (a_this->is_percentage == 1) {
255
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
g_string_append_c (str_buf, '%');
265
g_string_append_printf (str_buf, "%ld", a_this->red);
266
g_string_append (str_buf, ", ");
268
g_string_append_printf (str_buf, "%ld", a_this->green);
269
g_string_append (str_buf, ", ");
271
g_string_append_printf (str_buf, "%ld", a_this->blue);
275
result = str_buf->str;
276
g_string_free (str_buf, FALSE);
284
*@a_this: the "this pointer" of
285
*the current instance of #CRRgb.
286
*@a_fp: the destination file pointer.
288
*Dumps the current instance of #CRRgb
292
cr_rgb_dump (CRRgb * a_this, FILE * a_fp)
296
g_return_if_fail (a_this);
298
str = cr_rgb_to_string (a_this);
301
fprintf (a_fp, "%s", str);
308
* cr_rgb_compute_from_percentage:
309
*@a_this: the current instance of #CRRgb
311
*If the rgb values are expressed in percentage,
312
*compute their real value.
314
*Returns CR_OK upon successful completion, an error code otherwise.
317
cr_rgb_compute_from_percentage (CRRgb * a_this)
319
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
321
if (a_this->is_percentage == FALSE)
323
a_this->red = a_this->red * 255 / 100;
324
a_this->green = a_this->green * 255 / 100;
325
a_this->blue = a_this->blue * 255 / 100;
326
a_this->is_percentage = FALSE;
332
*@a_this: the current instance of #CRRgb.
333
*@a_red: the red value.
334
*@a_green: the green value.
335
*@a_blue: the blue value.
337
*Sets rgb values to the RGB.
339
*Returns CR_OK upon successful completion, an error code
343
cr_rgb_set (CRRgb * a_this, gulong a_red,
344
gulong a_green, gulong a_blue, gboolean a_is_percentage)
346
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
347
if (a_is_percentage != FALSE) {
348
g_return_val_if_fail (a_red <= 100
350
&& a_blue <= 100, CR_BAD_PARAM_ERROR);
353
a_this->is_percentage = a_is_percentage;
356
a_this->green = a_green;
357
a_this->blue = a_blue;
358
a_this->inherit = FALSE ;
359
a_this->is_transparent = FALSE ;
364
* cr_rgb_set_to_inherit:
365
*@a_this: the current instance of #CRRgb
367
*sets the value of the rgb to inherit.
368
*Look at the css spec from chapter 6.1 to 6.2 to understand
369
*the meaning of "inherit".
371
* Returns CR_OK upon succesful completion, an error code otherwise.
374
cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit)
376
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
378
a_this->inherit = a_inherit ;
384
* cr_rgb_is_set_to_inherit:
386
* @a_this: the current instance of #CRRgb.
388
* Returns TRUE if the rgb is set to the value "inherit", FALSE otherwise.
391
cr_rgb_is_set_to_inherit (CRRgb *a_this)
393
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
395
return a_this->inherit ;
399
* cr_rgb_is_set_to_transparent:
400
*@a_this: the current instance of
403
*Tests if the the rgb is set to the
404
*value "transparent" or not.
406
*Returns TRUE if the rgb has been set to
407
*transparent, FALSE otherwise.
410
cr_rgb_is_set_to_transparent (CRRgb *a_this)
412
g_return_val_if_fail (a_this, FALSE) ;
413
return a_this->is_transparent ;
418
* cr_rgb_set_to_transparent:
419
*@a_this: the current instance of #CRRgb
420
*@a_is_transparent: set to transparent or not.
422
*Sets the rgb to the "transparent" value (or not)
423
*Returns CR_OK upon successfull completion, an error code otherwise.
426
cr_rgb_set_to_transparent (CRRgb *a_this,
427
gboolean a_is_transparent)
429
g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
430
a_this->is_transparent = a_is_transparent ;
435
* cr_rgb_set_from_rgb:
436
*@a_this: the current instance of #CRRgb.
437
*@a_rgb: the rgb to "copy"
439
*Sets the rgb from an other one.
441
*Returns CR_OK upon successful completion, an error code otherwise.
444
cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb * a_rgb)
446
g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR);
448
cr_rgb_copy (a_this, a_rgb) ;
454
* cr_rgb_set_from_name:
455
* @a_this: the current instance of #CRRgb
456
* @a_color_name: the color name
458
* Returns CR_OK upon successful completion, an error code otherwise.
461
cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name)
464
enum CRStatus status = CR_OK;
466
g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR);
468
for (i = 0; i < sizeof (gv_standard_colors); i++) {
469
if (!strcmp (a_color_name, gv_standard_colors[i].name)) {
470
cr_rgb_set_from_rgb (a_this, &gv_standard_colors[i]);
475
if (i < sizeof (gv_standard_colors))
478
status = CR_UNKNOWN_TYPE_ERROR;
484
* cr_rgb_set_from_hex_str:
485
* @a_this: the current instance of #CRRgb
486
* @a_hex: the hexadecimal value to set.
488
* Returns CR_OK upon successful completion.
491
cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex)
493
enum CRStatus status = CR_OK;
495
guchar colors[3] = { 0 };
497
g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR);
499
if (strlen (a_hex) == 3) {
500
for (i = 0; i < 3; i++) {
501
if (a_hex[i] >= '0' && a_hex[i] <= '9') {
502
colors[i] = a_hex[i] - '0';
503
colors[i] = (colors[i] << 4) | colors[i];
504
} else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
505
colors[i] = 10 + a_hex[i] - 'a';
506
colors[i] = (colors[i] << 4) | colors[i];
507
} else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
508
colors[i] = 10 + a_hex[i] - 'A';
509
colors[i] = (colors[i] << 4) | colors[i];
511
status = CR_UNKNOWN_TYPE_ERROR;
514
} else if (strlen (a_hex) == 6) {
515
for (i = 0; i < 6; i++) {
516
if (a_hex[i] >= '0' && a_hex[i] <= '9') {
518
colors[i / 2] |= a_hex[i] - '0';
520
} else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
522
colors[i / 2] |= 10 + a_hex[i] - 'a';
524
} else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
526
colors[i / 2] |= 10 + a_hex[i] - 'A';
529
status = CR_UNKNOWN_TYPE_ERROR;
533
status = CR_UNKNOWN_TYPE_ERROR;
536
if (status == CR_OK) {
537
status = cr_rgb_set (a_this, colors[0],
538
colors[1], colors[2], FALSE);
539
cr_rgb_set_to_transparent (a_this, FALSE) ;
545
* cr_rgb_set_from_term:
546
*@a_this: the instance of #CRRgb to set
547
*@a_value: the terminal from which to set
549
*Set the rgb from a terminal symbol
551
* Returns CR_OK upon successful completion, an error code otherwise.
554
cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value)
556
enum CRStatus status = CR_OK ;
557
g_return_val_if_fail (a_this && a_value,
558
CR_BAD_PARAM_ERROR) ;
560
switch(a_value->type) {
562
if (a_value->content.rgb) {
564
(a_this, a_value->content.rgb) ;
568
if (a_value->content.str
569
&& a_value->content.str->stryng
570
&& a_value->content.str->stryng->str) {
571
if (!strncmp ("inherit",
572
a_value->content.str->stryng->str,
573
sizeof ("inherit")-1)) {
574
a_this->inherit = TRUE;
575
a_this->is_transparent = FALSE ;
577
status = cr_rgb_set_from_name
579
a_value->content.str->stryng->str) ;
583
("a_value has NULL string value") ;
587
if (a_value->content.str
588
&& a_value->content.str->stryng
589
&& a_value->content.str->stryng->str) {
590
status = cr_rgb_set_from_hex_str
592
a_value->content.str->stryng->str) ;
595
("a_value has NULL string value") ;
599
status = CR_UNKNOWN_TYPE_ERROR ;
605
cr_rgb_copy (CRRgb *a_dest, CRRgb*a_src)
607
g_return_val_if_fail (a_dest && a_src,
608
CR_BAD_PARAM_ERROR) ;
610
memcpy (a_dest, a_src, sizeof (CRRgb)) ;
616
*@a_this: the "this pointer" of the
617
*current instance of #CRRgb.
619
*Destructor of #CRRgb.
622
cr_rgb_destroy (CRRgb * a_this)
624
g_return_if_fail (a_this);
629
* cr_rgb_parse_from_buf:
630
*@a_str: a string that contains a color description
631
*@a_enc: the encoding of a_str
633
*Parses a text buffer that contains a rgb color
635
*Returns the parsed color, or NULL in case of error
638
cr_rgb_parse_from_buf (const guchar *a_str,
639
enum CREncoding a_enc)
641
enum CRStatus status = CR_OK ;
642
CRTerm *value = NULL ;
643
CRParser * parser = NULL;
644
CRRgb *result = NULL;
646
g_return_val_if_fail (a_str, NULL);
648
parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str),
651
g_return_val_if_fail (parser, NULL);
653
status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
657
status = cr_parser_parse_term (parser, &value);
661
result = cr_rgb_new ();
665
status = cr_rgb_set_from_term (result, value);
669
cr_parser_destroy (parser);
673
cr_term_destroy(value);