00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include "cr-rgb.h"
00028 #include "cr-term.h"
00029 #include "cr-parser.h"
00030
00031 static CRRgb gv_standard_colors[] = {
00032 {"aliceblue", 240, 248, 255, 0,},
00033 {"antiquewhite", 250, 235, 215, 0},
00034 {"aqua", 0, 255, 255, 0},
00035 {"aquamarine", 127, 255, 212, 0},
00036 {"azure", 240, 255, 255, 0},
00037 {"beige", 245, 245, 220, 0},
00038 {"bisque", 255, 228, 196, 0},
00039 {"black", 0, 0, 0, 0},
00040 {"blanchedalmond", 255, 235, 205, 0},
00041 {"blue", 0, 0, 255, 0},
00042 {"blueviolet", 138, 43, 226, 0},
00043 {"brown", 165, 42, 42, 0},
00044 {"burlywood", 222, 184, 135, 0},
00045 {"cadetblue", 95, 158, 160, 0},
00046 {"chartreuse", 127, 255, 0, 0},
00047 {"chocolate", 210, 105, 30, 0},
00048 {"coral", 255, 127, 80, 0},
00049 {"cornflowerblue", 100, 149, 237, 0},
00050 {"cornsilk", 255, 248, 220, 0},
00051 {"crimson", 220, 20, 60, 0},
00052 {"cyan", 0, 255, 255, 0},
00053 {"darkblue", 0, 0, 139, 0},
00054 {"darkcyan", 0, 139, 139, 0},
00055 {"darkgoldenrod", 184, 134, 11, 0},
00056 {"darkgray", 169, 169, 169, 0},
00057 {"darkgreen", 0, 100, 0, 0},
00058 {"darkgrey", 169, 169, 169, 0},
00059 {"darkkhaki", 189, 183, 107, 0},
00060 {"darkmagenta", 139, 0, 139, 0},
00061 {"darkolivegreen", 85, 107, 47, 0},
00062 {"darkorange", 255, 140, 0, 0},
00063 {"darkorchid", 153, 50, 204, 0},
00064 {"darkred", 139, 0, 0, 0},
00065 {"darksalmon", 233, 150, 122, 0},
00066 {"darkseagreen", 143, 188, 143, 0},
00067 {"darkslateblue", 72, 61, 139, 0},
00068 {"darkslategray", 47, 79, 79, 0},
00069 {"darkslategrey", 47, 79, 79, 0},
00070 {"darkturquoise", 0, 206, 209, 0},
00071 {"darkviolet", 148, 0, 211, 0},
00072 {"deeppink", 255, 20, 147, 0},
00073 {"deepskyblue", 0, 191, 255, 0},
00074 {"dimgray", 105, 105, 105, 0},
00075 {"dimgrey", 105, 105, 105, 0},
00076 {"dodgerblue", 30, 144, 255, 0},
00077 {"firebrick", 178, 34, 34, 0},
00078 {"floralwhite", 255, 250, 240, 0},
00079 {"forestgreen", 34, 139, 34, 0},
00080 {"fuchsia", 255, 0, 255, 0},
00081 {"gainsboro", 220, 220, 220, 0},
00082 {"ghostwhite", 248, 248, 255, 0},
00083 {"gold", 255, 215, 0, 0},
00084 {"goldenrod", 218, 165, 32, 0},
00085 {"gray", 128, 128, 128, 0},
00086 {"grey", 128, 128, 128, 0},
00087 {"green", 0, 128, 0, 0},
00088 {"greenyellow", 173, 255, 47, 0},
00089 {"honeydew", 240, 255, 240, 0},
00090 {"hotpink", 255, 105, 180, 0},
00091 {"indianred", 205, 92, 92, 0},
00092 {"indigo", 75, 0, 130, 0},
00093 {"ivory", 255, 255, 240, 0},
00094 {"khaki", 240, 230, 140, 0},
00095 {"lavender", 230, 230, 250, 0},
00096 {"lavenderblush", 255, 240, 245, 0},
00097 {"lawngreen", 124, 252, 0, 0},
00098 {"lemonchiffon", 255, 250, 205, 0},
00099 {"lightblue", 173, 216, 230, 0},
00100 {"lightcoral", 240, 128, 128, 0},
00101 {"lightcyan", 224, 255, 255, 0},
00102 {"lightgoldenrodyellow", 250, 250, 210, 0},
00103 {"lightgray", 211, 211, 211, 0},
00104 {"lightgreen", 144, 238, 144, 0},
00105 {"lightgrey", 211, 211, 211, 0},
00106 {"lightpink", 255, 182, 193, 0},
00107 {"lightsalmon", 255, 160, 122, 0},
00108 {"lightseagreen", 32, 178, 170, 0},
00109 {"lightskyblue", 135, 206, 250, 0},
00110 {"lightslategray", 119, 136, 153, 0},
00111 {"lightslategrey", 119, 136, 153, 0},
00112 {"lightsteelblue", 176, 196, 222, 0},
00113 {"lightyellow", 255, 255, 224, 0},
00114 {"lime", 0, 255, 0, 0},
00115 {"limegreen", 50, 205, 50, 0},
00116 {"linen", 250, 240, 230, 0},
00117 {"magenta", 255, 0, 255, 0},
00118 {"maroon", 128, 0, 0, 0},
00119 {"mediumaquamarine", 102, 205, 170, 0},
00120 {"mediumblue", 0, 0, 205, 0},
00121 {"mediumorchid", 186, 85, 211, 0},
00122 {"mediumpurple", 147, 112, 219, 0},
00123 {"mediumseagreen", 60, 179, 113, 0},
00124 {"mediumslateblue", 123, 104, 238, 0},
00125 {"mediumspringgreen", 0, 250, 154, 0},
00126 {"mediumturquoise", 72, 209, 204, 0},
00127 {"mediumvioletred", 199, 21, 133, 0},
00128 {"midnightblue", 25, 25, 112, 0},
00129 {"mintcream", 245, 255, 250, 0},
00130 {"mistyrose", 255, 228, 225, 0},
00131 {"moccasin", 255, 228, 181, 0},
00132 {"navajowhite", 255, 222, 173, 0},
00133 {"navy", 0, 0, 128, 0},
00134 {"oldlace", 253, 245, 230, 0},
00135 {"olive", 128, 128, 0, 0},
00136 {"olivedrab", 107, 142, 35, 0},
00137 {"orange", 255, 165, 0, 0},
00138 {"orangered", 255, 69, 0, 0},
00139 {"orchid", 218, 112, 214, 0},
00140 {"palegoldenrod", 238, 232, 170, 0},
00141 {"palegreen", 152, 251, 152, 0},
00142 {"paleturquoise", 175, 238, 238, 0},
00143 {"palevioletred", 219, 112, 147, 0},
00144 {"papayawhip", 255, 239, 213, 0},
00145 {"peachpuff", 255, 218, 185, 0},
00146 {"peru", 205, 133, 63, 0},
00147 {"pink", 255, 192, 203, 0},
00148 {"plum", 221, 160, 221, 0},
00149 {"powderblue", 176, 224, 230, 0},
00150 {"purple", 128, 0, 128, 0},
00151 {"red", 255, 0, 0, 0},
00152 {"rosybrown", 188, 143, 143, 0},
00153 {"royalblue", 65, 105, 225, 0},
00154 {"saddlebrown", 139, 69, 19, 0},
00155 {"salmon", 250, 128, 114, 0},
00156 {"sandybrown", 244, 164, 96, 0},
00157 {"seagreen", 46, 139, 87, 0},
00158 {"seashell", 255, 245, 238, 0},
00159 {"sienna", 160, 82, 45, 0},
00160 {"silver", 192, 192, 192, 0},
00161 {"skyblue", 135, 206, 235, 0},
00162 {"slateblue", 106, 90, 205, 0},
00163 {"slategray", 112, 128, 144, 0},
00164 {"slategrey", 112, 128, 144, 0},
00165 {"snow", 255, 250, 250, 0},
00166 {"springgreen", 0, 255, 127, 0},
00167 {"steelblue", 70, 130, 180, 0},
00168 {"tan", 210, 180, 140, 0},
00169 {"teal", 0, 128, 128, 0},
00170 {"thistle", 216, 191, 216, 0},
00171 {"tomato", 255, 99, 71, 0},
00172 {"turquoise", 64, 224, 208, 0},
00173 {"violet", 238, 130, 238, 0},
00174 {"wheat", 245, 222, 179, 0},
00175 {"white", 255, 255, 255, 0},
00176 {"whitesmoke", 245, 245, 245, 0,},
00177 {"yellow", 255, 255, 0, 0,},
00178 {"yellowgreen", 154, 205, 50, 0,},
00179 {"transparent", 255, 255, 255, 0, 0, 1}
00180 };
00181
00182
00183
00184
00185
00186
00187
00188
00189 CRRgb *
00190 cr_rgb_new (void)
00191 {
00192 CRRgb *result = NULL;
00193
00194 result = g_try_malloc (sizeof (CRRgb));
00195
00196 if (result == NULL) {
00197 cr_utils_trace_info ("No more memory");
00198 return NULL;
00199 }
00200
00201 memset (result, 0, sizeof (CRRgb));
00202
00203 return result;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 CRRgb *
00219 cr_rgb_new_with_vals (gulong a_red, gulong a_green,
00220 gulong a_blue, gboolean a_is_percentage)
00221 {
00222 CRRgb *result = NULL;
00223
00224 result = cr_rgb_new ();
00225
00226 g_return_val_if_fail (result, NULL);
00227
00228 result->red = a_red;
00229 result->green = a_green;
00230 result->blue = a_blue;
00231 result->is_percentage = a_is_percentage;
00232
00233 return result;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 guchar *
00246 cr_rgb_to_string (CRRgb * a_this)
00247 {
00248 guchar *result = NULL;
00249 GString *str_buf = NULL;
00250
00251 str_buf = g_string_new (NULL);
00252 g_return_val_if_fail (str_buf, NULL);
00253
00254 if (a_this->is_percentage == 1) {
00255 g_string_append_printf (str_buf, "%ld", a_this->red);
00256
00257 g_string_append (str_buf, "%, ");
00258
00259 g_string_append_printf (str_buf, "%ld", a_this->green);
00260 g_string_append (str_buf, "%, ");
00261
00262 g_string_append_printf (str_buf, "%ld", a_this->blue);
00263 g_string_append_c (str_buf, '%');
00264 } else {
00265 g_string_append_printf (str_buf, "%ld", a_this->red);
00266 g_string_append (str_buf, ", ");
00267
00268 g_string_append_printf (str_buf, "%ld", a_this->green);
00269 g_string_append (str_buf, ", ");
00270
00271 g_string_append_printf (str_buf, "%ld", a_this->blue);
00272 }
00273
00274 if (str_buf) {
00275 result = str_buf->str;
00276 g_string_free (str_buf, FALSE);
00277 }
00278
00279 return result;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 void
00292 cr_rgb_dump (CRRgb * a_this, FILE * a_fp)
00293 {
00294 guchar *str = NULL;
00295
00296 g_return_if_fail (a_this);
00297
00298 str = cr_rgb_to_string (a_this);
00299
00300 if (str) {
00301 fprintf (a_fp, "%s", str);
00302 g_free (str);
00303 str = NULL;
00304 }
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 enum CRStatus
00317 cr_rgb_compute_from_percentage (CRRgb * a_this)
00318 {
00319 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00320
00321 if (a_this->is_percentage == FALSE)
00322 return CR_OK;
00323 a_this->red = a_this->red * 255 / 100;
00324 a_this->green = a_this->green * 255 / 100;
00325 a_this->blue = a_this->blue * 255 / 100;
00326 a_this->is_percentage = FALSE;
00327 return CR_OK;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 enum CRStatus
00343 cr_rgb_set (CRRgb * a_this, gulong a_red,
00344 gulong a_green, gulong a_blue, gboolean a_is_percentage)
00345 {
00346 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00347 if (a_is_percentage != FALSE) {
00348 g_return_val_if_fail (a_red <= 100
00349 && a_green <= 100
00350 && a_blue <= 100, CR_BAD_PARAM_ERROR);
00351 }
00352
00353 a_this->is_percentage = a_is_percentage;
00354
00355 a_this->red = a_red;
00356 a_this->green = a_green;
00357 a_this->blue = a_blue;
00358 a_this->inherit = FALSE ;
00359 a_this->is_transparent = FALSE ;
00360 return CR_OK;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 enum CRStatus
00374 cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit)
00375 {
00376 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
00377
00378 a_this->inherit = a_inherit ;
00379
00380 return CR_OK ;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390 gboolean
00391 cr_rgb_is_set_to_inherit (CRRgb *a_this)
00392 {
00393 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
00394
00395 return a_this->inherit ;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 gboolean
00410 cr_rgb_is_set_to_transparent (CRRgb *a_this)
00411 {
00412 g_return_val_if_fail (a_this, FALSE) ;
00413 return a_this->is_transparent ;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 enum CRStatus
00426 cr_rgb_set_to_transparent (CRRgb *a_this,
00427 gboolean a_is_transparent)
00428 {
00429 g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
00430 a_this->is_transparent = a_is_transparent ;
00431 return CR_OK ;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 enum CRStatus
00444 cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb * a_rgb)
00445 {
00446 g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR);
00447
00448 cr_rgb_copy (a_this, a_rgb) ;
00449
00450 return CR_OK;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460 enum CRStatus
00461 cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name)
00462 {
00463 gulong i = 0;
00464 enum CRStatus status = CR_OK;
00465
00466 g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR);
00467
00468 for (i = 0; i < sizeof (gv_standard_colors); i++) {
00469 if (!strcmp (a_color_name, gv_standard_colors[i].name)) {
00470 cr_rgb_set_from_rgb (a_this, &gv_standard_colors[i]);
00471 break;
00472 }
00473 }
00474
00475 if (i < sizeof (gv_standard_colors))
00476 status = CR_OK;
00477 else
00478 status = CR_UNKNOWN_TYPE_ERROR;
00479
00480 return status;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490 enum CRStatus
00491 cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex)
00492 {
00493 enum CRStatus status = CR_OK;
00494 gulong i = 0;
00495 guchar colors[3] = { 0 };
00496
00497 g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR);
00498
00499 if (strlen (a_hex) == 3) {
00500 for (i = 0; i < 3; i++) {
00501 if (a_hex[i] >= '0' && a_hex[i] <= '9') {
00502 colors[i] = a_hex[i] - '0';
00503 colors[i] = (colors[i] << 4) | colors[i];
00504 } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
00505 colors[i] = 10 + a_hex[i] - 'a';
00506 colors[i] = (colors[i] << 4) | colors[i];
00507 } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
00508 colors[i] = 10 + a_hex[i] - 'A';
00509 colors[i] = (colors[i] << 4) | colors[i];
00510 } else {
00511 status = CR_UNKNOWN_TYPE_ERROR;
00512 }
00513 }
00514 } else if (strlen (a_hex) == 6) {
00515 for (i = 0; i < 6; i++) {
00516 if (a_hex[i] >= '0' && a_hex[i] <= '9') {
00517 colors[i / 2] <<= 4;
00518 colors[i / 2] |= a_hex[i] - '0';
00519 status = CR_OK;
00520 } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
00521 colors[i / 2] <<= 4;
00522 colors[i / 2] |= 10 + a_hex[i] - 'a';
00523 status = CR_OK;
00524 } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
00525 colors[i / 2] <<= 4;
00526 colors[i / 2] |= 10 + a_hex[i] - 'A';
00527 status = CR_OK;
00528 } else {
00529 status = CR_UNKNOWN_TYPE_ERROR;
00530 }
00531 }
00532 } else {
00533 status = CR_UNKNOWN_TYPE_ERROR;
00534 }
00535
00536 if (status == CR_OK) {
00537 status = cr_rgb_set (a_this, colors[0],
00538 colors[1], colors[2], FALSE);
00539 cr_rgb_set_to_transparent (a_this, FALSE) ;
00540 }
00541 return status;
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 enum CRStatus
00554 cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value)
00555 {
00556 enum CRStatus status = CR_OK ;
00557 g_return_val_if_fail (a_this && a_value,
00558 CR_BAD_PARAM_ERROR) ;
00559
00560 switch(a_value->type) {
00561 case TERM_RGB:
00562 if (a_value->content.rgb) {
00563 cr_rgb_set_from_rgb
00564 (a_this, a_value->content.rgb) ;
00565 }
00566 break ;
00567 case TERM_IDENT:
00568 if (a_value->content.str
00569 && a_value->content.str->stryng
00570 && a_value->content.str->stryng->str) {
00571 if (!strncmp ("inherit",
00572 a_value->content.str->stryng->str,
00573 sizeof ("inherit")-1)) {
00574 a_this->inherit = TRUE;
00575 a_this->is_transparent = FALSE ;
00576 } else {
00577 status = cr_rgb_set_from_name
00578 (a_this,
00579 a_value->content.str->stryng->str) ;
00580 }
00581 } else {
00582 cr_utils_trace_info
00583 ("a_value has NULL string value") ;
00584 }
00585 break ;
00586 case TERM_HASH:
00587 if (a_value->content.str
00588 && a_value->content.str->stryng
00589 && a_value->content.str->stryng->str) {
00590 status = cr_rgb_set_from_hex_str
00591 (a_this,
00592 a_value->content.str->stryng->str) ;
00593 } else {
00594 cr_utils_trace_info
00595 ("a_value has NULL string value") ;
00596 }
00597 break ;
00598 default:
00599 status = CR_UNKNOWN_TYPE_ERROR ;
00600 }
00601 return status ;
00602 }
00603
00604 enum CRStatus
00605 cr_rgb_copy (CRRgb *a_dest, CRRgb*a_src)
00606 {
00607 g_return_val_if_fail (a_dest && a_src,
00608 CR_BAD_PARAM_ERROR) ;
00609
00610 memcpy (a_dest, a_src, sizeof (CRRgb)) ;
00611 return CR_OK ;
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621 void
00622 cr_rgb_destroy (CRRgb * a_this)
00623 {
00624 g_return_if_fail (a_this);
00625 g_free (a_this);
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 CRRgb *
00638 cr_rgb_parse_from_buf (const guchar *a_str,
00639 enum CREncoding a_enc)
00640 {
00641 enum CRStatus status = CR_OK ;
00642 CRTerm *value = NULL ;
00643 CRParser * parser = NULL;
00644 CRRgb *result = NULL;
00645
00646 g_return_val_if_fail (a_str, NULL);
00647
00648 parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str),
00649 a_enc, FALSE) ;
00650
00651 g_return_val_if_fail (parser, NULL);
00652
00653 status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
00654 if (status != CR_OK)
00655 goto cleanup;
00656
00657 status = cr_parser_parse_term (parser, &value);
00658 if (status != CR_OK)
00659 goto cleanup;
00660
00661 result = cr_rgb_new ();
00662 if (!result)
00663 goto cleanup;
00664
00665 status = cr_rgb_set_from_term (result, value);
00666
00667 cleanup:
00668 if (parser) {
00669 cr_parser_destroy (parser);
00670 parser = NULL;
00671 }
00672 if (value) {
00673 cr_term_destroy(value);
00674 value = NULL;
00675 }
00676 return result ;
00677 }
00678