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

cr-style.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 
00008  * the GNU Lesser General Public
00009  * License as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the 
00017  * GNU Lesser General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00020  * USA
00021  *
00022  * Author: Dodji Seketeli.
00023  * see COPYRIGTHS file for copyright information
00024  */
00025 
00026 #include <string.h>
00027 #include "cr-style.h"
00028 
00029 /**
00030  *@file
00031  *The definition of the #CRStyle class.
00032  */
00033 
00034 /**
00035  *A property ID.
00036  *Each supported css property has an ID which is
00037  *an entry into a property "population" jump table.
00038  *each entry of the property population jump table
00039  *contains code to tranform the literal form of
00040  *a property value into a strongly typed value.
00041  */
00042 enum CRPropertyID {
00043         PROP_ID_NOT_KNOWN = 0,
00044         PROP_ID_PADDING_TOP,
00045         PROP_ID_PADDING_RIGHT,
00046         PROP_ID_PADDING_BOTTOM,
00047         PROP_ID_PADDING_LEFT,
00048         PROP_ID_PADDING,
00049         PROP_ID_BORDER_TOP_WIDTH,
00050         PROP_ID_BORDER_RIGHT_WIDTH,
00051         PROP_ID_BORDER_BOTTOM_WIDTH,
00052         PROP_ID_BORDER_LEFT_WIDTH,
00053         PROP_ID_BORDER_WIDTH,
00054         PROP_ID_BORDER_TOP_STYLE,
00055         PROP_ID_BORDER_RIGHT_STYLE,
00056         PROP_ID_BORDER_BOTTOM_STYLE,
00057         PROP_ID_BORDER_LEFT_STYLE,
00058         PROP_ID_BORDER_STYLE,
00059         PROP_ID_BORDER_TOP_COLOR,
00060         PROP_ID_BORDER_RIGHT_COLOR,
00061         PROP_ID_BORDER_BOTTOM_COLOR,
00062         PROP_ID_BORDER_LEFT_COLOR,
00063         PROP_ID_BORDER_TOP,
00064         PROP_ID_BORDER_RIGHT,
00065         PROP_ID_BORDER_BOTTOM,
00066         PROP_ID_BORDER_LEFT,
00067         PROP_ID_BORDER,
00068         PROP_ID_MARGIN_TOP,
00069         PROP_ID_MARGIN_RIGHT,
00070         PROP_ID_MARGIN_BOTTOM,
00071         PROP_ID_MARGIN_LEFT,
00072         PROP_ID_MARGIN,
00073         PROP_ID_DISPLAY,
00074         PROP_ID_POSITION,
00075         PROP_ID_TOP,
00076         PROP_ID_RIGHT,
00077         PROP_ID_BOTTOM,
00078         PROP_ID_LEFT,
00079         PROP_ID_FLOAT,
00080         PROP_ID_WIDTH,
00081         PROP_ID_COLOR,
00082         PROP_ID_BACKGROUND_COLOR,
00083         PROP_ID_FONT_FAMILY,
00084         PROP_ID_FONT_SIZE,
00085         PROP_ID_FONT_STYLE,
00086         PROP_ID_FONT_WEIGHT,
00087         PROP_ID_WHITE_SPACE,
00088         /*should be the last one. */
00089         NB_PROP_IDS
00090 };
00091 
00092 typedef struct _CRPropertyDesc CRPropertyDesc;
00093 
00094 struct _CRPropertyDesc {
00095         const guchar *name;
00096         enum CRPropertyID prop_id;
00097 };
00098 
00099 static CRPropertyDesc gv_prop_table[] = {
00100         {"padding-top", PROP_ID_PADDING_TOP},
00101         {"padding-right", PROP_ID_PADDING_RIGHT},
00102         {"padding-bottom", PROP_ID_PADDING_BOTTOM},
00103         {"padding-left", PROP_ID_PADDING_LEFT},
00104         {"padding", PROP_ID_PADDING},
00105         {"border-top-width", PROP_ID_BORDER_TOP_WIDTH},
00106         {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH},
00107         {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH},
00108         {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH},
00109         {"border-width", PROP_ID_BORDER_WIDTH},
00110         {"border-top-style", PROP_ID_BORDER_TOP_STYLE},
00111         {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE},
00112         {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE},
00113         {"border-left-style", PROP_ID_BORDER_LEFT_STYLE},
00114         {"border-style", PROP_ID_BORDER_STYLE},
00115         {"border-top", PROP_ID_BORDER_TOP},
00116         {"border-right", PROP_ID_BORDER_RIGHT},
00117         {"border-bottom", PROP_ID_BORDER_BOTTOM},
00118         {"border-left", PROP_ID_BORDER_LEFT},
00119         {"border", PROP_ID_BORDER},
00120         {"margin-top", PROP_ID_MARGIN_TOP},
00121         {"margin-right", PROP_ID_MARGIN_RIGHT},
00122         {"margin-bottom", PROP_ID_MARGIN_BOTTOM},
00123         {"margin-left", PROP_ID_MARGIN_LEFT},
00124         {"margin", PROP_ID_MARGIN},
00125         {"display", PROP_ID_DISPLAY},
00126         {"position", PROP_ID_POSITION},
00127         {"top", PROP_ID_TOP},
00128         {"right", PROP_ID_RIGHT},
00129         {"bottom", PROP_ID_BOTTOM},
00130         {"left", PROP_ID_LEFT},
00131         {"float", PROP_ID_FLOAT},
00132         {"width", PROP_ID_WIDTH},
00133         {"color", PROP_ID_COLOR},
00134         {"border-top-color", PROP_ID_BORDER_TOP_COLOR},
00135         {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR},
00136         {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR},
00137         {"border-left-color", PROP_ID_BORDER_LEFT_COLOR},
00138         {"background-color", PROP_ID_BACKGROUND_COLOR},
00139         {"font-family", PROP_ID_FONT_FAMILY},
00140         {"font-size", PROP_ID_FONT_SIZE},
00141         {"font-style", PROP_ID_FONT_STYLE},
00142         {"font-weight", PROP_ID_FONT_WEIGHT},
00143         {"white-space", PROP_ID_WHITE_SPACE},
00144         /*must be the last one */
00145         {NULL, 0}
00146 };
00147 
00148 /**
00149  *A the key/value pair of this hash table
00150  *are:
00151  *key => name of the the css propertie found in gv_prop_table
00152  *value => matching property id found in gv_prop_table.
00153  *So this hash table is here just to retrieval of a property id
00154  *from a property name.
00155  */
00156 static GHashTable *gv_prop_hash = NULL;
00157 
00158 /**
00159  *incremented by each new instance of #CRStyle
00160  *and decremented at the it destroy time.
00161  *When this reaches zero, gv_prop_hash is destroyed.
00162  */
00163 static gulong gv_prop_hash_ref_count = 0;
00164 
00165 struct CRNumPropEnumDumpInfo {
00166         enum CRNumProp code;
00167         const gchar *str;
00168 };
00169 
00170 static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = {
00171         {NUM_PROP_TOP, "top"},
00172         {NUM_PROP_RIGHT, "right"},
00173         {NUM_PROP_BOTTOM, "bottom"},
00174         {NUM_PROP_LEFT, "left"},
00175         {NUM_PROP_PADDING_TOP, "padding-top"},
00176         {NUM_PROP_PADDING_RIGHT, "padding-right"},
00177         {NUM_PROP_PADDING_BOTTOM, "padding-bottom"},
00178         {NUM_PROP_PADDING_LEFT, "padding-left"},
00179         {NUM_PROP_BORDER_TOP, "border-top"},
00180         {NUM_PROP_BORDER_RIGHT, "border-right"},
00181         {NUM_PROP_BORDER_BOTTOM, "border-bottom"},
00182         {NUM_PROP_BORDER_LEFT, "border-left"},
00183         {NUM_PROP_MARGIN_TOP, "margin-top"},
00184         {NUM_PROP_MARGIN_RIGHT, "margin-right"},
00185         {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"},
00186         {NUM_PROP_MARGIN_LEFT, "margin-left"},
00187         {NUM_PROP_WIDTH, "width"},
00188         {0, NULL}
00189 };
00190 
00191 struct CRRgbPropEnumDumpInfo {
00192         enum CRRgbProp code;
00193         const gchar *str;
00194 };
00195 
00196 static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = {
00197         {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"},
00198         {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"},
00199         {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"},
00200         {RGB_PROP_BORDER_LEFT_COLOR, "left-color"},
00201         {RGB_PROP_COLOR, "color"},
00202         {RGB_PROP_BACKGROUND_COLOR, "background-color"},
00203         {0, NULL}
00204 };
00205 
00206 struct CRBorderStylePropEnumDumpInfo {
00207         enum CRBorderStyleProp code;
00208         const gchar *str;
00209 
00210 };
00211 
00212 static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[]
00213         = {
00214         {BORDER_STYLE_PROP_TOP, "border-style-top"},
00215         {BORDER_STYLE_PROP_RIGHT, "border-style-right"},
00216         {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"},
00217         {BORDER_STYLE_PROP_LEFT, "border-style-left"},
00218         {0, NULL}
00219 };
00220 
00221 static enum CRStatus
00222   cr_style_init_properties (void);
00223 
00224 enum CRDirection {
00225         DIR_TOP = 0,
00226         DIR_RIGHT,
00227         DIR_BOTTOM,
00228         DIR_LEFT,
00229 
00230         /*must be the last one */
00231         NB_DIRS
00232 };
00233 
00234 static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
00235 
00236 static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
00237 
00238 static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
00239                                                       a_code);
00240 
00241 static enum CRStatus
00242 set_prop_padding_x_from_value (CRStyle * a_style,
00243                                  CRTerm * a_value, enum CRDirection a_dir);
00244 
00245 static enum CRStatus
00246 set_prop_border_x_width_from_value (CRStyle * a_style,
00247                                     CRTerm * a_value,
00248                                     enum CRDirection a_dir);
00249 static enum CRStatus
00250 set_prop_border_width_from_value (CRStyle *a_style,
00251                                   CRTerm *a_value) ;
00252 
00253 static enum CRStatus
00254 set_prop_border_x_style_from_value (CRStyle * a_style,
00255                                     CRTerm * a_value,
00256                                     enum CRDirection a_dir);
00257 static enum CRStatus
00258 set_prop_border_style_from_value (CRStyle *a_style,
00259                                   CRTerm *a_value) ;
00260 
00261 static enum CRStatus
00262 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
00263                                 enum CRDirection a_dir);
00264 
00265 static enum CRStatus
00266 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
00267 
00268 static enum CRStatus
00269 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
00270 
00271 static enum CRStatus
00272 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
00273                          enum CRDirection a_dir);
00274 
00275 static enum CRStatus
00276 set_prop_float (CRStyle * a_style, CRTerm * a_value);
00277 
00278 static enum CRStatus
00279 set_prop_width (CRStyle * a_style, CRTerm * a_value);
00280 
00281 static enum CRStatus
00282 set_prop_color (CRStyle * a_style, CRTerm * a_value);
00283 
00284 static enum CRStatus
00285 set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
00286 
00287 static enum CRStatus
00288 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
00289                                       enum CRDirection a_dir);
00290 
00291 static enum CRStatus
00292 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
00293                                 enum CRDirection a_dir);
00294 
00295 static enum CRStatus
00296 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
00297 
00298 static enum CRStatus
00299 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
00300 
00301 static enum CRStatus
00302 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
00303 
00304 static enum CRStatus
00305 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
00306 
00307 static enum CRStatus
00308 init_style_font_size_field (CRStyle * a_style);
00309 
00310 static enum CRStatus
00311 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
00312 
00313 static enum CRStatus
00314 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
00315 
00316 static enum CRStatus
00317 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
00318 
00319 static const gchar *
00320 num_prop_code_to_string (enum CRNumProp a_code)
00321 {
00322         gint len = sizeof (gv_num_props_dump_infos) /
00323                 sizeof (struct CRNumPropEnumDumpInfo);
00324         if (a_code >= len) {
00325                 cr_utils_trace_info ("A field has been added "
00326                                      "to 'enum CRNumProp' and no matching"
00327                                      " entry has been "
00328                                      "added to gv_num_prop_dump_infos table.\n"
00329                                      "Please add the missing matching entry");
00330                 return NULL;
00331         }
00332         if (gv_num_props_dump_infos[a_code].code != a_code) {
00333                 cr_utils_trace_info ("mismatch between the order of fields in"
00334                                      " 'enum CRNumProp' and "
00335                                      "the order of entries in "
00336                                      "the gv_num_prop_dump_infos table");
00337                 return NULL;
00338         }
00339         return gv_num_props_dump_infos[a_code].str;
00340 }
00341 
00342 static const gchar *
00343 rgb_prop_code_to_string (enum CRRgbProp a_code)
00344 {
00345         gint len = sizeof (gv_rgb_props_dump_infos) /
00346                 sizeof (struct CRRgbPropEnumDumpInfo);
00347 
00348         if (a_code >= len) {
00349                 cr_utils_trace_info ("A field has been added "
00350                                      "to 'enum CRRgbProp' and no matching"
00351                                      " entry has been "
00352                                      "added to gv_rgb_prop_dump_infos table.\n"
00353                                      "Please add the missing matching entry");
00354                 return NULL;
00355         }
00356         if (gv_rgb_props_dump_infos[a_code].code != a_code) {
00357                 cr_utils_trace_info ("mismatch between the order of fields in"
00358                                      " 'enum CRRgbProp' and "
00359                                      "the order of entries in "
00360                                      "the gv_rgb_props_dump_infos table");
00361                 return NULL;
00362         }
00363         return gv_rgb_props_dump_infos[a_code].str;
00364 }
00365 
00366 static const gchar *
00367 border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
00368 {
00369         gint len = sizeof (gv_border_style_props_dump_infos) /
00370                 sizeof (struct CRBorderStylePropEnumDumpInfo);
00371 
00372         if (a_code >= len) {
00373                 cr_utils_trace_info ("A field has been added "
00374                                      "to 'enum CRBorderStyleProp' and no matching"
00375                                      " entry has been "
00376                                      "added to gv_border_style_prop_dump_infos table.\n"
00377                                      "Please add the missing matching entry");
00378                 return NULL;
00379         }
00380         if (gv_border_style_props_dump_infos[a_code].code != a_code) {
00381                 cr_utils_trace_info ("mismatch between the order of fields in"
00382                                      " 'enum CRBorderStyleProp' and "
00383                                      "the order of entries in "
00384                                      "the gv_border_style_props_dump_infos table");
00385                 return NULL;
00386         }
00387         return gv_border_style_props_dump_infos[a_code].str;
00388 }
00389 
00390 static enum CRStatus
00391 cr_style_init_properties (void)
00392 {
00393 
00394         if (!gv_prop_hash) {
00395                 gulong i = 0;
00396 
00397                 gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal);
00398                 if (!gv_prop_hash) {
00399                         cr_utils_trace_info ("Out of memory");
00400                         return CR_ERROR;
00401                 }
00402 
00403                 /*load gv_prop_hash from gv_prop_table */
00404                 for (i = 0; gv_prop_table[i].name; i++) {
00405                         g_hash_table_insert
00406                                 (gv_prop_hash,
00407                                  (gpointer) gv_prop_table[i].name,
00408                                  GINT_TO_POINTER (gv_prop_table[i].prop_id));
00409                 }
00410         }
00411 
00412         return CR_OK;
00413 }
00414 
00415 static enum CRPropertyID
00416 cr_style_get_prop_id (const guchar * a_prop)
00417 {
00418         gpointer *raw_id = NULL;
00419 
00420         if (!gv_prop_hash) {
00421                 cr_style_init_properties ();
00422         }
00423 
00424         raw_id = g_hash_table_lookup (gv_prop_hash, a_prop);
00425         if (!raw_id) {
00426                 return PROP_ID_NOT_KNOWN;
00427         }
00428         return GPOINTER_TO_INT (raw_id);
00429 }
00430 
00431 static enum CRStatus
00432 set_prop_padding_x_from_value (CRStyle * a_style,
00433                                CRTerm * a_value, enum CRDirection a_dir)
00434 {
00435         enum CRStatus status = CR_OK;
00436         CRNum *num_val = NULL;
00437 
00438         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
00439 
00440         if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
00441                 return CR_BAD_PARAM_ERROR;
00442 
00443         switch (a_dir) {
00444         case DIR_TOP:
00445                 num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
00446                 break;
00447 
00448         case DIR_RIGHT:
00449                 num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
00450                 break;
00451 
00452         case DIR_BOTTOM:
00453                 num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
00454                 break;
00455 
00456         case DIR_LEFT:
00457                 num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
00458                 break;
00459 
00460         default:
00461                 return CR_BAD_PARAM_ERROR;
00462         }
00463 
00464         if (a_value->type == TERM_IDENT) {
00465                 if (a_value->content.str
00466                     && a_value->content.str->stryng
00467                     && a_value->content.str->stryng->str
00468                     && !strncmp ((guchar *) "inherit",
00469                                  a_value->content.str->stryng->str,
00470                                  sizeof ("inherit")-1)) {
00471                         status = cr_num_set (num_val, 0.0, NUM_INHERIT);
00472                         return CR_OK;
00473                 } else
00474                         return CR_UNKNOWN_TYPE_ERROR;
00475         }
00476 
00477         g_return_val_if_fail (a_value->type == TERM_NUMBER
00478                               && a_value->content.num, CR_UNKNOWN_TYPE_ERROR);
00479 
00480         switch (a_value->content.num->type) {
00481         case NUM_LENGTH_EM:
00482         case NUM_LENGTH_EX:
00483         case NUM_LENGTH_PX:
00484         case NUM_LENGTH_IN:
00485         case NUM_LENGTH_CM:
00486         case NUM_LENGTH_MM:
00487         case NUM_LENGTH_PT:
00488         case NUM_LENGTH_PC:
00489         case NUM_PERCENTAGE:
00490                 status = cr_num_copy (num_val, a_value->content.num);
00491                 break;
00492         default:
00493                 status = CR_UNKNOWN_TYPE_ERROR;
00494                 break;
00495         }
00496 
00497         return status;
00498 }
00499 
00500 static enum CRStatus
00501 set_prop_border_x_width_from_value (CRStyle * a_style,
00502                                     CRTerm * a_value, 
00503                                     enum CRDirection a_dir)
00504 {
00505         enum CRStatus status = CR_OK;
00506         CRNum *num_val = NULL;
00507 
00508         g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR);
00509 
00510         switch (a_dir) {
00511         case DIR_TOP:
00512                 num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv;
00513                 break;
00514 
00515         case DIR_RIGHT:
00516                 num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv;
00517                 break;
00518 
00519         case DIR_BOTTOM:
00520                 num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv;
00521                 break;
00522 
00523         case DIR_LEFT:
00524                 num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv;
00525                 break;
00526 
00527         default:
00528                 return CR_BAD_PARAM_ERROR;
00529                 break;
00530         }
00531 
00532         if (a_value->type == TERM_IDENT) {
00533                 if (a_value->content.str 
00534                     && a_value->content.str->stryng
00535                     && a_value->content.str->stryng->str) {
00536                         if (!strncmp ("thin",
00537                                       a_value->content.str->stryng->str,
00538                                       sizeof ("thin")-1)) {
00539                                 cr_num_set (num_val, BORDER_THIN,
00540                                             NUM_LENGTH_PX);
00541                         } else if (!strncmp 
00542                                    ("medium",
00543                                     a_value->content.str->stryng->str,
00544                                              sizeof ("medium")-1)) {
00545                                 cr_num_set (num_val, BORDER_MEDIUM,
00546                                             NUM_LENGTH_PX);
00547                         } else if (!strncmp ("thick",
00548                                              a_value->content.str->stryng->str,
00549                                              sizeof ("thick")-1)) {
00550                                 cr_num_set (num_val, BORDER_THICK,
00551                                             NUM_LENGTH_PX);
00552                         } else {
00553                                 return CR_UNKNOWN_TYPE_ERROR;
00554                         }
00555                 }
00556         } else if (a_value->type == TERM_NUMBER) {
00557                 if (a_value->content.num) {
00558                         cr_num_copy (num_val, a_value->content.num);
00559                 }
00560         } else if (a_value->type != TERM_NUMBER
00561                    || a_value->content.num == NULL) {
00562                 return CR_UNKNOWN_TYPE_ERROR;
00563         }
00564 
00565         return status;
00566 }
00567 
00568 static enum CRStatus
00569 set_prop_border_width_from_value (CRStyle *a_style,
00570                                   CRTerm *a_value)
00571 {
00572         CRTerm *cur_term = NULL ;
00573         enum CRDirection direction = DIR_TOP ;
00574 
00575         g_return_val_if_fail (a_style && a_value,
00576                               CR_BAD_PARAM_ERROR) ;
00577         cur_term = a_value ;
00578 
00579         if (!cur_term)
00580                 return CR_ERROR ;
00581 
00582         for (direction = DIR_TOP ; 
00583              direction < NB_DIRS ; direction ++) {
00584                 set_prop_border_x_width_from_value (a_style, 
00585                                                     cur_term,
00586                                                     direction) ;
00587         }
00588 
00589         cur_term = cur_term->next ;
00590         if (!cur_term)
00591                 return CR_OK ;
00592         set_prop_border_x_width_from_value (a_style, cur_term,
00593                                             DIR_RIGHT) ;
00594         set_prop_border_x_width_from_value (a_style, cur_term,
00595                                             DIR_LEFT) ;
00596 
00597         cur_term = cur_term->next ;
00598         if (!cur_term)
00599                 return CR_OK ;
00600         set_prop_border_x_width_from_value (a_style, cur_term,
00601                                             DIR_BOTTOM) ;
00602 
00603         cur_term = cur_term->next ;
00604         if (!cur_term)
00605                 return CR_OK ;
00606         set_prop_border_x_width_from_value (a_style, cur_term,
00607                                             DIR_LEFT) ;
00608 
00609         return CR_OK ;
00610 }
00611 
00612 static enum CRStatus
00613 set_prop_border_x_style_from_value (CRStyle * a_style,
00614                                     CRTerm * a_value, enum CRDirection a_dir)
00615 {
00616         enum CRStatus status = CR_OK;
00617         enum CRBorderStyle *border_style_ptr = NULL;
00618 
00619         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
00620 
00621         switch (a_dir) {
00622         case DIR_TOP:
00623                 border_style_ptr = &a_style->
00624                         border_style_props[BORDER_STYLE_PROP_TOP];
00625                 break;
00626 
00627         case DIR_RIGHT:
00628                 border_style_ptr =
00629                         &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
00630                 break;
00631 
00632         case DIR_BOTTOM:
00633                 border_style_ptr = &a_style->
00634                         border_style_props[BORDER_STYLE_PROP_BOTTOM];
00635                 break;
00636 
00637         case DIR_LEFT:
00638                 border_style_ptr = &a_style->
00639                         border_style_props[BORDER_STYLE_PROP_LEFT];
00640                 break;
00641 
00642         default:
00643                 break;
00644         }
00645 
00646         if (a_value->type != TERM_IDENT || !a_value->content.str) {
00647                 return CR_UNKNOWN_TYPE_ERROR;
00648         }
00649 
00650         if (!strncmp ("none", 
00651                       a_value->content.str->stryng->str, 
00652                       sizeof ("none")-1)) {
00653                 *border_style_ptr = BORDER_STYLE_NONE;
00654         } else if (!strncmp ("hidden",
00655                              a_value->content.str->stryng->str, 
00656                              sizeof ("hidden")-1)) {
00657                 *border_style_ptr = BORDER_STYLE_HIDDEN;
00658         } else if (!strncmp ("dotted",
00659                              a_value->content.str->stryng->str, 
00660                              sizeof ("dotted")-1)) {
00661                 *border_style_ptr = BORDER_STYLE_DOTTED;
00662         } else if (!strncmp ("dashed",
00663                              a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
00664                 *border_style_ptr = BORDER_STYLE_DASHED;
00665         } else if (!strncmp ("solid",
00666                              a_value->content.str->stryng->str, sizeof ("solid")-1)) {
00667                 *border_style_ptr = BORDER_STYLE_SOLID;
00668         } else if (!strncmp ("double",
00669                              a_value->content.str->stryng->str, sizeof ("double")-1)) {
00670                 *border_style_ptr = BORDER_STYLE_DOUBLE;
00671         } else if (!strncmp ("groove",
00672                              a_value->content.str->stryng->str, sizeof ("groove")-1)) {
00673                 *border_style_ptr = BORDER_STYLE_GROOVE;
00674         } else if (!strncmp ("ridge",
00675                              a_value->content.str->stryng->str, 
00676                              sizeof ("ridge")-1)) {
00677                 *border_style_ptr = BORDER_STYLE_RIDGE;
00678         } else if (!strncmp ("inset",
00679                              a_value->content.str->stryng->str, 
00680                              sizeof ("inset")-1)) {
00681                 *border_style_ptr = BORDER_STYLE_INSET;
00682         } else if (!strncmp ("outset",
00683                              a_value->content.str->stryng->str, 
00684                              sizeof ("outset")-1)) {
00685                 *border_style_ptr = BORDER_STYLE_OUTSET;
00686         } else if (!strncmp ("inherit",
00687                              a_value->content.str->stryng->str, 
00688                              sizeof ("inherit")-1)) {
00689                 *border_style_ptr = BORDER_STYLE_INHERIT;
00690         } else {
00691                 status = CR_UNKNOWN_TYPE_ERROR;
00692         }
00693 
00694         return status;
00695 }
00696 
00697 static enum CRStatus
00698 set_prop_border_style_from_value (CRStyle *a_style,
00699                                   CRTerm *a_value)
00700 {
00701         CRTerm *cur_term = NULL ;
00702         enum CRDirection direction = DIR_TOP ;
00703 
00704         g_return_val_if_fail (a_style && a_value, 
00705                               CR_BAD_PARAM_ERROR) ;
00706 
00707         cur_term = a_value ;
00708         if (!cur_term || cur_term->type != TERM_IDENT) {
00709                 return CR_ERROR ;
00710         }
00711         
00712         for (direction = DIR_TOP ; 
00713              direction < NB_DIRS ;
00714              direction ++) {
00715                 set_prop_border_x_style_from_value (a_style, 
00716                                                     cur_term,
00717                                                     direction) ;
00718         }
00719         
00720         cur_term = cur_term->next ;
00721         if (!cur_term || cur_term->type != TERM_IDENT) {
00722                 return CR_OK ;
00723         }
00724         
00725         set_prop_border_x_style_from_value (a_style, cur_term, 
00726                                             DIR_RIGHT) ;
00727         set_prop_border_x_style_from_value (a_style, cur_term, 
00728                                             DIR_LEFT) ;
00729 
00730         cur_term = cur_term->next ;
00731         if (!cur_term || cur_term->type != TERM_IDENT) {
00732                 return CR_OK ;
00733         }        
00734         set_prop_border_x_style_from_value (a_style, cur_term,
00735                                            DIR_BOTTOM) ;
00736         
00737         cur_term = cur_term->next ;
00738         if (!cur_term || cur_term->type != TERM_IDENT) {
00739                 return CR_OK ;
00740         }
00741         set_prop_border_x_style_from_value (a_style, cur_term,
00742                                             DIR_LEFT) ;
00743         return CR_OK ;
00744 }
00745 
00746 static enum CRStatus
00747 set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
00748                               enum CRDirection a_dir)
00749 {
00750         enum CRStatus status = CR_OK;
00751         CRNum *num_val = NULL;
00752 
00753         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
00754 
00755         switch (a_dir) {
00756         case DIR_TOP:
00757                 num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
00758                 break;
00759 
00760         case DIR_RIGHT:
00761                 num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
00762                 break;
00763 
00764         case DIR_BOTTOM:
00765                 num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
00766                 break;
00767 
00768         case DIR_LEFT:
00769                 num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
00770                 break;
00771 
00772         default:
00773                 break;
00774         }
00775 
00776         switch (a_value->type) {
00777         case TERM_IDENT:
00778                 if (a_value->content.str
00779                     && a_value->content.str->stryng
00780                     && a_value->content.str->stryng->str
00781                     && !strcmp (a_value->content.str->stryng->str,
00782                                  "inherit")) {
00783                         status = cr_num_set (num_val, 0.0, NUM_INHERIT);
00784                 } else if (a_value->content.str
00785                            && a_value->content.str->stryng
00786                            && !strcmp (a_value->content.str->stryng->str,
00787                                         "auto")) {
00788                         status = cr_num_set (num_val, 0.0, NUM_AUTO);
00789                 } else {
00790                         status = CR_UNKNOWN_TYPE_ERROR;
00791                 }
00792                 break ;
00793 
00794         case TERM_NUMBER:
00795                 status = cr_num_copy (num_val, a_value->content.num);
00796                 break;
00797 
00798         default:
00799                 status = CR_UNKNOWN_TYPE_ERROR;
00800                 break;
00801         }
00802 
00803         return status;
00804 }
00805 
00806 struct CRPropDisplayValPair {
00807         const guchar *prop_name;
00808         enum CRDisplayType type;
00809 };
00810 
00811 static enum CRStatus
00812 set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value)
00813 {
00814         static const struct CRPropDisplayValPair disp_vals_map[] = {
00815                 {"none", DISPLAY_NONE},
00816                 {"inline", DISPLAY_INLINE},
00817                 {"block", DISPLAY_BLOCK},
00818                 {"run-in", DISPLAY_RUN_IN},
00819                 {"compact", DISPLAY_COMPACT},
00820                 {"marker", DISPLAY_MARKER},
00821                 {"table", DISPLAY_TABLE},
00822                 {"inline-table", DISPLAY_INLINE_TABLE},
00823                 {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
00824                 {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
00825                 {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
00826                 {"table-row", DISPLAY_TABLE_ROW},
00827                 {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
00828                 {"table-column", DISPLAY_TABLE_COLUMN},
00829                 {"table-cell", DISPLAY_TABLE_CELL},
00830                 {"table-caption", DISPLAY_TABLE_CAPTION},
00831                 {"inherit", DISPLAY_INHERIT},
00832                 {NULL, DISPLAY_NONE}
00833         };
00834 
00835         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
00836 
00837         switch (a_value->type) {
00838         case TERM_IDENT:
00839                 {
00840                         int i = 0;
00841 
00842                         if (!a_value->content.str
00843                             || !a_value->content.str->stryng
00844                             || !a_value->content.str->stryng->str)
00845                                 break;
00846 
00847                         for (i = 0; disp_vals_map[i].prop_name; i++) {
00848                                 if (!strncmp 
00849                                     (disp_vals_map[i].prop_name,
00850                                      a_value->content.str->stryng->str,
00851                                      strlen (disp_vals_map[i].prop_name))) {
00852                                         a_style->display =
00853                                                 disp_vals_map[i].type;
00854                                         break;
00855                                 }
00856                         }
00857                 }
00858                 break;
00859 
00860         default:
00861                 break;
00862         }
00863 
00864         return CR_OK;
00865 }
00866 
00867 struct CRPropPositionValPair {
00868         const guchar *name;
00869         enum CRPositionType type;
00870 };
00871 
00872 static enum CRStatus
00873 set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value)
00874 {
00875         enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR;
00876         static const struct CRPropPositionValPair position_vals_map[] = {
00877                 {"static", POSITION_STATIC},
00878                 {"relative", POSITION_RELATIVE},
00879                 {"absolute", POSITION_ABSOLUTE},
00880                 {"fixed", POSITION_FIXED},
00881                 {"inherit", POSITION_INHERIT},
00882                 {NULL, POSITION_STATIC}
00883                 /*must alwas be the last one */
00884         };
00885 
00886         g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR);
00887 
00888         switch (a_value->type) {
00889         case TERM_IDENT:
00890                 {
00891                         int i = 0;
00892 
00893                         if (!a_value->content.str
00894                             || !a_value->content.str->stryng
00895                             || !a_value->content.str->stryng->str)
00896                                 break;
00897 
00898                         for (i = 0; position_vals_map[i].name; i++) {
00899                                 if (!strncmp (position_vals_map[i].name,
00900                                               a_value->content.str->stryng->str,
00901                                               strlen (position_vals_map[i].
00902                                                       name))) {
00903                                         a_style->position =
00904                                                 position_vals_map[i].type;
00905                                         status = CR_OK;
00906                                         break;
00907                                 }
00908                         }
00909                 }
00910                 break;
00911 
00912         default:
00913                 break;
00914         }
00915 
00916         return CR_OK;
00917 }
00918 
00919 static enum CRStatus
00920 set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
00921                        enum CRDirection a_dir)
00922 {
00923         CRNum *box_offset = NULL;
00924 
00925         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
00926 
00927         if (!(a_value->type == TERM_NUMBER)
00928             && !(a_value->type == TERM_IDENT)) {
00929                 return CR_UNKNOWN_PROP_VAL_ERROR;
00930         }
00931 
00932         switch (a_dir) {
00933         case DIR_TOP:
00934                 box_offset = &a_style->num_props[NUM_PROP_TOP].sv;
00935                 break;
00936 
00937         case DIR_RIGHT:
00938                 box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv;
00939                 break;
00940 
00941         case DIR_BOTTOM:
00942                 box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv;
00943                 break;
00944         case DIR_LEFT:
00945                 box_offset = &a_style->num_props[NUM_PROP_LEFT].sv;
00946                 break;
00947 
00948         default:
00949                 break;
00950         }
00951 
00952         box_offset->type = NUM_AUTO;
00953 
00954         if (a_value->type == TERM_NUMBER && a_value->content.num) {
00955                 cr_num_copy (box_offset, a_value->content.num);
00956         } else if (a_value->type == TERM_IDENT
00957                    && a_value->content.str
00958                    && a_value->content.str->stryng
00959                    && a_value->content.str->stryng->str) {
00960                 if (!strncmp ("inherit",
00961                               a_value->content.str->stryng->str,
00962                               sizeof ("inherit")-1)) {
00963                         cr_num_set (box_offset, 0.0, NUM_INHERIT);
00964                 } else if (!strncmp ("auto",
00965                                      a_value->content.str->stryng->str,
00966                                      sizeof ("auto")-1)) {
00967                         box_offset->type = NUM_AUTO;
00968                 }
00969         }
00970 
00971         return CR_OK;
00972 }
00973 
00974 static enum CRStatus
00975 set_prop_float (CRStyle * a_style, CRTerm * a_value)
00976 {
00977         g_return_val_if_fail (a_style && a_value, 
00978                               CR_BAD_PARAM_ERROR);
00979 
00980         /*the default float type as specified by the css2 spec */
00981         a_style->float_type = FLOAT_NONE;
00982 
00983         if (a_value->type != TERM_IDENT 
00984             || !a_value->content.str
00985             || !a_value->content.str->stryng
00986             || !a_value->content.str->stryng->str) { 
00987                 /*unknow type, the float type is set to it's default value */
00988                 return CR_OK;
00989         }
00990 
00991         if (!strncmp ("none", 
00992                       a_value->content.str->stryng->str, 
00993                       sizeof ("none")-1)) {
00994                 a_style->float_type = FLOAT_NONE;
00995         } else if (!strncmp ("left",
00996                              a_value->content.str->stryng->str, 
00997                              sizeof ("left")-1)) {
00998                 a_style->float_type = FLOAT_LEFT;
00999         } else if (!strncmp ("right",
01000                              a_value->content.str->stryng->str, 
01001                              sizeof ("right")-1)) {
01002                 a_style->float_type = FLOAT_RIGHT;
01003         } else if (!strncmp ("inherit",
01004                              a_value->content.str->stryng->str, 
01005                              sizeof ("inherit")-1)) {
01006                 a_style->float_type = FLOAT_INHERIT;
01007         }
01008         return CR_OK;
01009 }
01010 
01011 static enum CRStatus
01012 set_prop_width (CRStyle * a_style, CRTerm * a_value)
01013 {
01014         CRNum *width = NULL;
01015         g_return_val_if_fail (a_style 
01016                               && a_value, 
01017                               CR_BAD_PARAM_ERROR);
01018 
01019         width = &a_style->num_props[NUM_PROP_WIDTH].sv;
01020         cr_num_set (width, 0.0, NUM_AUTO);
01021 
01022         if (a_value->type == TERM_IDENT) {
01023                 if (a_value->content.str 
01024                     && a_value->content.str->stryng
01025                     && a_value->content.str->stryng->str) {
01026                         if (!strncmp ("auto",
01027                                       a_value->content.str->stryng->str,
01028                                       sizeof ("auto")-1)) {
01029                                 cr_num_set (width, 0.0, NUM_AUTO);
01030                         } else if (!strncmp ("inherit",
01031                                              a_value->content.str->stryng->str,
01032                                              sizeof ("inherit")-1)) {
01033                                 cr_num_set (width, 0.0, NUM_INHERIT);
01034                         }
01035                 }
01036         } else if (a_value->type == TERM_NUMBER) {
01037                 if (a_value->content.num) {
01038                         cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
01039                                      a_value->content.num);
01040                 }
01041         }
01042         return CR_OK;
01043 }
01044 
01045 static enum CRStatus 
01046 set_prop_color (CRStyle * a_style, CRTerm * a_value)
01047 {
01048         enum CRStatus status = CR_OK;
01049         CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv;
01050 
01051         g_return_val_if_fail (a_style 
01052                               && a_value, CR_BAD_PARAM_ERROR);
01053 
01054         status = cr_rgb_set_from_term (a_rgb, a_value);
01055 
01056         return status;
01057 }
01058 
01059 static enum CRStatus
01060 set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
01061 {
01062         enum CRStatus status = CR_OK;
01063         CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv;
01064 
01065         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01066 
01067         status = cr_rgb_set_from_term (rgb, a_value);
01068         return status;
01069 }
01070 
01071 /**
01072  *Sets border-top-color, border-right-color,
01073  *border-bottom-color or border-left-color properties
01074  *in the style structure. The value is taken from a
01075  *css2 term of type IDENT or RGB.
01076  *@param a_style the style structure to set.
01077  *@param a_value the css2 term to take the color information from.
01078  *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
01079  *@return CR_OK upon successfull completion, an error code otherwise.
01080  */
01081 static enum CRStatus
01082 set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
01083                                     enum CRDirection a_dir)
01084 {
01085         CRRgb *rgb_color = NULL;
01086         enum CRStatus status = CR_OK;
01087 
01088         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01089 
01090         switch (a_dir) {
01091         case DIR_TOP:
01092                 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
01093                 break;
01094 
01095         case DIR_RIGHT:
01096                 rgb_color =
01097                         &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
01098                 break;
01099 
01100         case DIR_BOTTOM:
01101                 rgb_color =
01102                         &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
01103                 break;
01104 
01105         case DIR_LEFT:
01106                 rgb_color =
01107                         &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
01108                 break;
01109 
01110         default:
01111                 cr_utils_trace_info ("unknown DIR type");
01112                 return CR_BAD_PARAM_ERROR;
01113         }
01114 
01115         status = CR_UNKNOWN_PROP_VAL_ERROR;
01116 
01117         if (a_value->type == TERM_IDENT) {
01118                 if (a_value->content.str 
01119                     && a_value->content.str->stryng
01120                     && a_value->content.str->stryng->str) {
01121                         status = cr_rgb_set_from_name
01122                                 (rgb_color, 
01123                                  a_value->content.str->stryng->str);
01124 
01125                 }
01126                 if (status != CR_OK) {
01127                         cr_rgb_set_from_name (rgb_color, "black");
01128                 }
01129         } else if (a_value->type == TERM_RGB) {
01130                 if (a_value->content.rgb) {
01131                         status = cr_rgb_set_from_rgb
01132                                 (rgb_color, a_value->content.rgb);
01133                 }
01134         }
01135         return status;
01136 }
01137 
01138 static enum CRStatus
01139 set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
01140                               enum CRDirection a_dir)
01141 {
01142         CRTerm *cur_term = NULL;
01143 
01144         enum CRStatus status = CR_OK;
01145 
01146         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01147 
01148         for (cur_term = a_value; 
01149              cur_term; 
01150              cur_term = cur_term->next) {
01151                 status = set_prop_border_x_width_from_value (a_style,
01152                                                              cur_term, a_dir);
01153 
01154                 if (status != CR_OK) {
01155                         status = set_prop_border_x_style_from_value
01156                                 (a_style, cur_term, a_dir);
01157                 }
01158                 if (status != CR_OK) {
01159                         status = set_prop_border_x_color_from_value
01160                                 (a_style, cur_term, a_dir);
01161                 }
01162         }
01163         return CR_OK;
01164 }
01165 
01166 static enum CRStatus
01167 set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
01168 {
01169         enum CRDirection direction = 0;
01170 
01171         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01172 
01173         for (direction = 0; direction < NB_DIRS; direction++) {
01174                 set_prop_border_x_from_value (a_style, 
01175                                               a_value, 
01176                                               direction);
01177         }
01178 
01179         return CR_OK;
01180 }
01181 
01182 static enum CRStatus
01183 set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
01184 {
01185         CRTerm *cur_term = NULL;
01186         enum CRDirection direction = 0;
01187         enum CRStatus status = CR_OK;
01188         
01189         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01190 
01191         cur_term = a_value;
01192 
01193         /*filter the eventual non NUMBER terms some user can have written here*/
01194         while (cur_term && cur_term->type != TERM_NUMBER) {
01195                 cur_term = cur_term->next;
01196         }
01197         if (!cur_term)
01198                 return CR_ERROR ;
01199 
01200         for (direction = 0; direction < NB_DIRS; direction++) {
01201                 set_prop_padding_x_from_value (a_style, cur_term, direction);
01202         }
01203         cur_term = cur_term->next;
01204 
01205         /*filter non NUMBER terms that some users can have written here...*/
01206         while (cur_term && cur_term->type != TERM_NUMBER) {
01207                 cur_term = cur_term->next;
01208         }
01209         /*the user can have just written padding: 1px*/
01210         if (!cur_term)
01211                 return CR_OK;
01212 
01213         set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
01214         set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
01215 
01216         while (cur_term && cur_term->type != TERM_NUMBER) {
01217                 cur_term = cur_term->next;
01218         }
01219         if (!cur_term)
01220                 return CR_OK;
01221 
01222         set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
01223 
01224         while (cur_term && cur_term->type != TERM_NUMBER) {
01225                 cur_term = cur_term->next;
01226         }
01227         if (!cur_term)
01228                 return CR_OK;
01229         status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
01230         return status;
01231 }
01232 
01233 static enum CRStatus
01234 set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
01235 {
01236         CRTerm *cur_term = NULL;
01237         enum CRDirection direction = 0;
01238         enum CRStatus status = CR_OK;
01239 
01240         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01241 
01242         cur_term = a_value;
01243 
01244         while (cur_term && cur_term->type != TERM_NUMBER) {
01245                 cur_term = cur_term->next;
01246         }
01247 
01248         if (!cur_term)
01249                 return CR_OK;
01250 
01251         for (direction = 0; direction < NB_DIRS; direction++) {
01252                 set_prop_margin_x_from_value (a_style, cur_term, direction);
01253         }
01254         cur_term = cur_term->next;
01255 
01256         while (cur_term && cur_term->type != TERM_NUMBER) {
01257                 cur_term = cur_term->next;
01258         }
01259         if (!cur_term)
01260                 return CR_OK;
01261 
01262         set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
01263         set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
01264 
01265         while (cur_term && cur_term->type != TERM_NUMBER) {
01266                 cur_term = cur_term->next;
01267         }
01268         if (!cur_term)
01269                 return CR_OK;
01270 
01271         set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
01272 
01273         while (cur_term && cur_term->type != TERM_NUMBER) {
01274                 cur_term = cur_term->next;
01275         }
01276         if (!cur_term)
01277                 return CR_OK;
01278 
01279         status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);        
01280 
01281         return status;
01282 }
01283 
01284 static enum CRStatus
01285 set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
01286 {
01287         CRTerm *cur_term = NULL;
01288         CRFontFamily *font_family = NULL,
01289                 *cur_ff = NULL,
01290                 *cur_ff2 = NULL;
01291 
01292         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01293 
01294         if (a_value->type == TERM_IDENT &&
01295             a_value->content.str &&
01296             a_value->content.str->stryng &&
01297             a_value->content.str->stryng->str &&
01298             !strcmp ("inherit", a_value->content.str->stryng->str))
01299         {
01300                 font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
01301                 goto out;
01302         }
01303 
01304         for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
01305                 switch (cur_term->type) {
01306                 case TERM_IDENT:
01307                         {
01308                                 enum CRFontFamilyType font_type;
01309 
01310                                 if (cur_term->content.str
01311                                     && cur_term->content.str->stryng
01312                                     && cur_term->content.str->stryng->str
01313                                     && !strcmp 
01314                                     (cur_term->content.str->stryng->str,
01315                                      "sans-serif")) {
01316                                         font_type = FONT_FAMILY_SANS_SERIF;
01317                                 } else if (cur_term->content.str
01318                                            && cur_term->content.str->stryng
01319                                            && cur_term->content.str->stryng->str
01320                                            && !strcmp 
01321                                            (cur_term->content.str->stryng->str, 
01322                                             "serif")) {
01323                                         font_type = FONT_FAMILY_SERIF;
01324                                 } else if (cur_term->content.str
01325                                            && cur_term->content.str->stryng
01326                                            && cur_term->content.str->stryng->str
01327                                            && !strcmp (cur_term->content.str->stryng->str, 
01328                                                        "cursive")) {
01329                                         font_type = FONT_FAMILY_CURSIVE;
01330                                 } else if (cur_term->content.str
01331                                            && cur_term->content.str->stryng
01332                                            && cur_term->content.str->stryng->str
01333                                            && !strcmp (cur_term->content.str->stryng->str,
01334                                                        "fantasy")) {
01335                                         font_type = FONT_FAMILY_FANTASY;
01336                                 } else if (cur_term->content.str
01337                                            && cur_term->content.str->stryng
01338                                            && cur_term->content.str->stryng->str
01339                                            && !strcmp (cur_term->content.str->stryng->str, 
01340                                                        "monospace")) {
01341                                         font_type = FONT_FAMILY_MONOSPACE;
01342                                 } else {
01343                                         /*
01344                                          *unknown property value.
01345                                          *ignore it.
01346                                          */
01347                                         continue;
01348                                 }
01349 
01350                                 cur_ff = cr_font_family_new (font_type, NULL);
01351                         }
01352                         break;
01353 
01354                 case TERM_STRING:
01355                         {
01356                                 if (cur_term->content.str
01357                                     && cur_term->content.str->stryng
01358                                     && cur_term->content.str->stryng->str) {
01359                                         cur_ff = cr_font_family_new
01360                                                 (FONT_FAMILY_NON_GENERIC,
01361                                                  cur_term->content.str->stryng->str);
01362                                 }
01363                         }
01364                         break;
01365 
01366                 default:
01367                         break;
01368                 }
01369 
01370                 cur_ff2 = cr_font_family_append (font_family, cur_ff);
01371                 if (cur_ff2) {
01372                         font_family = cur_ff2;
01373                 }
01374         }
01375 
01376  out:
01377         if (font_family) {
01378                 if (a_style->font_family) {
01379                         cr_font_family_destroy (a_style->font_family);
01380                         a_style->font_family = NULL ;
01381                 }
01382                 a_style->font_family = font_family;
01383                 font_family = NULL ;
01384         }
01385 
01386         return CR_OK;
01387 }
01388 
01389 static enum CRStatus
01390 init_style_font_size_field (CRStyle * a_style)
01391 {
01392         g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
01393 
01394         memset (&a_style->font_size, 0, 
01395                sizeof (CRFontSizeVal)) ;
01396         /*
01397         if (!a_style->font_size) {
01398                 a_style->font_size = cr_font_size_new ();
01399                 if (!a_style->font_size) {
01400                         return CR_INSTANCIATION_FAILED_ERROR;
01401                 }
01402         } else {
01403                 cr_font_size_clear (a_style->font_size);
01404         }
01405         */
01406         return CR_OK;
01407 }
01408 
01409 static enum CRStatus
01410 set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
01411 {
01412         enum CRStatus status = CR_OK;
01413 
01414         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01415 
01416         switch (a_value->type) {
01417         case TERM_IDENT:
01418                 if (a_value->content.str
01419                     && a_value->content.str->stryng
01420                     && a_value->content.str->stryng->str
01421                     && !strcmp (a_value->content.str->stryng->str,
01422                                 "xx-small")) {
01423                         status = init_style_font_size_field (a_style);
01424                         g_return_val_if_fail (status == CR_OK, status);
01425 
01426                         a_style->font_size.sv.type =
01427                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01428                         a_style->font_size.sv.value.predefined =
01429                                 FONT_SIZE_XX_SMALL;
01430 
01431                 } else if (a_value->content.str
01432                            && a_value->content.str->stryng
01433                            && a_value->content.str->stryng->str
01434                            && !strcmp (a_value->content.str->stryng->str, 
01435                                        "x-small")) {
01436                         status = init_style_font_size_field (a_style);
01437                         g_return_val_if_fail (status == CR_OK, status);
01438 
01439                         a_style->font_size.sv.type =
01440                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01441                         a_style->font_size.sv.value.predefined =
01442                                 FONT_SIZE_X_SMALL;
01443                 } else if (a_value->content.str
01444                            && a_value->content.str->stryng
01445                            && a_value->content.str->stryng->str
01446                            && !strcmp (a_value->content.str->stryng->str, 
01447                                        "small")) {
01448                         status = init_style_font_size_field (a_style);
01449                         g_return_val_if_fail (status == CR_OK, status);
01450 
01451                         a_style->font_size.sv.type =
01452                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01453                         a_style->font_size.sv.value.predefined =
01454                                 FONT_SIZE_SMALL;
01455                 } else if (a_value->content.str
01456                            && a_value->content.str->stryng
01457                            && a_value->content.str->stryng->str
01458                            && !strcmp (a_value->content.str->stryng->str, "medium")) {
01459                         status = init_style_font_size_field (a_style);
01460                         g_return_val_if_fail (status == CR_OK, status);
01461 
01462                         a_style->font_size.sv.type =
01463                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01464                         a_style->font_size.sv.value.predefined =
01465                                 FONT_SIZE_MEDIUM;
01466                 } else if (a_value->content.str
01467                            && a_value->content.str->stryng
01468                            && a_value->content.str->stryng->str
01469                            && !strcmp (a_value->content.str->stryng->str, 
01470                                        "large")) {
01471                         status = init_style_font_size_field (a_style);
01472                         g_return_val_if_fail (status == CR_OK, status);
01473 
01474                         a_style->font_size.sv.type =
01475                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01476                         a_style->font_size.sv.value.predefined =
01477                                 FONT_SIZE_LARGE;
01478                 } else if (a_value->content.str
01479                            && a_value->content.str->stryng
01480                            && a_value->content.str->stryng->str
01481                            && !strcmp (a_value->content.str->stryng->str, 
01482                                        "x-large")) {
01483                         status = init_style_font_size_field (a_style);
01484                         g_return_val_if_fail (status == CR_OK, status);
01485 
01486                         a_style->font_size.sv.type =
01487                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01488                         a_style->font_size.sv.value.predefined =
01489                                 FONT_SIZE_X_LARGE;
01490                 } else if (a_value->content.str
01491                            && a_value->content.str->stryng
01492                            && a_value->content.str->stryng->str
01493                            && !strcmp (a_value->content.str->stryng->str, 
01494                                        "xx-large")) {
01495                         status = init_style_font_size_field (a_style);
01496                         g_return_val_if_fail (status == CR_OK, status);
01497 
01498                         a_style->font_size.sv.type =
01499                                 PREDEFINED_ABSOLUTE_FONT_SIZE;
01500                         a_style->font_size.sv.value.predefined =
01501                                 FONT_SIZE_XX_LARGE;
01502                 } else if (a_value->content.str
01503                            && a_value->content.str->stryng
01504                            && a_value->content.str->stryng->str
01505                            && !strcmp (a_value->content.str->stryng->str, 
01506                                        "larger")) {
01507                         status = init_style_font_size_field (a_style);
01508                         g_return_val_if_fail (status == CR_OK, status);
01509 
01510                         a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
01511                         a_style->font_size.sv.value.relative = FONT_SIZE_LARGER;
01512                 } else if (a_value->content.str
01513                            && a_value->content.str->stryng
01514                            && a_value->content.str->stryng->str
01515                            && !strcmp (a_value->content.str->stryng->str, 
01516                                        "smaller")) {
01517                         status = init_style_font_size_field (a_style);
01518                         g_return_val_if_fail (status == CR_OK, status);
01519 
01520                         a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
01521                         a_style->font_size.sv.value.relative =
01522                                 FONT_SIZE_SMALLER;
01523                 } else if (a_value->content.str
01524                            && a_value->content.str->stryng
01525                            && a_value->content.str->stryng->str
01526                            && !strcmp (a_value->content.str->stryng->str, "inherit")) {
01527                         status = init_style_font_size_field (a_style);
01528                         g_return_val_if_fail (status == CR_OK, status);
01529                         a_style->font_size.sv.type = INHERITED_FONT_SIZE;
01530 
01531                 } else {
01532                         cr_utils_trace_info ("Unknow value of font-size") ;
01533                         status = init_style_font_size_field (a_style);
01534                         return CR_UNKNOWN_PROP_VAL_ERROR;
01535                 }
01536                 break;
01537 
01538         case TERM_NUMBER:
01539                 if (a_value->content.num) {
01540                         status = init_style_font_size_field (a_style);
01541                         g_return_val_if_fail (status == CR_OK, status);
01542 
01543                         a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE;
01544                         cr_num_copy (&a_style->font_size.sv.value.absolute,
01545                                      a_value->content.num) ;
01546                 }
01547                 break;
01548 
01549         default:
01550                 status = init_style_font_size_field (a_style);
01551                 return CR_UNKNOWN_PROP_VAL_ERROR;
01552         }
01553         return CR_OK;
01554 }
01555 
01556 static enum CRStatus
01557 set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value)
01558 {
01559         enum CRStatus status = CR_OK;
01560 
01561         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01562 
01563         switch (a_value->type) {
01564         case TERM_IDENT:
01565                 if (a_value->content.str 
01566                     && a_value->content.str->stryng
01567                     && a_value->content.str->stryng->str) {
01568                         if (!strcmp (a_value->content.str->stryng->str, "normal")) {
01569                                 a_style->font_style = FONT_STYLE_NORMAL;
01570                         } else if (!strcmp
01571                                    (a_value->content.str->stryng->str,
01572                                     "italic")) {
01573                                 a_style->font_style = FONT_STYLE_ITALIC;
01574                         } else if (!strcmp
01575                                    (a_value->content.str->stryng->str,
01576                                     "oblique")) {
01577                                 a_style->font_style = FONT_STYLE_OBLIQUE;
01578                         } else if (!strcmp
01579                                    (a_value->content.str->stryng->str,
01580                                     "inherit")) {
01581                                 a_style->font_style = FONT_STYLE_INHERIT;
01582                         } else {
01583                                 status = CR_UNKNOWN_PROP_VAL_ERROR;
01584                         }
01585                 }
01586                 break;
01587 
01588         default:
01589                 status = CR_UNKNOWN_PROP_VAL_ERROR;
01590                 break;
01591         }
01592 
01593         return status;
01594 }
01595 
01596 static enum CRStatus
01597 set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value)
01598 {
01599         enum CRStatus status = CR_OK;
01600 
01601         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01602 
01603         switch (a_value->type) {
01604         case TERM_IDENT:
01605                 if (a_value->content.str 
01606                     && a_value->content.str->stryng
01607                     && a_value->content.str->stryng->str) {
01608                         if (!strcmp (a_value->content.str->stryng->str, 
01609                                      "normal")) {
01610                                 a_style->font_weight = FONT_WEIGHT_NORMAL;
01611                         } else if (!strcmp (a_value->content.str->stryng->str,
01612                                             "bold")) {
01613                                 a_style->font_weight = FONT_WEIGHT_BOLD;
01614                         } else if (!strcmp (a_value->content.str->stryng->str,
01615                                             "bolder")) {
01616                                 a_style->font_weight = FONT_WEIGHT_BOLDER;
01617                         } else if (!strcmp (a_value->content.str->stryng->str,
01618                                             "lighter")) {
01619                                 a_style->font_weight = FONT_WEIGHT_LIGHTER;
01620                         } else if (!strcmp (a_value->content.str->stryng->str,
01621                                             "inherit")) {
01622                                 a_style->font_weight = FONT_WEIGHT_INHERIT;
01623 
01624                         } else {
01625                                 status = CR_UNKNOWN_PROP_VAL_ERROR;
01626                         }
01627 
01628                 }
01629                 break;
01630 
01631         case TERM_NUMBER:
01632                 if (a_value->content.num
01633                     && (a_value->content.num->type == NUM_GENERIC
01634                         || a_value->content.num->type == NUM_AUTO)) {
01635                         if (a_value->content.num->val <= 150) {
01636                                 a_style->font_weight = FONT_WEIGHT_100;
01637                         } else if (a_value->content.num->val <= 250) {
01638                                 a_style->font_weight = FONT_WEIGHT_200;
01639                         } else if (a_value->content.num->val <= 350) {
01640                                 a_style->font_weight = FONT_WEIGHT_300;
01641                         } else if (a_value->content.num->val <= 450) {
01642                                 a_style->font_weight = FONT_WEIGHT_400;
01643                         } else if (a_value->content.num->val <= 550) {
01644                                 a_style->font_weight = FONT_WEIGHT_500;
01645                         } else if (a_value->content.num->val <= 650) {
01646                                 a_style->font_weight = FONT_WEIGHT_600;
01647                         } else if (a_value->content.num->val <= 750) {
01648                                 a_style->font_weight = FONT_WEIGHT_700;
01649                         } else if (a_value->content.num->val <= 850) {
01650                                 a_style->font_weight = FONT_WEIGHT_800;
01651                         } else {
01652                                 a_style->font_weight = FONT_WEIGHT_900;
01653                         }
01654                 }
01655                 break;
01656 
01657         default:
01658                 status = CR_UNKNOWN_PROP_VAL_ERROR;
01659                 break;
01660         }
01661 
01662         return status;
01663 }
01664 
01665 static enum CRStatus
01666 set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value)
01667 {
01668         enum CRStatus status = CR_OK;
01669 
01670         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
01671 
01672         switch (a_value->type) {
01673         case TERM_IDENT:
01674                 if (a_value->content.str && a_value->content.str->stryng) {
01675                         if (!strcmp (a_value->content.str->stryng->str, "normal")) {
01676                                 a_style->white_space = WHITE_SPACE_NORMAL;
01677                         } else if (!strcmp (a_value->content.str->stryng->str, 
01678                                             "pre")) {
01679                                 a_style->font_weight = WHITE_SPACE_PRE;
01680                         } else if (!strcmp (a_value->content.str->stryng->str,
01681                                             "nowrap")) {
01682                                 a_style->white_space = WHITE_SPACE_NOWRAP;
01683                         } else if (!strcmp (a_value->content.str->stryng->str,
01684                                             "inherit")) {
01685                                 a_style->white_space = WHITE_SPACE_INHERIT;
01686                         } else {
01687                                 status = CR_UNKNOWN_PROP_VAL_ERROR;
01688                         }
01689                 }
01690                 break;
01691         default:
01692                 status = CR_UNKNOWN_PROP_VAL_ERROR;
01693                 break;
01694         }
01695 
01696         return status;
01697 }
01698 
01699 /******************
01700  *Public methods
01701  ******************/
01702 
01703 /**
01704  *Default constructor of #CRStyle.
01705  *@param a_set_props_to_initial_values if TRUE, the style properties
01706  *will be set to the default values. Only the style properties of the
01707  *root box should be set to their initial values.
01708  *Otherwise, the style values are set to their default value.
01709  *Read the CSS2 spec, chapters 6.1.1 to 6.2.
01710  */
01711 CRStyle *
01712 cr_style_new (gboolean a_set_props_to_initial_values)
01713 {
01714         CRStyle *result = NULL;
01715 
01716         result = g_try_malloc (sizeof (CRStyle));
01717         if (!result) {
01718                 cr_utils_trace_info ("Out of memory");
01719                 return NULL;
01720         }
01721         memset (result, 0, sizeof (CRStyle));
01722         gv_prop_hash_ref_count++;
01723 
01724         if (a_set_props_to_initial_values == TRUE) {
01725                 cr_style_set_props_to_initial_values (result);
01726         } else {
01727                 cr_style_set_props_to_default_values (result);
01728         }
01729 
01730         return result;
01731 }
01732 
01733 /**
01734  *Sets the style properties to their default values according to the css2 spec
01735  * i.e inherit if the property is inherited, its initial value otherwise.
01736  *@param a_this the current instance of #CRStyle.
01737  *@return CR_OK upon successfull completion, an error code otherwise.
01738  */
01739 enum CRStatus 
01740 cr_style_set_props_to_default_values (CRStyle * a_this)
01741 {
01742         glong i = 0;
01743 
01744         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
01745         
01746         for (i = 0; i < NB_NUM_PROPS; i++)
01747         {
01748                 switch (i)
01749                 {
01750                 case NUM_PROP_WIDTH:
01751                 case NUM_PROP_TOP:
01752                 case NUM_PROP_RIGHT:
01753                 case NUM_PROP_BOTTOM:
01754                 case NUM_PROP_LEFT:
01755                         cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
01756                         break;
01757 
01758                 case NUM_PROP_PADDING_TOP:
01759                 case NUM_PROP_PADDING_RIGHT:
01760                 case NUM_PROP_PADDING_BOTTOM:
01761                 case NUM_PROP_PADDING_LEFT:
01762                 case NUM_PROP_BORDER_TOP:
01763                 case NUM_PROP_BORDER_RIGHT:
01764                 case NUM_PROP_BORDER_BOTTOM:
01765                 case NUM_PROP_BORDER_LEFT:
01766                 case NUM_PROP_MARGIN_TOP:
01767                 case NUM_PROP_MARGIN_RIGHT:
01768                 case NUM_PROP_MARGIN_BOTTOM:
01769                 case NUM_PROP_MARGIN_LEFT:
01770                         cr_num_set (&a_this->num_props[i].sv,
01771                                     0, NUM_LENGTH_PX);
01772                         break;
01773 
01774                 default:
01775                         cr_utils_trace_info ("Unknown property");
01776                         break;
01777                 }
01778         }
01779 
01780         for (i = 0; i < NB_RGB_PROPS; i++) {
01781                 
01782                 switch (i) {
01783                         /*default foreground color is black */
01784                 case RGB_PROP_COLOR:
01785                         /*
01786                          *REVIEW: color is inherited and the default value is
01787                          *ua dependant.
01788                          */
01789                         cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv,
01790                                                TRUE) ;
01791                         break;
01792 
01793                         /*default background color is white */
01794                 case RGB_PROP_BACKGROUND_COLOR:
01795                         /* TODO: the default value should be transparent */
01796                         cr_rgb_set (&a_this->rgb_props[i].sv,
01797                                     255, 255, 255, FALSE);
01798                         cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
01799                                                    TRUE) ;
01800                         break;
01801 
01802                 default:
01803                         /* 
01804                          *TODO: for BORDER_COLOR the initial value should
01805                          * be the same as COLOR 
01806                          */
01807                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
01808                                     FALSE);
01809                         break;
01810                 }
01811         }
01812 
01813         for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
01814                 a_this->border_style_props[i] = BORDER_STYLE_NONE;
01815         }
01816 
01817         a_this->display = DISPLAY_INLINE;
01818         a_this->position = POSITION_STATIC;
01819         a_this->float_type = FLOAT_NONE;
01820         a_this->parent_style = NULL;
01821         a_this->font_style = FONT_STYLE_INHERIT;
01822         a_this->font_variant = FONT_VARIANT_INHERIT;
01823         a_this->font_weight = FONT_WEIGHT_INHERIT;
01824         a_this->font_family = NULL;
01825         
01826         cr_font_size_set_to_inherit (&a_this->font_size.sv) ;
01827         cr_font_size_clear (&a_this->font_size.cv) ;
01828         cr_font_size_clear (&a_this->font_size.av) ;
01829 
01830         /* To make the inheritance resolution possible and efficient */
01831         a_this->inherited_props_resolved = FALSE ;
01832         return CR_OK;
01833 }
01834 
01835 /**
01836  *Sets the style properties to their initial value according to the css2 spec.
01837  *This function should be used to initialize the style of the root element
01838  *of an xml tree.
01839  *Some properties are user agent dependant like font-family, and
01840  *are not initialized, read the spec to make you renderer compliant.
01841  *@param a_this the current instance of #CRStyle.
01842  *@return CR_OK upon successfull completion, an error code otherwise.
01843  */
01844 enum CRStatus 
01845 cr_style_set_props_to_initial_values (CRStyle *a_this)
01846 {
01847         glong i = 0;
01848 
01849         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
01850 
01851         for (i = 0; i < NB_NUM_PROPS; i++) {
01852                 switch (i) {
01853                 case NUM_PROP_WIDTH:
01854                         cr_num_set (&a_this->num_props[i].sv, 800,
01855                                     NUM_LENGTH_PX) ;
01856                         break ;
01857                 case NUM_PROP_TOP:
01858                 case NUM_PROP_RIGHT:
01859                 case NUM_PROP_BOTTOM:
01860                 case NUM_PROP_LEFT:
01861                         cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
01862                         break;
01863 
01864                 case NUM_PROP_PADDING_TOP:
01865                 case NUM_PROP_PADDING_RIGHT:
01866                 case NUM_PROP_PADDING_BOTTOM:
01867                 case NUM_PROP_PADDING_LEFT:
01868                 case NUM_PROP_BORDER_TOP:
01869                 case NUM_PROP_BORDER_RIGHT:
01870                 case NUM_PROP_BORDER_BOTTOM:
01871                 case NUM_PROP_BORDER_LEFT:
01872                 case NUM_PROP_MARGIN_TOP:
01873                 case NUM_PROP_MARGIN_RIGHT:
01874                 case NUM_PROP_MARGIN_BOTTOM:
01875                 case NUM_PROP_MARGIN_LEFT:
01876                         cr_num_set (&a_this->num_props[i].sv,
01877                                     0, NUM_LENGTH_PX);
01878                         break;
01879 
01880                 default:
01881                         cr_utils_trace_info ("Unknown property");
01882                         break;
01883                 }
01884         }
01885 
01886         for (i = 0; i < NB_RGB_PROPS; i++) {
01887 
01888                 switch (i) {
01889                         /*default foreground color is black */
01890                 case RGB_PROP_COLOR:
01891                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
01892                         break;
01893 
01894                         /*default background color is white */
01895                 case RGB_PROP_BACKGROUND_COLOR:
01896                         cr_rgb_set (&a_this->rgb_props[i].sv,
01897                                     255, 255, 255, FALSE);
01898                         cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
01899                                                    TRUE) ;                        
01900                         break;
01901                 default:
01902                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
01903                         break;
01904                 }
01905         }
01906 
01907         for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
01908                 a_this->border_style_props[i] = BORDER_STYLE_NONE;
01909         }
01910 
01911         a_this->display = DISPLAY_BLOCK;
01912         a_this->position = POSITION_STATIC;
01913         a_this->float_type = FLOAT_NONE;
01914         a_this->font_style = FONT_STYLE_NORMAL;
01915         a_this->font_variant = FONT_VARIANT_NORMAL;
01916         a_this->font_weight = FONT_WEIGHT_NORMAL;
01917         a_this->font_stretch = FONT_STRETCH_NORMAL;
01918         a_this->white_space = WHITE_SPACE_NORMAL;
01919         cr_font_size_set_predefined_absolute_font_size
01920                 (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ;
01921         a_this->inherited_props_resolved = FALSE ;
01922 
01923         return CR_OK;
01924 }
01925 
01926 /**
01927  *Resolves the inherited properties.
01928  *The function sets the "inherited" properties to either the value of
01929  *their parent properties.
01930  *This function is *NOT* recursive. So the inherited properties of
01931  *the parent style must have been resolved prior to calling this function.
01932  *@param a_this the instance where 
01933  *@return CR_OK if a root node is found and the propagation is successful,
01934  *an error code otherwise
01935  */
01936 enum CRStatus 
01937 cr_style_resolve_inherited_properties (CRStyle *a_this)
01938 {
01939         enum CRStatus ret = CR_OK;
01940         glong i = 0;
01941 
01942         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
01943         g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ;
01944 
01945         if (a_this->inherited_props_resolved == TRUE)
01946                 return CR_OK ;
01947 
01948         for (i=0 ; i < NB_NUM_PROPS ;i++) {
01949                 if (a_this->num_props[i].sv.type == NUM_INHERIT) {
01950                         cr_num_copy (&a_this->num_props[i].cv,
01951                                      &a_this->parent_style->num_props[i].cv);
01952                 }
01953         }
01954         for (i=0; i < NB_RGB_PROPS; i++) {
01955                 if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) {
01956                         cr_rgb_copy (
01957                                 &a_this->rgb_props[i].cv,
01958                                 &a_this->parent_style->rgb_props[i].cv);
01959                 }
01960         }
01961         for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
01962                 if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) {
01963                         a_this->border_style_props[i] =
01964                           a_this->parent_style->border_style_props[i];
01965                 }
01966         }
01967 
01968         if (a_this->display == DISPLAY_INHERIT) {
01969                 a_this->display = a_this->parent_style->display;
01970         }
01971         if (a_this->position == POSITION_INHERIT) {
01972                 a_this->position = a_this->parent_style->position;
01973         }
01974         if (a_this->float_type == FLOAT_INHERIT) {
01975                 a_this->float_type = a_this->parent_style->float_type;
01976         }
01977         if (a_this->font_style == FONT_STYLE_INHERIT) {
01978                 a_this->font_style = a_this->parent_style->font_style;
01979         }
01980         if (a_this->font_variant == FONT_VARIANT_INHERIT) {
01981                 a_this->font_variant = a_this->parent_style->font_variant;
01982         }
01983         if (a_this->font_weight == FONT_WEIGHT_INHERIT) {
01984                 a_this->font_weight = a_this->parent_style->font_weight;
01985         }
01986         if (a_this->font_stretch == FONT_STRETCH_INHERIT) {
01987                 a_this->font_stretch = a_this->parent_style->font_stretch;
01988         }
01989         /*NULL is inherit marker for font_famiy*/
01990         if (a_this->font_family == NULL)  {
01991                 a_this->font_family = a_this->parent_style->font_family;
01992         }
01993         if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) {
01994                 cr_font_size_copy (&a_this->font_size.cv,
01995                                    &a_this->parent_style->font_size.cv) ;
01996         }
01997         a_this->inherited_props_resolved = TRUE ;
01998         return ret;
01999 }
02000 
02001 /**
02002  *Walks through a css2 property declaration, and populated the
02003  *according field(s) in the #CRStyle structure.
02004  *If the properties or their value(s) are/is not known, 
02005  *sets the corresponding field(s) of #CRStyle to its/their default 
02006  *value(s)
02007  *@param a_this the instance of #CRStyle to set.
02008  *@param a_decl the declaration from which the #CRStyle fields are set.
02009  *@return CR_OK upon successfull completion, an error code otherwise.
02010  */
02011 enum CRStatus
02012 cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl)
02013 {
02014         CRTerm *value = NULL;
02015         enum CRStatus status = CR_OK;
02016 
02017         enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN;
02018 
02019         g_return_val_if_fail (a_this && a_decl
02020                               && a_decl
02021                               && a_decl->property
02022                               && a_decl->property->stryng
02023                               && a_decl->property->stryng->str,
02024                               CR_BAD_PARAM_ERROR);
02025 
02026         prop_id = cr_style_get_prop_id
02027                 (a_decl->property->stryng->str);
02028 
02029         value = a_decl->value;
02030         switch (prop_id) {
02031         case PROP_ID_PADDING_TOP:
02032                 status = set_prop_padding_x_from_value
02033                         (a_this, value, DIR_TOP);
02034                 break;
02035 
02036         case PROP_ID_PADDING_RIGHT:
02037                 status = set_prop_padding_x_from_value
02038                         (a_this, value, DIR_RIGHT);
02039                 break;
02040         case PROP_ID_PADDING_BOTTOM:
02041                 status = set_prop_padding_x_from_value
02042                         (a_this, value, DIR_BOTTOM);
02043                 break;
02044 
02045         case PROP_ID_PADDING_LEFT:
02046                 status = set_prop_padding_x_from_value
02047                         (a_this, value, DIR_LEFT);
02048                 break;
02049 
02050         case PROP_ID_PADDING:
02051                 status = set_prop_padding_from_value (a_this, value) ;
02052                 break;
02053 
02054         case PROP_ID_BORDER_TOP_WIDTH:
02055                 status = set_prop_border_x_width_from_value (a_this, value,
02056                                                              DIR_TOP);
02057                 break;
02058 
02059         case PROP_ID_BORDER_RIGHT_WIDTH:
02060                 status = set_prop_border_x_width_from_value (a_this, value,
02061                                                              DIR_RIGHT);
02062                 break;
02063 
02064         case PROP_ID_BORDER_BOTTOM_WIDTH:
02065                 status = set_prop_border_x_width_from_value (a_this, value,
02066                                                              DIR_BOTTOM);
02067                 break;
02068 
02069         case PROP_ID_BORDER_LEFT_WIDTH:
02070                 status = set_prop_border_x_width_from_value (a_this, value,
02071                                                              DIR_LEFT);
02072                 break;
02073 
02074         case PROP_ID_BORDER_WIDTH:
02075                 status = set_prop_border_width_from_value (a_this, value) ;
02076                 break ;
02077 
02078         case PROP_ID_BORDER_TOP_STYLE:
02079                 status = set_prop_border_x_style_from_value (a_this, value,
02080                                                              DIR_TOP);
02081                 break;
02082 
02083         case PROP_ID_BORDER_RIGHT_STYLE:
02084                 status = set_prop_border_x_style_from_value (a_this, value,
02085                                                              DIR_RIGHT);
02086                 break;
02087 
02088         case PROP_ID_BORDER_BOTTOM_STYLE:
02089                 status = set_prop_border_x_style_from_value (a_this, value,
02090                                                              DIR_BOTTOM);
02091                 break;
02092 
02093         case PROP_ID_BORDER_LEFT_STYLE:
02094                 status = set_prop_border_x_style_from_value (a_this, value,
02095                                                              DIR_LEFT);
02096                 break;
02097 
02098         case PROP_ID_BORDER_STYLE:
02099                 status = set_prop_border_style_from_value (a_this, value) ;
02100                 break ;
02101 
02102         case PROP_ID_BORDER_TOP_COLOR:
02103                 status = set_prop_border_x_color_from_value (a_this, value,
02104                                                              DIR_TOP);
02105                 break;
02106 
02107         case PROP_ID_BORDER_RIGHT_COLOR:
02108                 status = set_prop_border_x_color_from_value (a_this, value,
02109                                                              DIR_RIGHT);
02110                 break;
02111 
02112         case PROP_ID_BORDER_BOTTOM_COLOR:
02113                 status = set_prop_border_x_color_from_value (a_this, value,
02114                                                              DIR_BOTTOM);
02115                 break;
02116 
02117         case PROP_ID_BORDER_LEFT_COLOR:
02118                 status = set_prop_border_x_color_from_value (a_this, value,
02119                                                              DIR_BOTTOM);
02120                 break;
02121 
02122         case PROP_ID_BORDER_TOP:
02123                 status = set_prop_border_x_from_value (a_this, value,
02124                                                        DIR_TOP);
02125                 break;
02126 
02127         case PROP_ID_BORDER_RIGHT:
02128                 status = set_prop_border_x_from_value (a_this, value,
02129                                                        DIR_RIGHT);
02130                 break;
02131 
02132         case PROP_ID_BORDER_BOTTOM:
02133                 status = set_prop_border_x_from_value (a_this, value,
02134                                                        DIR_BOTTOM);
02135                 break;
02136 
02137         case PROP_ID_BORDER_LEFT:
02138                 status = set_prop_border_x_from_value (a_this, value,
02139                                                        DIR_LEFT);
02140                 break;
02141 
02142         case PROP_ID_MARGIN_TOP:
02143                 status = set_prop_margin_x_from_value (a_this, value,
02144                                                        DIR_TOP);
02145                 break;
02146 
02147         case PROP_ID_BORDER:
02148                 status = set_prop_border_from_value (a_this, value);
02149                 break;
02150 
02151         case PROP_ID_MARGIN_RIGHT:
02152                 status = set_prop_margin_x_from_value (a_this, value,
02153                                                        DIR_RIGHT);
02154                 break;
02155 
02156         case PROP_ID_MARGIN_BOTTOM:
02157                 status = set_prop_margin_x_from_value (a_this, value,
02158                                                        DIR_BOTTOM);
02159                 break;
02160 
02161         case PROP_ID_MARGIN_LEFT:
02162                 status = set_prop_margin_x_from_value (a_this, value,
02163                                                        DIR_LEFT);
02164                 break;
02165 
02166         case PROP_ID_MARGIN:
02167                 status = set_prop_margin_from_value (a_this, value);
02168                 break;
02169 
02170         case PROP_ID_DISPLAY:
02171                 status = set_prop_display_from_value (a_this, value);
02172                 break;
02173 
02174         case PROP_ID_POSITION:
02175                 status = set_prop_position_from_value (a_this, value);
02176                 break;
02177 
02178         case PROP_ID_TOP:
02179                 status = set_prop_x_from_value (a_this, value, DIR_TOP);
02180                 break;
02181 
02182         case PROP_ID_RIGHT:
02183                 status = set_prop_x_from_value (a_this, value, DIR_RIGHT);
02184                 break;
02185 
02186         case PROP_ID_BOTTOM:
02187                 status = set_prop_x_from_value (a_this, value, DIR_BOTTOM);
02188                 break;
02189 
02190         case PROP_ID_LEFT:
02191                 status = set_prop_x_from_value (a_this, value, DIR_LEFT);
02192                 break;
02193 
02194         case PROP_ID_FLOAT:
02195                 status = set_prop_float (a_this, value);
02196                 break;
02197 
02198         case PROP_ID_WIDTH:
02199                 status = set_prop_width (a_this, value);
02200                 break;
02201 
02202         case PROP_ID_COLOR:
02203                 status = set_prop_color (a_this, value);
02204                 break;
02205 
02206         case PROP_ID_BACKGROUND_COLOR:
02207                 status = set_prop_background_color (a_this, value);
02208                 break;
02209 
02210         case PROP_ID_FONT_FAMILY:
02211                 status = set_prop_font_family_from_value (a_this, value);
02212                 break;
02213 
02214         case PROP_ID_FONT_SIZE:
02215                 status = set_prop_font_size_from_value (a_this, value);
02216                 break;
02217 
02218         case PROP_ID_FONT_STYLE:
02219                 status = set_prop_font_style_from_value (a_this, value);
02220                 break;
02221 
02222         case PROP_ID_FONT_WEIGHT:
02223                 status = set_prop_font_weight_from_value (a_this, value);
02224                 break;
02225 
02226         case PROP_ID_WHITE_SPACE:
02227                 status = set_prop_white_space_from_value(a_this, value);
02228                 break;
02229 
02230         default:
02231                 return CR_UNKNOWN_TYPE_ERROR;
02232 
02233         }
02234 
02235         return status;
02236 }
02237 
02238 /**
02239  *Increases the reference count
02240  *of the current instance of #CRStyle.
02241  *@param a_this the current instance of #CRStyle.
02242  *@return CR_OK upon successfull completion, an error code
02243  *otherwise.
02244  */
02245 enum CRStatus
02246 cr_style_ref (CRStyle * a_this)
02247 {
02248         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
02249 
02250         a_this->ref_count++;
02251         return CR_OK;
02252 }
02253 
02254 /**
02255  *Decreases the reference count of
02256  *the current instance of #CRStyle.
02257  *If the reference count reaches 0, the
02258  *instance of #CRStyle is destoyed.
02259  *@param a_this the current instance of #CRStyle.
02260  *@return TRUE if the instance has been destroyed, FALSE
02261  *otherwise.
02262  */
02263 gboolean
02264 cr_style_unref (CRStyle * a_this)
02265 {
02266         g_return_val_if_fail (a_this, FALSE);
02267 
02268         if (a_this->ref_count)
02269                 a_this->ref_count--;
02270 
02271         if (!a_this->ref_count) {
02272                 cr_style_destroy (a_this);
02273                 return TRUE;
02274         }
02275 
02276         return FALSE;
02277 }
02278 
02279 /**
02280  *Duplicates the current instance of #CRStyle .
02281  *The newly created instance of #CRStyle must be
02282  *freed using cr_style_destroy ().
02283  *@param a_this the current instance of #CRStyle.
02284  *@return the newly duplicated instance of #CRStyle.
02285  */
02286 CRStyle *
02287 cr_style_dup (CRStyle * a_this)
02288 {
02289         CRStyle *result = NULL;
02290 
02291         g_return_val_if_fail (a_this, NULL);
02292 
02293         result = cr_style_new (FALSE);
02294         if (!result) {
02295                 cr_utils_trace_info ("Out of memory");
02296                 return NULL;
02297         }
02298         cr_style_copy (result, a_this);
02299         return result;
02300 }
02301 
02302 /**
02303  *Copies a style data structure into another.
02304  *TODO: this is actually broken because it's based
02305  *on memcpy although some data stuctures of CRStyle should
02306  *be properly duplicated.
02307  *@param a_dest the destination style datastructure
02308  *@param a_src the source style datastructure.
02309  *@return CR_OK upon succesfull completion, an error code otherwise
02310  */
02311 enum CRStatus
02312 cr_style_copy (CRStyle * a_dest, CRStyle * a_src)
02313 {
02314         g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
02315 
02316         memcpy (a_dest, a_src, sizeof (CRStyle));
02317         return CR_OK;
02318 }
02319 
02320 /**
02321  *dump a CRNumpPropVal in a string.
02322  *@param a_prop_val the numerical property value to dump
02323  *@param a_str the string to dump the numerical propertie into.
02324  *Note that the string value is appended to a_str.
02325  *@param a_nb_indent the number white chars of indentation.
02326  */
02327 enum CRStatus
02328 cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val,
02329                                  GString * a_str, guint a_nb_indent)
02330 {
02331         enum CRStatus status = CR_OK;
02332         guchar *tmp_str = NULL;
02333         GString *str = NULL;
02334 
02335         g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
02336 
02337         str = g_string_new (NULL);
02338         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
02339         g_string_append (str, "NumPropVal {");
02340         tmp_str = cr_num_to_string (&a_prop_val->sv);
02341         if (!tmp_str) {
02342                 status = CR_ERROR;
02343                 goto cleanup;
02344         }
02345         g_string_append_printf (str, "sv: %s ", tmp_str);
02346         g_free (tmp_str);
02347         tmp_str = NULL;
02348         
02349         tmp_str = cr_num_to_string (&a_prop_val->cv);
02350         if (!tmp_str) {
02351                 status = CR_ERROR;
02352                 goto cleanup;
02353         }
02354         g_string_append_printf (str, "cv: %s ", tmp_str);
02355         g_free (tmp_str);
02356         tmp_str = NULL;
02357 
02358         tmp_str = cr_num_to_string (&a_prop_val->av);
02359         if (!tmp_str) {
02360                 status = CR_ERROR;
02361                 goto cleanup;
02362         }
02363         g_string_append_printf (str, "av: %s ", tmp_str);
02364         g_free (tmp_str);
02365         tmp_str = NULL;
02366         g_string_append (str, "}");
02367         g_string_append (a_str, str->str);
02368         status = CR_OK;
02369       cleanup:
02370 
02371         if (tmp_str) {
02372                 g_free (tmp_str);
02373                 tmp_str = NULL;
02374         }
02375         if (str) {
02376                 g_string_free (str, TRUE);
02377         }
02378         return status;
02379 }
02380 
02381 enum CRStatus
02382 cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
02383                                  GString * a_str, guint a_nb_indent)
02384 {
02385         enum CRStatus status = CR_OK;
02386         guchar *tmp_str = NULL;
02387         GString *str = NULL;
02388 
02389         g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
02390 
02391         str = g_string_new (NULL);
02392 
02393         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
02394         g_string_append (str, "RGBPropVal {");
02395         tmp_str = cr_rgb_to_string (&a_prop_val->sv);
02396         if (!tmp_str) {
02397                 status = CR_ERROR;
02398                 goto cleanup;
02399         }
02400         g_string_append_printf (str, "sv: %s ", tmp_str);
02401         g_free (tmp_str);
02402         tmp_str = NULL;
02403         tmp_str = cr_rgb_to_string (&a_prop_val->cv);
02404         if (!tmp_str) {
02405                 status = CR_ERROR;
02406                 goto cleanup;
02407         }
02408         g_string_append_printf (str, "cv: %s ", tmp_str);
02409         g_free (tmp_str);
02410         tmp_str = NULL;
02411         tmp_str = cr_rgb_to_string (&a_prop_val->av);
02412         if (!tmp_str) {
02413                 status = CR_ERROR;
02414                 goto cleanup;
02415         }
02416         g_string_append_printf (str, "av: %s ", tmp_str);
02417         g_free (tmp_str);
02418         tmp_str = NULL;
02419 
02420         g_string_append (str, "}");
02421         g_string_append (a_str, str->str);
02422         status = CR_OK;
02423       cleanup:
02424 
02425         if (tmp_str) {
02426                 g_free (tmp_str);
02427                 tmp_str = NULL;
02428         }
02429         if (str) {
02430                 g_string_free (str, TRUE);
02431         }
02432         return status;
02433 }
02434 
02435 enum CRStatus
02436 cr_style_border_style_to_string (enum CRBorderStyle a_prop,
02437                                  GString * a_str, guint a_nb_indent)
02438 {
02439         gchar *str = NULL;
02440 
02441         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
02442 
02443         switch (a_prop) {
02444         case BORDER_STYLE_NONE:
02445                 str = (gchar *) "border-style-none";
02446                 break;
02447         case BORDER_STYLE_HIDDEN:
02448                 str = (gchar *) "border-style-hidden";
02449                 break;
02450         case BORDER_STYLE_DOTTED:
02451                 str = (gchar *) "border-style-dotted";
02452                 break;
02453         case BORDER_STYLE_DASHED:
02454                 str = (gchar *) "border-style-dashed";
02455                 break;
02456         case BORDER_STYLE_SOLID:
02457                 str = (gchar *) "border-style-solid";
02458                 break;
02459         case BORDER_STYLE_DOUBLE:
02460                 str = (gchar *) "border-style-double";
02461                 break;
02462         case BORDER_STYLE_GROOVE:
02463                 str = (gchar *) "border-style-groove";
02464                 break;
02465         case BORDER_STYLE_RIDGE:
02466                 str = (gchar *) "border-style-ridge";
02467                 break;
02468         case BORDER_STYLE_INSET:
02469                 str = (gchar *) "border-style-inset";
02470                 break;
02471         case BORDER_STYLE_OUTSET:
02472                 str = (gchar *) "border-style-outset";
02473                 break;
02474         default:
02475                 str = (gchar *) "unknown border style";
02476                 break;
02477         }
02478         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
02479         g_string_append (a_str, str);
02480         return CR_OK;
02481 }
02482 
02483 enum CRStatus
02484 cr_style_display_type_to_string (enum CRDisplayType a_code,
02485                                  GString * a_str, guint a_nb_indent)
02486 {
02487         gchar *str = NULL;
02488 
02489         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
02490 
02491         switch (a_code) {
02492         case DISPLAY_NONE:
02493                 str = (gchar *) "display-none";
02494                 break;
02495         case DISPLAY_INLINE:
02496                 str = (gchar *) "display-inline";
02497                 break;
02498         case DISPLAY_BLOCK:
02499                 str = (gchar *) "display-block";
02500                 break;
02501         case DISPLAY_LIST_ITEM:
02502                 str = (gchar *) "display-list-item";
02503                 break;
02504         case DISPLAY_RUN_IN:
02505                 str = (gchar *) "display-run-in";
02506                 break;
02507         case DISPLAY_COMPACT:
02508                 str = (gchar *) "display-compact";
02509                 break;
02510         case DISPLAY_MARKER:
02511                 str = (gchar *) "display-marker";
02512                 break;
02513         case DISPLAY_TABLE:
02514                 str = (gchar *) "display-table";
02515                 break;
02516         case DISPLAY_INLINE_TABLE:
02517                 str = (gchar *) "display-inline-table";
02518                 break;
02519         case DISPLAY_TABLE_ROW_GROUP:
02520                 str = (gchar *) "display-table-row-group";
02521                 break;
02522         case DISPLAY_TABLE_HEADER_GROUP:
02523                 str = (gchar *) "display-table-header-group";
02524                 break;
02525         case DISPLAY_TABLE_FOOTER_GROUP:
02526                 str = (gchar *) "display-table-footer-group";
02527                 break;
02528         case DISPLAY_TABLE_ROW:
02529                 str = (gchar *) "display-table-row";
02530                 break;
02531         case DISPLAY_TABLE_COLUMN_GROUP:
02532                 str = (gchar *) "display-table-column-group";
02533                 break;
02534         case DISPLAY_TABLE_COLUMN:
02535                 str = (gchar *) "display-table-column";
02536                 break;
02537         case DISPLAY_TABLE_CELL:
02538                 str = (gchar *) "display-table-cell";
02539                 break;
02540         case DISPLAY_TABLE_CAPTION:
02541                 str = (gchar *) "display-table-caption";
02542                 break;
02543         case DISPLAY_INHERIT:
02544                 str = (gchar *) "display-inherit";
02545                 break;
02546         default:
02547                 str = (gchar *) "unknown display property";
02548                 break;
02549         }
02550         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
02551         g_string_append (a_str, str);
02552         return CR_OK;
02553 
02554 }
02555 
02556 enum CRStatus
02557 cr_style_position_type_to_string (enum CRPositionType a_code,
02558                                   GString * a_str, guint a_nb_indent)
02559 {
02560         gchar *str = NULL;
02561 
02562         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
02563 
02564         switch (a_code) {
02565         case POSITION_STATIC:
02566                 str = (gchar *) "position-static";
02567                 break;
02568         case POSITION_RELATIVE:
02569                 str = (gchar *) "position-relative";
02570                 break;
02571         case POSITION_ABSOLUTE:
02572                 str = (gchar *) "position-absolute";
02573                 break;
02574         case POSITION_FIXED:
02575                 str = (gchar *) "position-fixed";
02576                 break;
02577         case POSITION_INHERIT:
02578                 str = (gchar *) "position-inherit";
02579                 break;
02580         default:
02581                 str = (gchar *) "unknown static property";
02582         }
02583         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
02584         g_string_append (a_str, str);
02585         return CR_OK;
02586 }
02587 
02588 enum CRStatus
02589 cr_style_float_type_to_string (enum CRFloatType a_code,
02590                                GString * a_str, guint a_nb_indent)
02591 {
02592         gchar *str = NULL;
02593 
02594         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
02595 
02596         switch (a_code) {
02597         case FLOAT_NONE:
02598                 str = (gchar *) "float-none";
02599                 break;
02600         case FLOAT_LEFT:
02601                 str = (gchar *) "float-left";
02602                 break;
02603         case FLOAT_RIGHT:
02604                 str = (gchar *) "float-right";
02605                 break;
02606         case FLOAT_INHERIT:
02607                 str = (gchar *) "float-inherit";
02608                 break;
02609         default:
02610                 str = (gchar *) "unknown float property value";
02611                 break;
02612         }
02613         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
02614         g_string_append (a_str, str);
02615         return CR_OK;
02616 }
02617 
02618 enum CRStatus
02619 cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
02620                                      GString * a_str, guint a_nb_indent)
02621 {
02622         gchar *str = NULL;
02623 
02624         g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
02625 
02626         switch (a_code) {
02627         case WHITE_SPACE_NORMAL:
02628                 str = (gchar *) "normal";
02629                 break;
02630         case WHITE_SPACE_PRE:
02631                 str = (gchar *) "pre";
02632                 break;
02633         case WHITE_SPACE_NOWRAP:
02634                 str = (gchar *) "nowrap";
02635                 break;
02636         case WHITE_SPACE_INHERIT:
02637                 str = (gchar *) "inherited";
02638                 break;
02639         default:
02640                 str = (gchar *) "unknow white space property value";
02641                 break;
02642         }
02643         cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
02644         g_string_append (a_str, str);
02645         return CR_OK;
02646 }
02647  
02648 /**
02649  *Serializes in instance of #CRStyle into
02650  *a string
02651  *@param a_this the instance of #CRStyle to serialize
02652  *@param a_str the string to serialise the style into.
02653  *if *a_str is NULL, a new GString is instanciated, otherwise
02654  *the style serialisation is appended to the existed *a_str
02655  *@param the number of white space char to use for indentation.
02656  *@return CR_OK upon successful completion, an error code otherwise.
02657  */
02658 enum CRStatus
02659 cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent)
02660 {
02661         const gint INTERNAL_INDENT = 2;
02662         gint indent = a_nb_indent + INTERNAL_INDENT;
02663         gchar *tmp_str = NULL;
02664         GString *str = NULL;
02665         gint i = 0;
02666 
02667         g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR);
02668 
02669         if (!*a_str) {
02670                 str = g_string_new (NULL);
02671         } else {
02672                 str = *a_str;
02673         }
02674         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
02675         g_string_append (str, "style {\n");
02676 
02677         /*loop over the num_props and to_string() them */
02678         for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) {
02679                 /*
02680                  *to_string() the name of the num_prop
02681                  *(using num_prop_code_to_string)
02682                  *before outputing it value
02683                  */
02684                 cr_utils_dump_n_chars2 (' ', str, indent);
02685                 tmp_str = (gchar *) num_prop_code_to_string (i);
02686                 if (tmp_str) {
02687                         g_string_append_printf (str, "%s: ", tmp_str);
02688                 } else {
02689                         g_string_append (str, "NULL");
02690                 }
02691                 tmp_str = NULL;
02692                 cr_style_num_prop_val_to_string (&a_this->num_props[i], str,
02693                                                  a_nb_indent +
02694                                                  INTERNAL_INDENT);
02695                 g_string_append (str, "\n");
02696         }
02697         /*loop over the rgb_props and to_string() them all */
02698         for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) {
02699                 tmp_str = (gchar *) rgb_prop_code_to_string (i);
02700                 cr_utils_dump_n_chars2 (' ', str, indent);
02701                 if (tmp_str) {
02702                         g_string_append_printf (str, "%s: ", tmp_str);
02703                 } else {
02704                         g_string_append (str, "NULL: ");
02705                 }
02706                 tmp_str = NULL;
02707                 cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str,
02708                                                  a_nb_indent +
02709                                                  INTERNAL_INDENT);
02710                 g_string_append (str, "\n");
02711         }
02712         /*loop over the border_style_props and to_string() them */
02713         for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) {
02714                 tmp_str = (gchar *) border_style_prop_code_to_string (i);
02715                 cr_utils_dump_n_chars2 (' ', str, indent);
02716                 if (tmp_str) {
02717                         g_string_append_printf (str, "%s: ", tmp_str);
02718                 } else {
02719                         g_string_append (str, "NULL: ");
02720                 }
02721                 tmp_str = NULL;
02722                 cr_style_border_style_to_string (a_this->
02723                                                  border_style_props[i], str,
02724                                                  0);
02725                 g_string_append (str, "\n");
02726         }
02727         cr_utils_dump_n_chars2 (' ', str, indent);
02728         g_string_append (str, "display: ");
02729         cr_style_display_type_to_string (a_this->display, str, 0);
02730         g_string_append (str, "\n");
02731 
02732         cr_utils_dump_n_chars2 (' ', str, indent);
02733         g_string_append (str, "position: ");
02734         cr_style_position_type_to_string (a_this->position, str, 0);
02735         g_string_append (str, "\n");
02736 
02737         cr_utils_dump_n_chars2 (' ', str, indent);
02738         g_string_append (str, "float-type: ");
02739         cr_style_float_type_to_string (a_this->float_type, str, 0);
02740         g_string_append (str, "\n");
02741 
02742         cr_utils_dump_n_chars2 (' ', str, indent);
02743         g_string_append (str, "white-space: ");
02744         cr_style_white_space_type_to_string (a_this->white_space, str, 0);
02745         g_string_append (str, "\n");
02746 
02747         cr_utils_dump_n_chars2 (' ', str, indent);
02748         g_string_append (str, "font-family: ");
02749         tmp_str = cr_font_family_to_string (a_this->font_family, TRUE);
02750         if (tmp_str) {
02751                 g_string_append (str, tmp_str);
02752                 g_free (tmp_str);
02753                 tmp_str = NULL;
02754         } else {
02755                 g_string_append (str, "NULL");
02756         }
02757         g_string_append (str, "\n");
02758 
02759         cr_utils_dump_n_chars2 (' ', str, indent);
02760         tmp_str = cr_font_size_to_string (&a_this->font_size.sv);
02761         if (tmp_str) {
02762                 g_string_append_printf (str, "font-size {sv:%s, ",
02763                                         tmp_str) ;
02764         } else {
02765                 g_string_append (str, "font-size {sv:NULL, ");
02766         }
02767         tmp_str = cr_font_size_to_string (&a_this->font_size.cv);
02768         if (tmp_str) {
02769                 g_string_append_printf (str, "cv:%s, ", tmp_str);
02770         } else {
02771                 g_string_append (str, "cv:NULL, ");
02772         }
02773         tmp_str = cr_font_size_to_string (&a_this->font_size.av);
02774         if (tmp_str) {
02775                 g_string_append_printf (str, "av:%s}", tmp_str);
02776         } else {
02777                 g_string_append (str, "av:NULL}");
02778         }
02779 
02780         tmp_str = NULL;
02781         g_string_append (str, "\n");
02782 
02783         cr_utils_dump_n_chars2 (' ', str, indent);
02784         tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust);
02785         if (tmp_str) {
02786                 g_string_append_printf (str, "font-size-adjust: %s", tmp_str);
02787         } else {
02788                 g_string_append (str, "font-size-adjust: NULL");
02789         }
02790         tmp_str = NULL;
02791         g_string_append (str, "\n");
02792 
02793         cr_utils_dump_n_chars2 (' ', str, indent);
02794         tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style);
02795         if (tmp_str) {
02796                 g_string_append_printf (str, "font-style: %s", tmp_str);
02797         } else {
02798                 g_string_append (str, "font-style: NULL");
02799         }
02800         tmp_str = NULL;
02801         g_string_append (str, "\n");
02802 
02803         cr_utils_dump_n_chars2 (' ', str, indent);
02804         tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant);
02805         if (tmp_str) {
02806                 g_string_append_printf (str, "font-variant: %s", tmp_str);
02807         } else {
02808                 g_string_append (str, "font-variant: NULL");
02809         }
02810         tmp_str = NULL;
02811         g_string_append (str, "\n");
02812 
02813         cr_utils_dump_n_chars2 (' ', str, indent);
02814         tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight);
02815         if (tmp_str) {
02816                 g_string_append_printf (str, "font-weight: %s", tmp_str);
02817         } else {
02818                 g_string_append (str, "font-weight: NULL");
02819         }
02820         tmp_str = NULL;
02821         g_string_append (str, "\n");
02822 
02823         cr_utils_dump_n_chars2 (' ', str, indent);
02824         tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch);
02825         if (tmp_str) {
02826                 g_string_append_printf (str, "font-stretch: %s", tmp_str);
02827         } else {
02828                 g_string_append (str, "font-stretch: NULL");
02829         }
02830         tmp_str = NULL;
02831         g_string_append (str, "\n");
02832 
02833 
02834         cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
02835         g_string_append (str, "}");
02836 
02837         return CR_OK;
02838 }
02839 
02840 /**
02841  *Destructor of the #CRStyle class.
02842  *@param a_this the instance to destroy.
02843  */
02844 void
02845 cr_style_destroy (CRStyle * a_this)
02846 {
02847         g_return_if_fail (a_this);
02848 
02849         g_free (a_this);
02850 }
02851 

Generated on Fri Oct 29 08:29:12 2004 for Libcroco by  doxygen 1.3.9.1