Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

cr-rgb.c

Go to the documentation of this file.
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
00002 
00003 /*
00004  * This file is part of The Croco Library
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of version 2.1 of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00018  * USA
00019  * 
00020  * See COPYRIGHTS file for copyrights information.
00021  */
00022 
00023 
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include "cr-rgb.h"
00027 #include "cr-term.h"
00028 #include "cr-parser.h"
00029 
00030 static CRRgb gv_standard_colors[] = {
00031         {"aliceblue", 240, 248, 255, 0},
00032         {"antiquewhite", 250, 235, 215, 0},
00033         {"aqua", 0, 255, 255, 0},
00034         {"aquamarine", 127, 255, 212, 0},
00035         {"azure", 240, 255, 255, 0},
00036         {"beige", 245, 245, 220, 0},
00037         {"bisque", 255, 228, 196, 0},
00038         {"black", 0, 0, 0, 0},
00039         {"blanchedalmond", 255, 235, 205, 0},
00040         {"blue", 0, 0, 255, 0},
00041         {"blueviolet", 138, 43, 226, 0},
00042         {"brown", 165, 42, 42, 0},
00043         {"burlywood", 222, 184, 135, 0},
00044         {"cadetblue", 95, 158, 160, 0},
00045         {"chartreuse", 127, 255, 0, 0},
00046         {"chocolate", 210, 105, 30, 0},
00047         {"coral", 255, 127, 80, 0},
00048         {"cornflowerblue", 100, 149, 237, 0},
00049         {"cornsilk", 255, 248, 220, 0},
00050         {"crimson", 220, 20, 60, 0},
00051         {"cyan", 0, 255, 255, 0},
00052         {"darkblue", 0, 0, 139, 0},
00053         {"darkcyan", 0, 139, 139, 0},
00054         {"darkgoldenrod", 184, 134, 11, 0},
00055         {"darkgray", 169, 169, 169, 0},
00056         {"darkgreen", 0, 100, 0, 0},
00057         {"darkgrey", 169, 169, 169, 0},
00058         {"darkkhaki", 189, 183, 107, 0},
00059         {"darkmagenta", 139, 0, 139, 0},
00060         {"darkolivegreen", 85, 107, 47, 0},
00061         {"darkorange", 255, 140, 0, 0},
00062         {"darkorchid", 153, 50, 204, 0},
00063         {"darkred", 139, 0, 0, 0},
00064         {"darksalmon", 233, 150, 122, 0},
00065         {"darkseagreen", 143, 188, 143, 0},
00066         {"darkslateblue", 72, 61, 139, 0},
00067         {"darkslategray", 47, 79, 79, 0},
00068         {"darkslategrey", 47, 79, 79, 0},
00069         {"darkturquoise", 0, 206, 209, 0},
00070         {"darkviolet", 148, 0, 211, 0},
00071         {"deeppink", 255, 20, 147, 0},
00072         {"deepskyblue", 0, 191, 255, 0},
00073         {"dimgray", 105, 105, 105, 0},
00074         {"dimgrey", 105, 105, 105, 0},
00075         {"dodgerblue", 30, 144, 255, 0},
00076         {"firebrick", 178, 34, 34, 0},
00077         {"floralwhite", 255, 250, 240, 0},
00078         {"forestgreen", 34, 139, 34, 0},
00079         {"fuchsia", 255, 0, 255, 0},
00080         {"gainsboro", 220, 220, 220, 0},
00081         {"ghostwhite", 248, 248, 255, 0},
00082         {"gold", 255, 215, 0, 0},
00083         {"goldenrod", 218, 165, 32, 0},
00084         {"gray", 128, 128, 128, 0},
00085         {"grey", 128, 128, 128, 0},
00086         {"green", 0, 128, 0, 0},
00087         {"greenyellow", 173, 255, 47, 0},
00088         {"honeydew", 240, 255, 240, 0},
00089         {"hotpink", 255, 105, 180, 0},
00090         {"indianred", 205, 92, 92, 0},
00091         {"indigo", 75, 0, 130, 0},
00092         {"ivory", 255, 255, 240, 0},
00093         {"khaki", 240, 230, 140, 0},
00094         {"lavender", 230, 230, 250, 0},
00095         {"lavenderblush", 255, 240, 245, 0},
00096         {"lawngreen", 124, 252, 0, 0},
00097         {"lemonchiffon", 255, 250, 205, 0},
00098         {"lightblue", 173, 216, 230, 0},
00099         {"lightcoral", 240, 128, 128, 0},
00100         {"lightcyan", 224, 255, 255, 0},
00101         {"lightgoldenrodyellow", 250, 250, 210, 0},
00102         {"lightgray", 211, 211, 211, 0},
00103         {"lightgreen", 144, 238, 144, 0},
00104         {"lightgrey", 211, 211, 211, 0},
00105         {"lightpink", 255, 182, 193, 0},
00106         {"lightsalmon", 255, 160, 122, 0},
00107         {"lightseagreen", 32, 178, 170, 0},
00108         {"lightskyblue", 135, 206, 250, 0},
00109         {"lightslategray", 119, 136, 153, 0},
00110         {"lightslategrey", 119, 136, 153, 0},
00111         {"lightsteelblue", 176, 196, 222, 0},
00112         {"lightyellow", 255, 255, 224, 0},
00113         {"lime", 0, 255, 0, 0},
00114         {"limegreen", 50, 205, 50, 0},
00115         {"linen", 250, 240, 230, 0},
00116         {"magenta", 255, 0, 255, 0},
00117         {"maroon", 128, 0, 0, 0},
00118         {"mediumaquamarine", 102, 205, 170, 0},
00119         {"mediumblue", 0, 0, 205, 0},
00120         {"mediumorchid", 186, 85, 211, 0},
00121         {"mediumpurple", 147, 112, 219, 0},
00122         {"mediumseagreen", 60, 179, 113, 0},
00123         {"mediumslateblue", 123, 104, 238, 0},
00124         {"mediumspringgreen", 0, 250, 154, 0},
00125         {"mediumturquoise", 72, 209, 204, 0},
00126         {"mediumvioletred", 199, 21, 133, 0},
00127         {"midnightblue", 25, 25, 112, 0},
00128         {"mintcream", 245, 255, 250, 0},
00129         {"mistyrose", 255, 228, 225, 0},
00130         {"moccasin", 255, 228, 181, 0},
00131         {"navajowhite", 255, 222, 173, 0},
00132         {"navy", 0, 0, 128, 0},
00133         {"oldlace", 253, 245, 230, 0},
00134         {"olive", 128, 128, 0, 0},
00135         {"olivedrab", 107, 142, 35, 0},
00136         {"orange", 255, 165, 0, 0},
00137         {"orangered", 255, 69, 0, 0},
00138         {"orchid", 218, 112, 214, 0},
00139         {"palegoldenrod", 238, 232, 170, 0},
00140         {"palegreen", 152, 251, 152, 0},
00141         {"paleturquoise", 175, 238, 238, 0},
00142         {"palevioletred", 219, 112, 147, 0},
00143         {"papayawhip", 255, 239, 213, 0},
00144         {"peachpuff", 255, 218, 185, 0},
00145         {"peru", 205, 133, 63, 0},
00146         {"pink", 255, 192, 203, 0},
00147         {"plum", 221, 160, 221, 0},
00148         {"powderblue", 176, 224, 230, 0},
00149         {"purple", 128, 0, 128, 0},
00150         {"red", 255, 0, 0, 0},
00151         {"rosybrown", 188, 143, 143, 0},
00152         {"royalblue", 65, 105, 225, 0},
00153         {"saddlebrown", 139, 69, 19, 0},
00154         {"salmon", 250, 128, 114, 0},
00155         {"sandybrown", 244, 164, 96, 0},
00156         {"seagreen", 46, 139, 87, 0},
00157         {"seashell", 255, 245, 238, 0},
00158         {"sienna", 160, 82, 45, 0},
00159         {"silver", 192, 192, 192, 0},
00160         {"skyblue", 135, 206, 235, 0},
00161         {"slateblue", 106, 90, 205, 0},
00162         {"slategray", 112, 128, 144, 0},
00163         {"slategrey", 112, 128, 144, 0},
00164         {"snow", 255, 250, 250, 0},
00165         {"springgreen", 0, 255, 127, 0},
00166         {"steelblue", 70, 130, 180, 0},
00167         {"tan", 210, 180, 140, 0},
00168         {"teal", 0, 128, 128, 0},
00169         {"thistle", 216, 191, 216, 0},
00170         {"tomato", 255, 99, 71, 0},
00171         {"turquoise", 64, 224, 208, 0},
00172         {"violet", 238, 130, 238, 0},
00173         {"wheat", 245, 222, 179, 0},
00174         {"white", 255, 255, 255, 0},
00175         {"whitesmoke", 245, 245, 245, 0},
00176         {"yellow", 255, 255, 0, 0},
00177         {"yellowgreen", 154, 205, 50, 0}
00178 };
00179 
00180 /**
00181  *The default constructor of #CRRgb.
00182  *@return the newly built instance of #CRRgb
00183  */
00184 CRRgb *
00185 cr_rgb_new (void)
00186 {
00187         CRRgb *result = NULL;
00188 
00189         result = g_try_malloc (sizeof (CRRgb));
00190 
00191         if (result == NULL) {
00192                 cr_utils_trace_info ("No more memory");
00193                 return NULL;
00194         }
00195 
00196         memset (result, 0, sizeof (CRRgb));
00197 
00198         return result;
00199 }
00200 
00201 /**
00202  *A constructor of #CRRgb.
00203  *@param a_red the red component of the color.
00204  *@param a_green the green component of the color.
00205  *@param a_blue the blue component of the color.
00206  *@param a_unit the unit of the rgb values.
00207  *(either percentage or integer values)
00208  *@return the newly built instance of #CRRgb.
00209  */
00210 CRRgb *
00211 cr_rgb_new_with_vals (gulong a_red, gulong a_green,
00212                       gulong a_blue, gboolean a_is_percentage)
00213 {
00214         CRRgb *result = NULL;
00215 
00216         result = cr_rgb_new ();
00217 
00218         g_return_val_if_fail (result, NULL);
00219 
00220         result->red = a_red;
00221         result->green = a_green;
00222         result->blue = a_blue;
00223         result->is_percentage = a_is_percentage;
00224 
00225         return result;
00226 }
00227 
00228 /**
00229  *Serializes the rgb into a zero terminated string.
00230  *@param a_this the instance of #CRRgb to serialize.
00231  *@return the zero terminated string containing the serialized
00232  *rgb. MUST BE FREED by the caller using g_free().
00233  */
00234 guchar *
00235 cr_rgb_to_string (CRRgb * a_this)
00236 {
00237         guchar *result = NULL;
00238         GString *str_buf = NULL;
00239 
00240         str_buf = g_string_new (NULL);
00241         g_return_val_if_fail (str_buf, NULL);
00242 
00243         if (a_this->is_percentage == TRUE) {
00244                 g_string_append_printf (str_buf, "%ld", a_this->red);
00245 
00246                 g_string_append_c (str_buf, '%');
00247                 g_string_append_printf (str_buf, ", ");
00248 
00249                 g_string_append_printf (str_buf, "%ld", a_this->green);
00250                 g_string_append_c (str_buf, '%');;
00251                 g_string_append_printf (str_buf, ", ");
00252 
00253                 g_string_append_printf (str_buf, "%ld", a_this->blue);
00254                 g_string_append_c (str_buf, '%');
00255         } else {
00256                 g_string_append_printf (str_buf, "%ld", a_this->red);
00257                 g_string_append_printf (str_buf, ", ");
00258 
00259                 g_string_append_printf (str_buf, "%ld", a_this->green);
00260                 g_string_append_printf (str_buf, ", ");
00261 
00262                 g_string_append_printf (str_buf, "%ld", a_this->blue);
00263         }
00264 
00265         if (str_buf) {
00266                 result = str_buf->str;
00267                 g_string_free (str_buf, FALSE);
00268         }
00269 
00270         return result;
00271 }
00272 
00273 /**
00274  *Dumps the current instance of #CRRgb
00275  *to a file.
00276  *@param a_this the "this pointer" of
00277  *the current instance of #CRRgb.
00278  *@param a_fp the destination file pointer.
00279  */
00280 void
00281 cr_rgb_dump (CRRgb * a_this, FILE * a_fp)
00282 {
00283         guchar *str = NULL;
00284 
00285         g_return_if_fail (a_this);
00286 
00287         str = cr_rgb_to_string (a_this);
00288 
00289         if (str) {
00290                 fprintf (a_fp, "%s", str);
00291                 g_free (str);
00292                 str = NULL;
00293         }
00294 }
00295 
00296 /**
00297  *If the rgb values are expressed in percentage,
00298  *compute their real value.
00299  *@param a_this the current instance of #CRRgb
00300  *@return
00301  */
00302 enum CRStatus
00303 cr_rgb_compute_from_percentage (CRRgb * a_this)
00304 {
00305         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00306 
00307         if (a_this->is_percentage == FALSE)
00308                 return CR_OK;
00309         a_this->red = a_this->red * 255 / 100;
00310         a_this->green = a_this->green * 255 / 100;
00311         a_this->blue = a_this->blue * 255 / 100;
00312         a_this->is_percentage = FALSE;
00313         return CR_OK;
00314 }
00315 
00316 /**
00317  *Sets rgb values to the RGB.
00318  *@param a_this the current instance of #CRRgb.
00319  *@param a_red the red value.
00320  *@param a_green the green value.
00321  *@param a_blue the blue value.
00322  *@return CR_OK upon successful completion, an error code
00323  *otherwise.
00324  */
00325 enum CRStatus
00326 cr_rgb_set (CRRgb * a_this, gulong a_red,
00327             gulong a_green, gulong a_blue, gboolean a_is_percentage)
00328 {
00329         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00330         if (a_is_percentage != FALSE) {
00331                 g_return_val_if_fail (a_red <= 100
00332                                       && a_green <= 100
00333                                       && a_blue <= 100, CR_BAD_PARAM_ERROR);
00334         }
00335 
00336         a_this->is_percentage = a_is_percentage;
00337 
00338         a_this->red = a_red;
00339         a_this->green = a_green;
00340         a_this->blue = a_blue;
00341 
00342         return CR_OK;
00343 }
00344 
00345 /**
00346  *Sets the rgb from an other one.
00347  *@param a_this the current instance of #CRRgb.
00348  *@param a_rgb the rgb to "copy"
00349  *@return CR_OK upon successful completion, an error code otherwise.
00350  */
00351 enum CRStatus
00352 cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb * a_rgb)
00353 {
00354         g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR);
00355 
00356         cr_rgb_set (a_this, a_rgb->red, a_rgb->green,
00357                     a_rgb->blue, a_rgb->is_percentage);
00358 
00359         return CR_OK;
00360 }
00361 
00362 enum CRStatus
00363 cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name)
00364 {
00365         gulong i = 0;
00366         enum CRStatus status = CR_OK;
00367 
00368         g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR);
00369 
00370         for (i = 0; i < sizeof (gv_standard_colors); i++) {
00371                 if (!strcmp (a_color_name, gv_standard_colors[i].name)) {
00372                         cr_rgb_set_from_rgb (a_this, &gv_standard_colors[i]);
00373                         break;
00374                 }
00375         }
00376 
00377         if (i < sizeof (gv_standard_colors))
00378                 status = CR_OK;
00379         else
00380                status = CR_UNKNOWN_TYPE_ERROR;
00381 
00382         return status;
00383 }
00384 
00385 enum CRStatus
00386 cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex)
00387 {
00388         enum CRStatus status = CR_OK;
00389         gulong i = 0;
00390         guchar colors[3] = { 0 };
00391 
00392         g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR);
00393 
00394         if (strlen (a_hex) == 3) {
00395                 for (i = 0; i < 3; i++) {
00396                         if (a_hex[i] >= '0' && a_hex[i] <= '9') {
00397                                 colors[i] = a_hex[i] - '0';
00398                                 colors[i] = (colors[i] << 4) | colors[i];
00399                         } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
00400                                 colors[i] = 10 + a_hex[i] - 'a';
00401                                 colors[i] = (colors[i] << 4) | colors[i];
00402                         } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
00403                                 colors[i] = 10 + a_hex[i] - 'A';
00404                                 colors[i] = (colors[i] << 4) | colors[i];
00405                         } else {
00406                                 status = CR_UNKNOWN_TYPE_ERROR;
00407                         }
00408                 }
00409         } else if (strlen (a_hex) == 6) {
00410                 for (i = 0; i < 6; i++) {
00411                         if (a_hex[i] >= '0' && a_hex[i] <= '9') {
00412                                 colors[i / 2] <<= 4;
00413                                 colors[i / 2] |= a_hex[i] - '0';
00414                                 status = CR_OK;
00415                         } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') {
00416                                 colors[i / 2] <<= 4;
00417                                 colors[i / 2] |= 10 + a_hex[i] - 'a';
00418                                 status = CR_OK;
00419                         } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') {
00420                                 colors[i / 2] <<= 4;
00421                                 colors[i / 2] |= 10 + a_hex[i] - 'A';
00422                                 status = CR_OK;
00423                         } else {
00424                                 status = CR_UNKNOWN_TYPE_ERROR;
00425                         }
00426                 }
00427         } else {
00428                 status = CR_UNKNOWN_TYPE_ERROR;
00429         }
00430 
00431         if (status == CR_OK) {
00432                 status = cr_rgb_set (a_this, colors[0],
00433                                      colors[1], colors[2], FALSE);
00434         }
00435         return status;
00436 }
00437 
00438 /**
00439  *Set the rgb from a terminal symbol
00440  *@param a_this the instance of #CRRgb to set
00441  *@param a_value the terminal from which to set
00442  */
00443 enum CRStatus
00444 cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value)
00445 {
00446         enum CRStatus status = CR_OK ;
00447         g_return_val_if_fail (a_this && a_value,
00448                               CR_BAD_PARAM_ERROR) ;
00449 
00450         switch(a_value->type) {
00451         case TERM_RGB:
00452                 if (a_value->content.rgb) {
00453                         cr_rgb_set_from_rgb
00454                                 (a_this, a_value->content.rgb) ;
00455                 }
00456                 break ;
00457         case TERM_IDENT:
00458                 status = cr_rgb_set_from_name 
00459                         (a_this,
00460                          a_value->content.str->str) ;
00461                 break ;
00462         case TERM_HASH:
00463                 status = cr_rgb_set_from_hex_str
00464                         (a_this, 
00465                          a_value->content.str->str) ;
00466                 break ;
00467         default:
00468                 status =  CR_UNKNOWN_TYPE_ERROR ;
00469         }
00470 
00471         return status ;
00472 }
00473 
00474 /**
00475  *Destructor of #CRRgb.
00476  *@param a_this the "this pointer" of the
00477  *current instance of #CRRgb.
00478  */
00479 void
00480 cr_rgb_destroy (CRRgb * a_this)
00481 {
00482         g_return_if_fail (a_this);
00483 
00484         g_free (a_this);
00485 }
00486 
00487 /**
00488  *Parses a text buffer that contains a rgb color
00489  *
00490  *@param a_str a string that contains a color description
00491  *@param a_enc the encoding of a_str
00492  *@return the parsed color, or NULL in case of error
00493  */
00494 CRRgb *cr_rgb_parse_from_buf (const guchar *a_str,
00495                               enum CREncoding a_enc)
00496 {
00497         enum CRStatus status = CR_OK ;
00498         CRTerm *value = NULL ;
00499         CRParser * parser = NULL;
00500         CRRgb *result = NULL;
00501         
00502         g_return_val_if_fail (a_str, NULL);
00503         
00504         parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), 
00505                                          a_enc, FALSE) ;
00506 
00507         g_return_val_if_fail (parser, NULL);
00508 
00509         status = cr_parser_try_to_skip_spaces_and_comments (parser) ;
00510         if (status != CR_OK)
00511                 goto cleanup;
00512 
00513         status = cr_parser_parse_term (parser, &value);
00514         if (status != CR_OK)
00515                 goto cleanup;
00516 
00517         result = cr_rgb_new ();
00518         if (!result)
00519                 goto cleanup;
00520 
00521         status = cr_rgb_set_from_term (result, value);
00522 
00523 cleanup:
00524         if (parser) {
00525                 cr_parser_destroy (parser);
00526                 parser = NULL;
00527         }
00528         if (value) {
00529                 cr_term_destroy(value);
00530                 value = NULL;
00531         }
00532         return result ;
00533 }
00534                   
00535         
00536           
00537 
00538         

Generated on Sat Mar 20 02:38:43 2004 for Libcroco by doxygen 1.3.5