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