Main Page | Alphabetical List | Data Structures | 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  * Copyright (C) 2002-2003 Dodji Seketeli <dodji@seketeli.org>
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of version 2.1 of 
00010  * the GNU Lesser General Public
00011  * License as published by the Free Software Foundation.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the 
00019  * GNU Lesser General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00022  * USA
00023  */
00024 
00025 /*
00026  *$Id: cr-style.c,v 1.10 2003/07/05 21:09:17 dodji Exp $
00027  */
00028 #include <string.h>
00029 #include "cr-style.h"
00030 
00031 /**
00032  *@file
00033  *The definition of the #CRStyle class.
00034  */
00035 
00036 
00037 /**
00038  *A property ID.
00039  *Each supported css property has an ID which is
00040  *an entry into a property "population" jump table.
00041  *each entry of the property population jump table
00042  *contains code to tranform the literal form of
00043  *a property value into a strongly typed value.
00044  */
00045 enum CRPropertyID
00046 {
00047         PROP_ID_NOT_KNOWN = 0,
00048         PROP_ID_PADDING_TOP,
00049         PROP_ID_PADDING_RIGHT,
00050         PROP_ID_PADDING_BOTTOM,
00051         PROP_ID_PADDING_LEFT,
00052         PROP_ID_PADDING,
00053         PROP_ID_BORDER_TOP_WIDTH,
00054         PROP_ID_BORDER_RIGHT_WIDTH,
00055         PROP_ID_BORDER_BOTTOM_WIDTH,
00056         PROP_ID_BORDER_LEFT_WIDTH,
00057         PROP_ID_BORDER_TOP_STYLE,
00058         PROP_ID_BORDER_RIGHT_STYLE,
00059         PROP_ID_BORDER_BOTTOM_STYLE,
00060         PROP_ID_BORDER_LEFT_STYLE,
00061         PROP_ID_BORDER_TOP_COLOR,
00062         PROP_ID_BORDER_RIGHT_COLOR,
00063         PROP_ID_BORDER_BOTTOM_COLOR,
00064         PROP_ID_BORDER_LEFT_COLOR,
00065         PROP_ID_BORDER_TOP,
00066         PROP_ID_BORDER_RIGHT,
00067         PROP_ID_BORDER_BOTTOM,
00068         PROP_ID_BORDER_LEFT,
00069         PROP_ID_BORDER,
00070         PROP_ID_MARGIN_TOP,
00071         PROP_ID_MARGIN_RIGHT,
00072         PROP_ID_MARGIN_BOTTOM,
00073         PROP_ID_MARGIN_LEFT,
00074         PROP_ID_MARGIN,
00075         PROP_ID_DISPLAY,
00076         PROP_ID_POSITION,
00077         PROP_ID_TOP,
00078         PROP_ID_RIGHT,
00079         PROP_ID_BOTTOM,
00080         PROP_ID_LEFT,
00081         PROP_ID_FLOAT,
00082         PROP_ID_WIDTH,
00083         PROP_ID_COLOR,        
00084         PROP_ID_BACKGROUND_COLOR,
00085         PROP_ID_FONT_FAMILY,
00086         PROP_ID_FONT_SIZE,
00087         PROP_ID_FONT_STYLE,
00088         PROP_ID_FONT_WEIGHT,
00089         /*should be the last one.*/
00090         NB_PROP_IDS
00091 } ;
00092 
00093 
00094 typedef struct _CRPropertyDesc CRPropertyDesc ;
00095 
00096 struct _CRPropertyDesc
00097 {
00098         const guchar * name ;
00099         enum CRPropertyID prop_id ;
00100 } ;
00101 
00102 static CRPropertyDesc gv_prop_table [] =
00103 
00104 {
00105         {"padding-top", PROP_ID_PADDING_TOP},
00106         {"padding-right", PROP_ID_PADDING_RIGHT},
00107         {"padding-bottom", PROP_ID_PADDING_BOTTOM},
00108         {"padding-left", PROP_ID_PADDING_LEFT},
00109         {"padding", PROP_ID_PADDING},
00110         {"border-top-width", PROP_ID_BORDER_TOP_WIDTH},
00111         {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH},
00112         {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH},
00113         {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH},
00114         {"border-top-style", PROP_ID_BORDER_TOP_STYLE},
00115         {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE},
00116         {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE},
00117         {"border-left-style", PROP_ID_BORDER_LEFT_STYLE},
00118         {"border-top", PROP_ID_BORDER_TOP},
00119         {"border-right", PROP_ID_BORDER_RIGHT},
00120         {"border-bottom", PROP_ID_BORDER_BOTTOM},
00121         {"border-left", PROP_ID_BORDER_LEFT},
00122         {"border", PROP_ID_BORDER},
00123         {"margin-top", PROP_ID_MARGIN_TOP},
00124         {"margin-right", PROP_ID_MARGIN_RIGHT},
00125         {"margin-bottom", PROP_ID_MARGIN_BOTTOM},
00126         {"margin-left", PROP_ID_MARGIN_LEFT},
00127         {"margin", PROP_ID_MARGIN},
00128         {"display", PROP_ID_DISPLAY},
00129         {"position", PROP_ID_POSITION},
00130         {"top", PROP_ID_TOP},
00131         {"right", PROP_ID_RIGHT},
00132         {"bottom", PROP_ID_BOTTOM},
00133         {"left", PROP_ID_LEFT},
00134         {"float", PROP_ID_FLOAT},
00135         {"width", PROP_ID_WIDTH},
00136         {"color", PROP_ID_COLOR},
00137         {"background-color", PROP_ID_BACKGROUND_COLOR},
00138         {"font-family", PROP_ID_FONT_FAMILY},
00139         {"font-size", PROP_ID_FONT_SIZE},
00140         {"font-style", PROP_ID_FONT_STYLE},
00141         {"font-weight", PROP_ID_FONT_WEIGHT},
00142         /*must be the last one*/
00143         {NULL, 0}
00144 } ;
00145 
00146 const gulong gv_predefined_abs_font_size_tab [NB_PREDEFINED_ABSOLUTE_FONT_SIZES]
00147 =
00148 {
00149         7, /*FONT_SIZE_XX_SMALL*/
00150         9,/*FONT_SIZE_X_SMALL*/
00151         11, /*FONT_SIZE_SMALL*/
00152         14, /*FONT_MEDIUM*/
00153         17, /*FONT_LARGE*/
00154         20, /*FONT_X_LARGE*/
00155         24 /*FONT_XX_LARGE*/        
00156 } ;
00157 
00158 /**
00159  *A the key/value pair of this hash table
00160  *are:
00161  *key => name of the the css propertie found in gv_prop_table
00162  *value => matching property id found in gv_prop_table.
00163  *So this hash table is here just to retrieval of a property id
00164  *from a property name.
00165  */
00166 static GHashTable *gv_prop_hash = NULL ;
00167 
00168 /**
00169  *incremented by each new instance of #CRStyle
00170  *and decremented at the it destroy time.
00171  *When this reaches zero, gv_prop_hash is destroyed.
00172  */
00173 static gulong gv_prop_hash_ref_count = 0 ;
00174 
00175 static enum CRStatus
00176 cr_style_init_properties (void) ;
00177 
00178 enum CRDirection
00179 {
00180         DIR_TOP = 0,
00181         DIR_RIGHT,
00182         DIR_BOTTOM,
00183         DIR_LEFT,
00184 
00185         /*must be the last one*/
00186         NB_DIRS
00187 } ;
00188 
00189 static enum CRStatus
00190 cr_style_set_props_to_defaults (CRStyle *a_this) ;
00191 
00192 static enum CRStatus
00193 set_prop_padding_x_from_value (CRStyle *a_style,                          
00194                                CRTerm *a_value,
00195                                enum CRDirection a_dir) ;
00196 
00197 static enum CRStatus
00198 set_prop_border_x_width_from_value (CRStyle *a_style,
00199                                     CRTerm *a_value,
00200                                     enum CRDirection a_dir) ;
00201 
00202 static enum CRStatus
00203 set_prop_border_x_style_from_value (CRStyle *a_style,
00204                                     CRTerm *a_value,
00205                                     enum CRDirection a_dir) ;
00206 
00207 static enum CRStatus
00208 set_prop_margin_x_from_value (CRStyle *a_style, CRTerm *a_value,
00209                               enum CRDirection a_dir) ;
00210 
00211 static enum CRStatus
00212 set_prop_display_from_value (CRStyle *a_style, CRTerm *a_value) ;
00213 
00214 static enum CRStatus
00215 set_prop_position_from_value (CRStyle *a_style, CRTerm *a_value) ;
00216 
00217 static enum CRStatus
00218 set_prop_x_from_value (CRStyle *a_style, CRTerm *a_value,
00219                        enum CRDirection a_dir) ;
00220 
00221 static enum CRStatus
00222 set_prop_float (CRStyle *a_style, CRTerm *a_value) ;
00223 
00224 static enum CRStatus
00225 set_prop_width (CRStyle *a_style, CRTerm *a_value) ;
00226 
00227 static enum CRStatus
00228 set_prop_color_rgb (CRStyle *a_style, CRTerm *a_value) ;
00229 
00230 static enum CRStatus
00231 set_prop_background_color (CRStyle *a_style, CRTerm *a_value) ;
00232 
00233 static enum CRStatus
00234 set_prop_border_x_color_from_value (CRStyle *a_style, CRTerm *a_value,
00235                                     enum CRDirection a_dir) ;
00236 
00237 static enum CRStatus
00238 set_prop_border_x_from_value (CRStyle *a_style, CRTerm *a_value,
00239                               enum CRDirection a_dir) ;
00240 
00241 static enum CRStatus
00242 set_prop_border_from_value (CRStyle *a_style, CRTerm *a_value) ;
00243 
00244 static enum CRStatus
00245 set_prop_padding_from_value (CRStyle *a_style, CRTerm *a_value) ;
00246 
00247 static enum CRStatus
00248 set_prop_margin_from_value (CRStyle *a_style, CRTerm *a_value) ;
00249 
00250 static enum CRStatus
00251 set_prop_font_family_from_value (CRStyle *a_style, CRTerm *a_value) ;
00252 
00253 static enum CRStatus
00254 init_style_font_size_field (CRStyle *a_style) ;
00255 
00256 static enum CRStatus
00257 set_prop_font_size_from_value (CRStyle *a_style, CRTerm *a_value) ;
00258 
00259 
00260 static enum CRStatus
00261 set_prop_font_style_from_value (CRStyle *a_style, CRTerm *a_value) ;
00262 
00263 static enum CRStatus
00264 set_prop_font_weight_from_value (CRStyle *a_style, CRTerm *a_value) ;
00265 
00266 static enum CRStatus
00267 cr_style_init_properties (void)
00268 {
00269 
00270         if (!gv_prop_hash)
00271         {
00272                 gulong i = 0 ;
00273 
00274                 gv_prop_hash = g_hash_table_new (g_str_hash,
00275                                                  g_str_equal) ;
00276                 if (!gv_prop_hash)
00277                 {
00278                         cr_utils_trace_info ("Out of memory") ;
00279                         return CR_ERROR ;
00280                 }
00281 
00282                 /*load gv_prop_hash from gv_prop_table*/
00283                 for (i = 0 ; gv_prop_table[i].name ; i++)
00284                 {
00285                         g_hash_table_insert 
00286                                 (gv_prop_hash,
00287                                  (gpointer)gv_prop_table[i].name,
00288                                  GINT_TO_POINTER 
00289                                  (gv_prop_table[i].prop_id)) ;
00290                 }
00291         }
00292 
00293         return CR_OK ;
00294 }
00295 
00296 /**
00297  *Sets the style properties to their default values
00298  *according to the css2 spec.
00299  *@param a_this the current instance of #CRStyle.
00300  *@return CR_OK upon successfull completion, an error code otherwise.
00301  */
00302 static enum CRStatus
00303 cr_style_set_props_to_defaults (CRStyle *a_this)
00304 {
00305         glong i = 0 ;
00306 
00307         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
00308 
00309         for (i = 0 ; i < NB_NUM_PROPS ; i++)
00310         {
00311                 switch (i)
00312                 {
00313                 case NUM_PROP_WIDTH:
00314                 case NUM_PROP_TOP:
00315                 case NUM_PROP_RIGHT:
00316                 case NUM_PROP_BOTTOM:
00317                 case NUM_PROP_LEFT:
00318                         cr_num_set (&a_this->num_props[i].sv,
00319                                     0, NUM_AUTO) ;
00320                         break ;
00321 
00322                 case NUM_PROP_PADDING_TOP:
00323                 case NUM_PROP_PADDING_RIGHT:
00324                 case NUM_PROP_PADDING_BOTTOM:
00325                 case NUM_PROP_PADDING_LEFT:
00326                 case NUM_PROP_BORDER_TOP:
00327                 case NUM_PROP_BORDER_RIGHT:
00328                 case NUM_PROP_BORDER_BOTTOM:
00329                 case NUM_PROP_BORDER_LEFT:
00330                 case NUM_PROP_MARGIN_TOP:
00331                 case NUM_PROP_MARGIN_RIGHT:
00332                 case NUM_PROP_MARGIN_BOTTOM:
00333                 case NUM_PROP_MARGIN_LEFT:                
00334                         cr_num_set (&a_this->num_props[i].sv,
00335                                     0, NUM_LENGTH_PX) ;
00336                         break ;
00337 
00338                 default:
00339                         cr_utils_trace_info ("Unknown property") ;
00340                         break ;
00341                 }
00342         }
00343 
00344         for (i = 0 ; i < NB_RGB_PROPS ; i++)
00345         {
00346                 
00347                 switch (i)
00348                 {
00349                         /*default foreground color is black*/
00350                 case RGB_PROP_COLOR:
00351                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
00352                                     FALSE) ;
00353                         break ;
00354                         
00355                         /*default background color is white*/
00356                 case RGB_PROP_BACKGROUND_COLOR:
00357                         cr_rgb_set (&a_this->rgb_props[i].sv, 
00358                                     255, 255, 255, FALSE) ;
00359                         break ;
00360 
00361                 default:
00362                         cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
00363                                     FALSE) ;
00364                 break ;
00365                 }
00366         }
00367 
00368         for (i = 0 ; i < NB_BORDER_STYLE_PROPS ; i++)
00369         {
00370                 a_this->border_style_props[i] = BORDER_STYLE_NONE ;
00371         }
00372 
00373         a_this->display = DISPLAY_BLOCK ;
00374         a_this->position = POSITION_STATIC ;
00375         a_this->float_type = FLOAT_NONE ;
00376         a_this->parent_style = NULL ;
00377 
00378         return CR_OK ;
00379 }
00380 
00381 
00382 static enum CRPropertyID
00383 cr_style_get_prop_id (const guchar * a_prop)
00384 {
00385         gpointer * raw_id = NULL ;
00386 
00387         if (!gv_prop_hash)
00388         {
00389                 cr_style_init_properties () ;
00390         }
00391 
00392         raw_id = g_hash_table_lookup (gv_prop_hash,
00393                                       a_prop) ;
00394         if (!raw_id)
00395         {
00396                 return PROP_ID_NOT_KNOWN ;
00397         }
00398         return GPOINTER_TO_INT (raw_id) ;
00399 }
00400 
00401 
00402 static enum CRStatus
00403 set_prop_padding_x_from_value (CRStyle *a_style,
00404                                CRTerm *a_value,
00405                                enum CRDirection a_dir)
00406 {
00407         enum CRStatus status = CR_OK ;
00408         CRNum *num_val = NULL, *parent_num_val = NULL ;
00409 
00410         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
00411 
00412         if (a_value->type != TERM_NUMBER
00413             && a_value->type != TERM_IDENT)
00414                 return CR_BAD_PARAM_ERROR ;
00415 
00416         switch (a_dir)
00417         {
00418         case DIR_TOP:
00419                 num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv ;
00420                 parent_num_val = 
00421                         &a_style->parent_style->
00422                         num_props[NUM_PROP_PADDING_TOP].sv ;
00423                 break ;
00424                 
00425         case DIR_RIGHT:
00426                 num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv ;
00427                 parent_num_val = 
00428                         &a_style->parent_style-> 
00429                         num_props[NUM_PROP_PADDING_RIGHT].sv;
00430 
00431                 num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv ;
00432                 parent_num_val =
00433                         &a_style->parent_style->
00434                         num_props[NUM_PROP_PADDING_RIGHT].sv ;
00435                 break ;
00436 
00437         case DIR_BOTTOM:
00438                 num_val = 
00439                         &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv ;
00440                 parent_num_val = 
00441                         &a_style->parent_style->
00442                         num_props[NUM_PROP_PADDING_BOTTOM].sv ;
00443                 break ;
00444 
00445         case DIR_LEFT:
00446                 num_val = & a_style->num_props[NUM_PROP_PADDING_LEFT].sv ;
00447                 parent_num_val = 
00448                         &a_style->parent_style->
00449                         num_props[NUM_PROP_PADDING_LEFT].sv ;
00450                 break ;
00451 
00452         default:
00453                 return CR_BAD_PARAM_ERROR ;
00454         }
00455 
00456         if (a_value->type == TERM_IDENT)
00457         {
00458                 if (a_value->content.str
00459                     && a_value->content.str->str
00460                     && !strncmp ((guchar*)"inherited", 
00461                                  a_value->content.str->str,
00462                                  strlen ("inherited")))
00463                 {
00464                         cr_num_copy (num_val, parent_num_val) ;
00465                         return CR_OK ;
00466                 }
00467                 else
00468                         return CR_UNKNOWN_TYPE_ERROR ;
00469         }
00470 
00471         g_return_val_if_fail (a_value->type == TERM_NUMBER
00472                               && a_value->content.num,
00473                               CR_UNKNOWN_TYPE_ERROR) ;
00474 
00475         switch (a_value->content.num->type)
00476         {
00477         case NUM_LENGTH_EM:
00478         case NUM_LENGTH_EX:
00479         case NUM_LENGTH_PX:
00480         case NUM_LENGTH_IN:
00481         case NUM_LENGTH_CM:
00482         case NUM_LENGTH_MM:
00483         case NUM_LENGTH_PT:
00484         case NUM_LENGTH_PC:
00485         case NUM_PERCENTAGE:
00486                 status = cr_num_copy (num_val, a_value->content.num) ;
00487                 break ;
00488         default:
00489                 status = CR_UNKNOWN_TYPE_ERROR ;
00490                 break ;
00491         }
00492 
00493         return status ;
00494 }
00495 
00496 
00497 static enum CRStatus
00498 set_prop_border_x_width_from_value (CRStyle *a_style,
00499                                     CRTerm *a_value,
00500                                     enum CRDirection a_dir)
00501 {
00502         enum CRStatus status = CR_OK ;
00503         CRNum *num_val = NULL ;
00504 
00505         g_return_val_if_fail (a_value
00506                               && a_style,
00507                               CR_BAD_PARAM_ERROR) ;
00508 
00509         switch (a_dir)
00510         {
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 = 
00517                         &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv ;
00518                 break ;
00519 
00520         case DIR_BOTTOM:
00521                 num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv ;
00522                 break ;
00523 
00524         case DIR_LEFT:
00525                 num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv ;
00526                 break ;
00527 
00528         default:
00529                 return CR_BAD_PARAM_ERROR ;
00530                 break ;
00531         }
00532 
00533 
00534         if (a_value->type == TERM_IDENT)
00535         {
00536                 if (a_value->content.str && a_value->content.str->str)
00537                 {
00538                         if (!strncmp ("thin", 
00539                                       a_value->content.str->str,
00540                                       strlen ("thin")))
00541                         {
00542                                 cr_num_set (num_val, BORDER_THIN,
00543                                             NUM_LENGTH_PX) ;
00544                         }
00545                         else if (!strncmp ("medium",
00546                                            a_value->content.str->str,
00547                                            strlen ("medium")))
00548                         {
00549                                 cr_num_set (num_val, BORDER_MEDIUM,
00550                                             NUM_LENGTH_PX) ;
00551                         }
00552                         else if (!strncmp ("thick",
00553                                            a_value->content.str->str,
00554                                            strlen ("thick")))
00555                         {
00556                                 cr_num_set (num_val, BORDER_THICK,
00557                                             NUM_LENGTH_PX) ;
00558                         }
00559                         else
00560                         {
00561                                 return CR_UNKNOWN_TYPE_ERROR ;
00562                         }
00563                 }
00564         }
00565         else if (a_value->type == TERM_NUMBER)
00566         {
00567                 if (a_value->content.num)
00568                 {
00569                         cr_num_copy (num_val, a_value->content.num) ;
00570                 }
00571         }
00572         else if (a_value->type != TERM_NUMBER
00573                  || a_value->content.num == NULL)
00574         {
00575                 return CR_UNKNOWN_TYPE_ERROR ;
00576         }
00577         
00578         return status ;
00579 }
00580 
00581 
00582 static enum CRStatus
00583 set_prop_border_x_style_from_value (CRStyle *a_style,
00584                                     CRTerm *a_value,
00585                                     enum CRDirection a_dir)
00586 {
00587         enum CRStatus status = CR_OK ;
00588         enum CRBorderStyle *border_style_ptr, *parent_border_style_ptr ;
00589 
00590         g_return_val_if_fail (a_style && a_value, 
00591                               CR_BAD_PARAM_ERROR) ;
00592      
00593         switch (a_dir)
00594         {
00595         case DIR_TOP:
00596                 border_style_ptr = &a_style->
00597                         border_style_props[BORDER_STYLE_PROP_TOP] ;
00598                 parent_border_style_ptr = (a_style->parent_style)?
00599                         &a_style->parent_style->
00600                         border_style_props[BORDER_STYLE_PROP_TOP]: NULL ;
00601 
00602                 break ;
00603 
00604         case DIR_RIGHT:
00605                 border_style_ptr = 
00606                         &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT] ;
00607 
00608                 parent_border_style_ptr = (a_style->parent_style)?
00609                         &a_style->parent_style->
00610                         border_style_props[BORDER_STYLE_PROP_RIGHT] : NULL ;
00611                 break ;
00612 
00613         case DIR_BOTTOM:
00614                 border_style_ptr = &a_style->
00615                         border_style_props[BORDER_STYLE_PROP_BOTTOM] ;
00616                 parent_border_style_ptr = (a_style->parent_style)?
00617                         &a_style->parent_style->
00618                         border_style_props[BORDER_STYLE_PROP_BOTTOM] : NULL;
00619                 break ;
00620 
00621         case DIR_LEFT:
00622                 border_style_ptr = &a_style->
00623                         border_style_props[BORDER_STYLE_PROP_LEFT] ;
00624                 parent_border_style_ptr = (a_style->parent_style)?
00625                         &a_style->parent_style->
00626                         border_style_props[BORDER_STYLE_PROP_LEFT] : NULL;
00627                 break ;
00628 
00629         default:
00630                 break ;
00631         }
00632         
00633         if (a_value->type != TERM_IDENT
00634             || !a_value->content.str)
00635         {
00636                 return CR_UNKNOWN_TYPE_ERROR ;
00637         }
00638 
00639         if (!strncmp ("none", 
00640                       a_value->content.str->str, 
00641                       strlen ("none")))
00642         {
00643                 *border_style_ptr = BORDER_STYLE_NONE ;
00644         }
00645         else if (!strncmp ("hidden", 
00646                            a_value->content.str->str,
00647                            strlen ("hidden")))
00648         {
00649                 *border_style_ptr = BORDER_STYLE_HIDDEN ;
00650         }
00651         else if (!strncmp ("dotted", 
00652                            a_value->content.str->str, 
00653                            strlen ("dotted")))
00654         {
00655                 *border_style_ptr = BORDER_STYLE_DOTTED ;
00656         }
00657         else if (!strncmp ("dashed", 
00658                            a_value->content.str->str, 
00659                            strlen ("dashed")))
00660         {
00661                 *border_style_ptr = BORDER_STYLE_DASHED ;
00662         }
00663         else if (!strncmp ("solid", 
00664                            a_value->content.str->str, 
00665                            strlen ("solid")))
00666         {
00667                 *border_style_ptr = BORDER_STYLE_SOLID ;
00668         }
00669         else if (!strncmp ("double", 
00670                            a_value->content.str->str, 
00671                            strlen ("double")))
00672         {
00673                 *border_style_ptr = BORDER_STYLE_DOUBLE ;
00674         }
00675         else if (!strncmp ("groove", 
00676                            a_value->content.str->str, 
00677                            strlen ("groove")))
00678         {
00679                 *border_style_ptr = BORDER_STYLE_GROOVE ;
00680         }
00681         else if (!strncmp ("ridge", 
00682                            a_value->content.str->str, 
00683                            strlen ("ridge")))
00684         {
00685                 *border_style_ptr = BORDER_STYLE_RIDGE ;
00686         }
00687         else if (!strncmp ("inset", 
00688                            a_value->content.str->str, 
00689                            strlen ("inset")))
00690         {
00691                 *border_style_ptr = BORDER_STYLE_INSET ;
00692         }
00693         else if (!strncmp ("outset", 
00694                            a_value->content.str->str, 
00695                            strlen ("outset")))
00696         {
00697                 *border_style_ptr = BORDER_STYLE_OUTSET ;
00698         }
00699         else if (!strncmp ("inherit", 
00700                            a_value->content.str->str, 
00701                            strlen ("inherit")))
00702         {
00703                 if (parent_border_style_ptr)
00704                         *border_style_ptr = *parent_border_style_ptr ;
00705         }
00706         else
00707         {
00708                 status = CR_UNKNOWN_TYPE_ERROR ;
00709         }
00710 
00711         return status ;
00712 }
00713 
00714 static enum CRStatus
00715 set_prop_margin_x_from_value (CRStyle *a_style, CRTerm *a_value,
00716                               enum CRDirection a_dir)
00717 {
00718         enum CRStatus status = CR_OK ;
00719         CRNum *num_val = NULL, *parent_num_val = NULL ;
00720 
00721         g_return_val_if_fail (a_style && a_value, 
00722                               CR_BAD_PARAM_ERROR) ;
00723 
00724         switch (a_dir)
00725         {
00726         case DIR_TOP:
00727                 num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv ;
00728                 parent_num_val = 
00729                         &a_style->parent_style->
00730                         num_props[NUM_PROP_MARGIN_TOP].sv ;
00731                 break ;
00732 
00733         case DIR_RIGHT:
00734                 num_val = 
00735                         &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv ;
00736 
00737                 parent_num_val = 
00738                         &a_style->parent_style->
00739                         num_props[NUM_PROP_MARGIN_RIGHT].sv ;
00740                 break ;
00741 
00742         case DIR_BOTTOM:
00743                 num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv ;
00744                 parent_num_val = 
00745                         &a_style->parent_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv ;
00746                 break ;
00747 
00748         case DIR_LEFT:
00749                 num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv ;
00750                 parent_num_val = 
00751                         &a_style->parent_style->
00752                         num_props[NUM_PROP_MARGIN_LEFT].sv ;
00753                 break ;
00754 
00755         default:
00756                 break ;
00757         }
00758 
00759         switch (a_value->type)
00760         {
00761         case TERM_IDENT:
00762                 if (a_value->content.str 
00763                     && a_value->content.str->str
00764                     && !strncmp (a_value->content.str->str,
00765                                  "inherit", strlen ("inherit")))
00766                 {
00767                         status = cr_num_copy (num_val, parent_num_val) ;
00768                 }
00769                 else if (a_value->content.str 
00770                          && a_value->content.str->str
00771                          && !strncmp (a_value->content.str->str,
00772                                       "auto", strlen ("auto")))
00773                 {
00774                         status = cr_num_set (num_val, 0.0, NUM_AUTO) ;
00775                 }
00776                 else
00777                 {
00778                         status = CR_UNKNOWN_TYPE_ERROR ;
00779                 }
00780 
00781         case TERM_NUMBER:
00782                 status = cr_num_copy (num_val, a_value->content.num) ;
00783                 break ;
00784 
00785         default:
00786                 status = CR_UNKNOWN_TYPE_ERROR ;
00787                 break ;
00788         }
00789 
00790         return status ;
00791 }
00792 
00793 struct CRPropDisplayValPair
00794 {
00795         const guchar *prop_name ;
00796         enum CRDisplayType type;
00797 } ;
00798 
00799 static enum CRStatus
00800 set_prop_display_from_value (CRStyle *a_style, CRTerm *a_value)
00801 {
00802         enum CRDisplayType default_display_val = DISPLAY_INLINE ;
00803         static const struct CRPropDisplayValPair disp_vals_map[] =
00804                 {
00805                         {"none", DISPLAY_NONE},
00806                         {"inline", DISPLAY_INLINE},
00807                         {"block", DISPLAY_BLOCK},
00808                         {"run-in", DISPLAY_RUN_IN},
00809                         {"compact", DISPLAY_COMPACT},
00810                         {"marker", DISPLAY_MARKER},
00811                         {"table", DISPLAY_TABLE},
00812                         {"inline-table", DISPLAY_INLINE_TABLE},
00813                         {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
00814                         {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
00815                         {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
00816                         {"table-row", DISPLAY_TABLE_ROW},
00817                         {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
00818                         {"table-column", DISPLAY_TABLE_COLUMN},
00819                         {"table-cell", DISPLAY_TABLE_CELL},
00820                         {"table-caption", DISPLAY_TABLE_CAPTION},
00821                         {"inherit", DISPLAY_INHERIT},
00822                         {NULL, DISPLAY_NONE}
00823                 } ;
00824 
00825         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
00826 
00827         /*Sets to its default value according to the css2 spec.*/
00828         a_style->display = default_display_val ;
00829 
00830         switch (a_value->type)
00831         {
00832         case TERM_IDENT:
00833         {
00834                 int i = 0 ;
00835 
00836                 if (!a_value->content.str || !a_value->content.str->str)
00837                         break ;
00838 
00839                 for (i = 0; disp_vals_map[i].prop_name ; i++)
00840                 {
00841                         if (!strncmp (disp_vals_map[i].prop_name,
00842                                       a_value->content.str->str,
00843                                       strlen 
00844                                       (disp_vals_map[i].prop_name)))
00845                         {
00846                                 a_style->display = disp_vals_map[i].type ;
00847                                 break ;
00848                         }
00849                 }
00850 
00851                 if (a_style->display == DISPLAY_INHERIT)
00852                 {
00853                         if (a_style->parent_style)
00854                         {
00855                                 a_style->display = 
00856                                         a_style->parent_style->display ;
00857                         }
00858                         else
00859                         {
00860                                 a_style->display = default_display_val ;
00861                         }
00862                 }
00863         }
00864         break ;
00865 
00866         default :
00867                 break ;
00868         }
00869 
00870         return CR_OK ;
00871 }
00872 
00873 struct CRPropPositionValPair
00874 {
00875         const guchar * name ;
00876         enum CRPositionType type ;
00877 } ;
00878 
00879 static enum CRStatus
00880 set_prop_position_from_value (CRStyle *a_style, CRTerm *a_value)
00881 {
00882         enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR ;
00883         static const struct CRPropPositionValPair position_vals_map [] =
00884                 {
00885                         {"static", POSITION_STATIC},
00886                         {"relative", POSITION_RELATIVE},
00887                         {"absolute", POSITION_ABSOLUTE},
00888                         {"fixed", POSITION_FIXED},
00889                         {"inherited", POSITION_INHERIT},
00890                         {NULL, POSITION_STATIC} 
00891                         /*must alwas be the last one*/
00892                 } ;
00893 
00894         g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR) ;
00895 
00896         /*set to it's default value according to the css2 spec*/
00897         a_style->position = POSITION_STATIC ;
00898 
00899         switch (a_value->type)
00900         {
00901         case TERM_IDENT:
00902         {
00903                 int i = 0 ;
00904 
00905                 if (!a_value->content.str || !a_value->content.str->str)
00906                         break ;
00907 
00908                 for (i = 0; position_vals_map[i].name ; i++)
00909                 {
00910                         if (!strncmp (position_vals_map[i].name,
00911                                       a_value->content.str->str,
00912                                       strlen (position_vals_map[i].name)))
00913                         {
00914                                 a_style->position = 
00915                                         position_vals_map[i].type ;
00916                                 status = CR_OK ;
00917                                 break ;
00918                         }
00919                 }
00920                 if (a_style->position == POSITION_INHERIT)
00921                 {
00922                         if (a_style->parent_style)
00923                         {
00924                                 a_style->position  =
00925                                         a_style->parent_style->position ;
00926                         }
00927                         else
00928                         {
00929                                 a_style->position = POSITION_STATIC ;
00930                         }
00931                 }
00932         }
00933                 break ;
00934 
00935         default:
00936                 break ;
00937         }
00938 
00939         return CR_OK ;
00940 }
00941 
00942 static enum CRStatus
00943 set_prop_x_from_value (CRStyle *a_style, CRTerm *a_value,
00944                        enum CRDirection a_dir)
00945 {
00946         CRNum *box_offset = NULL, *parent_box_offset = NULL ;
00947 
00948         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
00949 
00950         
00951         if (!(a_value->type == TERM_NUMBER)
00952             && !(a_value->type == TERM_IDENT))
00953         {
00954                 return CR_UNKNOWN_PROP_VAL_ERROR ;
00955         }
00956         
00957         switch (a_dir)
00958         {
00959         case DIR_TOP:
00960                 box_offset = &a_style->num_props[NUM_PROP_TOP].sv ;
00961                 if (a_style->parent_style)
00962                         parent_box_offset = 
00963                                 &a_style->parent_style->
00964                                 num_props[NUM_PROP_TOP].sv ;
00965                 break ;
00966 
00967         case DIR_RIGHT: 
00968                 box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv ;
00969                 if (a_style->parent_style)
00970                         parent_box_offset = &a_style->parent_style->
00971                                 num_props[NUM_PROP_RIGHT].sv ;
00972                 break ;
00973 
00974         case DIR_BOTTOM:
00975                 box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv ;
00976                 if (a_style->parent_style)
00977                         parent_box_offset = 
00978                                 &a_style->parent_style->
00979                                 num_props[NUM_PROP_BOTTOM].sv ;
00980                 break ;
00981         case DIR_LEFT:
00982                 box_offset = &a_style->num_props[NUM_PROP_LEFT].sv ;
00983                 if (a_style->parent_style)
00984                         parent_box_offset = 
00985                                 &a_style->parent_style->
00986                                 num_props[NUM_PROP_LEFT].sv ;
00987                 break ;
00988 
00989         default:
00990                 break ;
00991         }
00992 
00993         box_offset->type = NUM_AUTO ;
00994 
00995         if (a_value->type == TERM_NUMBER 
00996             && a_value->content.num)
00997         {
00998                 cr_num_copy (box_offset, a_value->content.num) ;
00999         }
01000         else if (a_value->type == TERM_IDENT
01001                  && a_value->content.str
01002                  && a_value->content.str->str)
01003         {
01004                 if (!strncmp ("inherit", 
01005                               a_value->content.str->str,
01006                               strlen ("inherit")))
01007                 {
01008                         cr_num_copy (box_offset, 
01009                                      parent_box_offset) ;
01010                 }
01011                 else if (!strncmp ("auto", 
01012                                    a_value->content.str->str,
01013                                    strlen ("auto")))
01014                 {
01015                         box_offset->type = NUM_AUTO ;
01016                 }
01017         }
01018 
01019         return CR_OK ;
01020 }
01021 
01022 
01023 static enum CRStatus
01024 set_prop_float (CRStyle *a_style, CRTerm *a_value)
01025 {
01026         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
01027 
01028         /*the default float type as specified by the css2 spec*/
01029         a_style->float_type = FLOAT_NONE ;
01030 
01031         if (a_value->type != TERM_IDENT
01032             || !a_value->content.str
01033             || !a_value->content.str->str) 
01034         {/*unknow type, the float type is set to it's default value*/
01035                 return CR_OK ;
01036         }
01037 
01038         if (!strncmp ("none",
01039                       a_value->content.str->str,
01040                       strlen ("none")))
01041         {
01042                 a_style->float_type = FLOAT_NONE ;
01043         }
01044         else if (!strncmp ("left",
01045                            a_value->content.str->str,
01046                            strlen ("left")))
01047         {
01048                 a_style->float_type = FLOAT_LEFT ;
01049         }
01050         else if (!strncmp ("right",
01051                            a_value->content.str->str,
01052                            strlen ("right")))
01053         {
01054                 a_style->float_type = FLOAT_RIGHT ;
01055         }
01056         else if (!strncmp ("inherit",
01057                            a_value->content.str->str,
01058                            strlen ("inherit")))
01059         {
01060                 a_style->float_type = 
01061                         a_style->parent_style->float_type ;
01062         }
01063 
01064         return CR_OK ;        
01065 }
01066 
01067 
01068 static enum CRStatus
01069 set_prop_width (CRStyle *a_style, CRTerm *a_value)
01070 {
01071         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
01072 
01073         
01074         a_style->num_props[NUM_PROP_WIDTH].sv.type = NUM_AUTO ;
01075         
01076         if (a_value->type == TERM_IDENT)
01077         {
01078                 if (a_value->content.str
01079                     && a_value->content.str->str)
01080                 {
01081                         if (!strncmp ("auto",
01082                                       a_value->content.str->str,
01083                                       strlen ("auto")))
01084                         {
01085                                 a_style->num_props[NUM_PROP_WIDTH].sv.type = 
01086                                         NUM_AUTO ;
01087                         }
01088                         else if (!strncmp ("inherit",
01089                                            a_value->content.str->str,
01090                                            strlen ("inherit")))
01091                         {
01092                                 cr_num_copy 
01093                                         (&a_style->
01094                                          num_props[NUM_PROP_WIDTH].sv,
01095                                          &a_style->parent_style->
01096                                          num_props[NUM_PROP_WIDTH].sv) ;
01097                         }
01098                 }
01099         }
01100         else if (a_value->type == TERM_NUMBER)
01101         {
01102                 if (a_value->content.num)
01103                 {
01104                         cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
01105                                      a_value->content.num) ;
01106                 }
01107         }
01108 
01109         return CR_OK ;
01110 }
01111 
01112 static enum CRStatus
01113 set_prop_color_rgb (CRStyle *a_style, CRTerm *a_value)
01114 {
01115         g_return_val_if_fail (a_style && a_value,
01116                               CR_BAD_PARAM_ERROR) ;
01117 
01118         if (a_value->type == TERM_RGB)
01119         {
01120                 if (a_value->content.rgb)
01121                 {
01122                         cr_rgb_set_from_rgb
01123                                 (&a_style->rgb_props[RGB_PROP_COLOR].sv,
01124                                  a_value->content.rgb) ;
01125                 }
01126 
01127         }
01128 
01129         return CR_OK ;
01130 }
01131 
01132 static enum CRStatus
01133 set_prop_background_color (CRStyle *a_style, CRTerm *a_value)
01134 {
01135         enum CRStatus status = CR_OK ;
01136 
01137         g_return_val_if_fail (a_style && a_value,
01138                               CR_BAD_PARAM_ERROR) ;
01139 
01140         switch (a_value->type)
01141         {
01142         case TERM_RGB:
01143                 if (a_value->content.rgb)
01144                 {
01145                         status = cr_rgb_set_from_rgb
01146                                 (&a_style->
01147                                  rgb_props[RGB_PROP_BACKGROUND_COLOR].sv,
01148                                  a_value->content.rgb) ;
01149                 }
01150                 break ;
01151 
01152         case TERM_IDENT:
01153                 status = cr_rgb_set_from_name 
01154                         (&a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv,
01155                          a_value->content.str->str) ;
01156                 break ;
01157 
01158         case TERM_HASH:
01159                 status = cr_rgb_set_from_hex_str
01160                         (&a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv, 
01161                          a_value->content.str->str) ;
01162                 break ;
01163 
01164         default:
01165                 status =  CR_UNKNOWN_TYPE_ERROR ;
01166                 break ;
01167         }
01168 
01169         return status ;
01170 }
01171 
01172 /**
01173  *Sets border-top-color, border-right-color,
01174  *border-bottom-color or border-left-color properties
01175  *in the style structure. The value is taken from a
01176  *css2 term of type IDENT or RGB.
01177  *@param a_style the style structure to set.
01178  *@param a_value the css2 term to take the color information from.
01179  *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
01180  *@return CR_OK upon successfull completion, an error code otherwise.
01181  */
01182 static enum CRStatus
01183 set_prop_border_x_color_from_value (CRStyle *a_style, CRTerm *a_value,
01184                                     enum CRDirection a_dir)
01185 {
01186         CRRgb *rgb_color = NULL ;
01187         enum CRStatus status = CR_OK ;
01188 
01189         g_return_val_if_fail (a_style && a_value,
01190                               CR_BAD_PARAM_ERROR) ;
01191         
01192         switch (a_dir)
01193         {
01194         case DIR_TOP:
01195                 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv ;
01196                 break ;
01197 
01198         case DIR_RIGHT:
01199                 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv ;
01200                 break ;
01201 
01202         case DIR_BOTTOM:
01203                 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
01204                 break ;
01205 
01206         case DIR_LEFT:
01207                 rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv ;
01208                 break ;
01209 
01210         default:
01211                 cr_utils_trace_info ("unknown DIR type") ;
01212                 return CR_BAD_PARAM_ERROR ;
01213         }
01214 
01215         status = CR_UNKNOWN_PROP_VAL_ERROR ;
01216 
01217         if (a_value->type == TERM_IDENT)
01218         {
01219                 if (a_value->content.str && a_value->content.str->str)
01220                 {
01221                         status = cr_rgb_set_from_name 
01222                                 (rgb_color, a_value->content.str->str) ;
01223                         
01224                 }
01225 
01226                 if (status != CR_OK)
01227                 {
01228                         cr_rgb_set_from_name (rgb_color, "black") ;
01229                 }
01230         }
01231         else if (a_value->type == TERM_RGB)
01232         {
01233                 if (a_value->content.rgb)
01234                 {
01235                         status = cr_rgb_set_from_rgb 
01236                                 (rgb_color, a_value->content.rgb) ;
01237                 }
01238         }
01239 
01240         return status ;
01241 }
01242 
01243 
01244 static enum CRStatus
01245 set_prop_border_x_from_value (CRStyle *a_style, CRTerm *a_value,
01246                               enum CRDirection a_dir)
01247 {
01248         CRTerm *cur_term = NULL ;
01249 
01250         enum CRStatus status = CR_OK ;
01251 
01252         g_return_val_if_fail (a_style && a_value,
01253                               CR_BAD_PARAM_ERROR) ;
01254 
01255         for (cur_term = a_value ; cur_term ; cur_term = cur_term->next)
01256         {
01257                 status = 
01258                         set_prop_border_x_width_from_value (a_style, cur_term,
01259                                                             a_dir) ;
01260 
01261                 if (status != CR_OK)
01262                 {
01263                         status = set_prop_border_x_style_from_value 
01264                                 (a_style, cur_term, a_dir) ;
01265                 }
01266 
01267                 if (status != CR_OK)
01268                 {
01269                         status = set_prop_border_x_color_from_value 
01270                                 (a_style, cur_term, a_dir) ;
01271                 }
01272         }
01273 
01274         return CR_OK ;
01275 }
01276 
01277 static enum CRStatus
01278 set_prop_border_from_value (CRStyle *a_style, CRTerm *a_value)
01279 {
01280         enum CRDirection direction = 0 ;
01281 
01282         g_return_val_if_fail (a_style && a_value,
01283                               CR_BAD_PARAM_ERROR) ;
01284 
01285         for (direction = 0 ; direction < NB_DIRS ; direction ++)
01286         {
01287                 set_prop_border_x_from_value (a_style, a_value, direction) ;
01288         }
01289 
01290         return CR_OK ;
01291 }
01292 
01293 static enum CRStatus
01294 set_prop_padding_from_value (CRStyle *a_style, CRTerm *a_value)
01295 {
01296         CRTerm *cur_term = NULL ;
01297         enum CRDirection direction = 0 ;
01298         enum CRStatus status = CR_OK ;
01299 
01300         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
01301 
01302         cur_term = a_value ;
01303         while (cur_term && cur_term->type != TERM_NUMBER)
01304         {
01305                 cur_term = cur_term->next ;
01306         }
01307 
01308         if (!cur_term)
01309                 return CR_OK ;
01310 
01311         for (direction = 0 ; direction < NB_DIRS ; direction ++)
01312         {
01313                 set_prop_padding_x_from_value (a_style, cur_term,
01314                                                direction) ;
01315         }
01316         cur_term = cur_term->next ;
01317 
01318         while (cur_term && cur_term->type != TERM_NUMBER)
01319         {
01320                 cur_term = cur_term->next ;
01321         }
01322         if (!cur_term)
01323                 return CR_OK ;
01324 
01325         set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT) ;
01326         set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT) ;
01327 
01328         while (cur_term && cur_term->type != TERM_NUMBER)
01329         {
01330                 cur_term = cur_term->next ;
01331         }
01332         if (!cur_term)
01333                 return CR_OK ;
01334         
01335         set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM) ;
01336 
01337         while (cur_term && cur_term->type != TERM_NUMBER)
01338         {
01339                 cur_term = cur_term->next ;
01340         }
01341         if (!cur_term)
01342                 return CR_OK ;
01343 
01344         status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT) ;
01345 
01346         return status ;
01347 }
01348 
01349 static enum CRStatus
01350 set_prop_margin_from_value (CRStyle *a_style, CRTerm *a_value)
01351 {
01352         CRTerm *cur_term = NULL ;
01353         enum CRDirection direction = 0 ;
01354         enum CRStatus status = CR_OK ;
01355 
01356         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
01357 
01358         cur_term = a_value ;
01359         while (cur_term && cur_term->type != TERM_NUMBER)
01360         {
01361                 cur_term = cur_term->next ;
01362         }
01363 
01364         if (!cur_term)
01365                 return CR_OK ;
01366 
01367         for (direction = 0 ; direction < NB_DIRS ; direction ++)
01368         {
01369                 set_prop_margin_x_from_value (a_style, cur_term,
01370                                               direction) ;
01371         }
01372         cur_term = cur_term->next ;
01373 
01374         while (cur_term && cur_term->type != TERM_NUMBER)
01375         {
01376                 cur_term = cur_term->next ;
01377         }
01378         if (!cur_term)
01379                 return CR_OK ;
01380 
01381         set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT) ;
01382         set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT) ;
01383 
01384         while (cur_term && cur_term->type != TERM_NUMBER)
01385         {
01386                 cur_term = cur_term->next ;
01387         }
01388         if (!cur_term)
01389                 return CR_OK ;
01390         
01391         set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM) ;
01392 
01393         while (cur_term && cur_term->type != TERM_NUMBER)
01394         {
01395                 cur_term = cur_term->next ;
01396         }
01397         if (!cur_term)
01398                 return CR_OK ;
01399 
01400         status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT) ;
01401 
01402         return status ;
01403 }
01404 
01405 static enum CRStatus
01406 set_prop_font_family_from_value (CRStyle *a_style, CRTerm *a_value)
01407 {
01408         CRTerm *cur_term = NULL ;
01409         CRFontFamily *font_family = NULL, *cur_ff = NULL, *cur_ff2 = NULL;
01410 
01411         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
01412 
01413         
01414         for (cur_term = a_value ; cur_term ; cur_term = cur_term->next)
01415         {
01416                 switch (cur_term->type)
01417                 {
01418                 case TERM_IDENT:
01419                 {
01420                         enum CRFontFamilyType font_type ;
01421 
01422                         if (cur_term->content.str
01423                             && cur_term->content.str->str
01424                             && ! strcmp (cur_term->content.str->str,
01425                                          "sans-serif"))
01426                         {
01427                                 font_type = FONT_FAMILY_SANS_SERIF ;
01428                         }
01429                         else if (cur_term->content.str
01430                                  && cur_term->content.str->str
01431                                  && ! strcmp (cur_term->content.str->str,
01432                                               "serif"))
01433                         {
01434                                 font_type = FONT_FAMILY_SERIF ;
01435                         }
01436                         else if (cur_term->content.str
01437                                  && cur_term->content.str->str
01438                                  && ! strcmp (cur_term->content.str->str,
01439                                               "cursive"))
01440                         {
01441                                 font_type = FONT_FAMILY_CURSIVE ;
01442                         }
01443                         else if (cur_term->content.str
01444                                  && cur_term->content.str->str
01445                                  && ! strcmp (cur_term->content.str->str,
01446                                               "fantasy"))
01447                         {
01448                                 font_type = FONT_FAMILY_FANTASY ;
01449                         }
01450                         else if (cur_term->content.str
01451                                  && cur_term->content.str->str
01452                                  && ! strcmp (cur_term->content.str->str,
01453                                               "monospace"))
01454                         {
01455                                 font_type = FONT_FAMILY_MONOSPACE ;
01456                         }
01457                         else
01458                         {
01459                                 /*
01460                                  *unknown property value.
01461                                  *ignore it.
01462                                  */
01463                                 continue ;
01464                         }
01465 
01466                         cur_ff = 
01467                                 cr_font_family_new (font_type, NULL) ;
01468                 }                   
01469                 break ;
01470 
01471                 case TERM_STRING:
01472                 {
01473                         if (cur_term->content.str
01474                             && cur_term->content.str->str)
01475                         {
01476                                 cur_ff = cr_font_family_new 
01477                                         (FONT_FAMILY_NON_GENERIC,
01478                                          cur_term->content.str->str) ;
01479                         }
01480                 }
01481                 break ;
01482 
01483                 default:
01484                         break ;
01485                 }
01486 
01487                 cur_ff2 = cr_font_family_append (font_family,
01488                                                  cur_ff) ;
01489                 if (cur_ff2)
01490                 {
01491                         font_family = cur_ff2 ;
01492                 }
01493         }
01494         
01495         if (font_family)
01496         {
01497                 if (a_style->font_family)
01498                 {
01499                         cr_font_family_destroy (a_style->font_family) ;
01500                         a_style->font_family = font_family ;
01501                 }
01502         }
01503 
01504         return CR_OK ;
01505 }
01506 
01507 static enum CRStatus
01508 init_style_font_size_field (CRStyle *a_style)
01509 {
01510         g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR) ;
01511         
01512         if (!a_style->font_size)
01513         {
01514                 a_style->font_size = cr_font_size_new () ;
01515                 if (!a_style->font_size)
01516                 {
01517                         return CR_INSTANCIATION_FAILED_ERROR ;
01518                 }
01519         }
01520         else
01521         {
01522                 cr_font_size_clear (a_style->font_size) ;
01523         }
01524         
01525         return CR_OK ;
01526 }
01527 
01528 static enum CRStatus
01529 set_prop_font_size_from_value (CRStyle *a_style, CRTerm *a_value)
01530 {
01531         enum CRStatus status = CR_OK ;
01532 
01533         g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR) ;
01534 
01535         switch (a_value->type)
01536         {
01537         case TERM_IDENT:
01538                 if (a_value->content.str 
01539                     && a_value->content.str->str
01540                     && !strcmp (a_value->content.str->str, "xx-small"))
01541                 {
01542                         status = init_style_font_size_field (a_style) ;
01543                         g_return_val_if_fail (status == CR_OK,
01544                                               status) ;
01545 
01546                         a_style->font_size->type = 
01547                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01548                         a_style->font_size->value.predefined = 
01549                                 FONT_SIZE_XX_SMALL ;
01550                         
01551                 }
01552                 else if (a_value->content.str 
01553                          && a_value->content.str->str
01554                          && !strcmp (a_value->content.str->str, "x-small"))
01555                 {
01556                         status = init_style_font_size_field (a_style) ;
01557                         g_return_val_if_fail (status == CR_OK,
01558                                               status) ;
01559 
01560                         a_style->font_size->type = 
01561                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01562                         a_style->font_size->value.predefined = 
01563                                 FONT_SIZE_X_SMALL ;
01564                 }
01565                 else if (a_value->content.str 
01566                          && a_value->content.str->str
01567                          && !strcmp (a_value->content.str->str, "small"))
01568                 {
01569                         status = init_style_font_size_field (a_style) ;
01570                         g_return_val_if_fail (status == CR_OK,
01571                                               status) ;
01572 
01573                         a_style->font_size->type = 
01574                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01575                         a_style->font_size->value.predefined = 
01576                                 FONT_SIZE_SMALL ;
01577                 }
01578                 else if (a_value->content.str 
01579                          && a_value->content.str->str
01580                          && !strcmp (a_value->content.str->str, "medium"))
01581                 {
01582                         status = init_style_font_size_field (a_style) ;
01583                         g_return_val_if_fail (status == CR_OK,
01584                                               status) ;
01585 
01586                         a_style->font_size->type = 
01587                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01588                         a_style->font_size->value.predefined = 
01589                                 FONT_SIZE_MEDIUM ;
01590                 }
01591                 else if (a_value->content.str 
01592                          && a_value->content.str->str
01593                          && !strcmp (a_value->content.str->str, "large"))
01594                 {
01595                         status = init_style_font_size_field (a_style) ;
01596                         g_return_val_if_fail (status == CR_OK,
01597                                               status) ;
01598 
01599                         a_style->font_size->type = 
01600                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01601                         a_style->font_size->value.predefined = 
01602                                 FONT_SIZE_LARGE ;
01603                 }
01604                 else if (a_value->content.str 
01605                          && a_value->content.str->str
01606                          && !strcmp (a_value->content.str->str, "x-large"))
01607                 {
01608                         status = init_style_font_size_field (a_style) ;
01609                         g_return_val_if_fail (status == CR_OK,
01610                                               status) ;
01611 
01612                         a_style->font_size->type = 
01613                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01614                         a_style->font_size->value.predefined = 
01615                                 FONT_SIZE_X_LARGE ;
01616                 }
01617                 else if (a_value->content.str 
01618                          && a_value->content.str->str
01619                          && !strcmp (a_value->content.str->str, "xx-large"))
01620                 {
01621                         status = init_style_font_size_field (a_style) ;
01622                         g_return_val_if_fail (status == CR_OK,
01623                                               status) ;
01624 
01625                         a_style->font_size->type = 
01626                                 PREDEFINED_ABSOLUTE_FONT_SIZE ;
01627                         a_style->font_size->value.predefined = 
01628                                 FONT_SIZE_XX_LARGE ;
01629                 }
01630                 else if (a_value->content.str 
01631                          && a_value->content.str->str
01632                          && !strcmp (a_value->content.str->str, "larger"))
01633                 {
01634                         status = init_style_font_size_field (a_style) ;
01635                         g_return_val_if_fail (status == CR_OK, status) ;
01636 
01637                         a_style->font_size->type = 
01638                                 RELATIVE_FONT_SIZE ;
01639                         a_style->font_size->value.relative = 
01640                                 FONT_SIZE_LARGER ;
01641                 }
01642                 else if (a_value->content.str 
01643                          && a_value->content.str->str
01644                          && !strcmp (a_value->content.str->str, "smaller"))
01645                 {
01646                         status = init_style_font_size_field (a_style) ;
01647                         g_return_val_if_fail (status == CR_OK, status) ;
01648 
01649                         a_style->font_size->type = 
01650                                 RELATIVE_FONT_SIZE ;
01651                         a_style->font_size->value.relative = 
01652                                 FONT_SIZE_SMALLER ;
01653                 }
01654                 else if (a_value->content.str 
01655                          && a_value->content.str->str
01656                          && !strcmp (a_value->content.str->str, "inherit"))
01657                 {
01658                         status = init_style_font_size_field (a_style) ;
01659                         g_return_val_if_fail (status == CR_OK, status) ;
01660 
01661                         if (a_style->parent_style
01662                             && a_style->parent_style->font_style)
01663                         {
01664                                 cr_font_size_copy 
01665                                         (a_style->font_size,
01666                                          a_style->parent_style->font_size) ;
01667                         }
01668                 }
01669                 else
01670                 {
01671                         return CR_UNKNOWN_PROP_VAL_ERROR ;
01672                 }
01673                 break ;
01674 
01675         case TERM_NUMBER:
01676                 if (a_value->content.num)
01677                 {
01678                         status = init_style_font_size_field (a_style) ;
01679                         g_return_val_if_fail (status == CR_OK, status) ;
01680 
01681                         a_style->font_size->type = ABSOLUTE_FONT_SIZE ;
01682                         a_style->font_size->value.absolute = 
01683                                 cr_num_dup (a_value->content.num) ;
01684                 }
01685                 break ;
01686 
01687         default:
01688                 return CR_UNKNOWN_PROP_VAL_ERROR ;
01689         }
01690 
01691         return CR_OK ;
01692 }
01693 
01694 static enum CRStatus
01695 set_prop_font_style_from_value (CRStyle *a_style, CRTerm *a_value)
01696 {
01697         enum CRStatus status = CR_OK ;
01698 
01699         g_return_val_if_fail (a_style && a_value,
01700                               CR_BAD_PARAM_ERROR) ;
01701 
01702         switch (a_value->type)
01703         {
01704         case TERM_IDENT:
01705                 if (a_value->content.str && a_value->content.str->str)
01706                 {
01707                         if (!strcmp (a_value->content.str->str, "normal"))
01708                         {
01709                                 a_style->font_style = FONT_STYLE_NORMAL ;
01710                         }
01711                         else if (!strcmp (a_value->content.str->str, "italic"))
01712                         {
01713                                 a_style->font_style = FONT_STYLE_ITALIC ;
01714                         }
01715                         else if (!strcmp (a_value->content.str->str, "oblique"))
01716                         {
01717                                 a_style->font_style = FONT_STYLE_OBLIQUE ;
01718                         }
01719                         else if (!strcmp (a_value->content.str->str, "inherit"))
01720                         {
01721                                 if (!a_style->font_style)
01722                                         a_style->font_style = FONT_STYLE_NORMAL;
01723                                 else
01724                                         a_style->font_style = 
01725                                                 a_style->parent_style->
01726                                                 font_style ;
01727                         }
01728                         else
01729                         {
01730                                 status = CR_UNKNOWN_PROP_VAL_ERROR ;
01731                         }
01732                 }
01733                 break ;
01734 
01735         default:
01736                 status = CR_UNKNOWN_PROP_VAL_ERROR ;
01737                 break ;
01738         }
01739 
01740         return status ;
01741 }
01742 
01743 static enum CRStatus
01744 set_prop_font_weight_from_value (CRStyle *a_style, CRTerm *a_value)
01745 {
01746         enum CRStatus status = CR_OK ;
01747 
01748         g_return_val_if_fail (a_style && a_value,
01749                               CR_BAD_PARAM_ERROR) ;
01750 
01751         switch (a_value->type)
01752         {
01753         case TERM_IDENT:
01754                 if (a_value->content.str && a_value->content.str->str)
01755                 {
01756                         if (!strcmp (a_value->content.str->str,
01757                                      "normal"))
01758                         {
01759                                 a_style->font_weight = FONT_WEIGHT_NORMAL ;
01760                         }
01761                         else if (!strcmp (a_value->content.str->str,
01762                                           "bold"))
01763                         {
01764                                 a_style->font_weight = FONT_WEIGHT_BOLD ;
01765                         }
01766                         else if (!strcmp (a_value->content.str->str,
01767                                           "bolder"))
01768                         {
01769                                 a_style->font_weight = FONT_WEIGHT_BOLDER ;
01770                         }
01771                         else if (!strcmp (a_value->content.str->str,
01772                                           "lighter"))
01773                         {
01774                                 a_style->font_weight = FONT_WEIGHT_LIGHTER ;
01775                         }
01776                         else
01777                         {
01778                                 status = CR_UNKNOWN_PROP_VAL_ERROR ;
01779                         }
01780 
01781                 }
01782                 break ;
01783 
01784         case TERM_NUMBER:
01785                 if (a_value->content.num 
01786                     && (a_value->content.num->type == NUM_GENERIC
01787                         ||a_value->content.num->type == NUM_AUTO))
01788                 {
01789                         if (a_value->content.num->val <= 150)
01790                         {
01791                                 a_style->font_weight = FONT_WEIGHT_100 ;
01792                         }
01793                         else if (a_value->content.num->val <= 250)
01794                         {
01795                                 a_style->font_weight = FONT_WEIGHT_200 ;
01796                         }
01797                         else if (a_value->content.num->val <= 350)
01798                         {
01799                                 a_style->font_weight = FONT_WEIGHT_300 ;
01800                         }
01801                         else if (a_value->content.num->val <= 450)
01802                         {
01803                                 a_style->font_weight = FONT_WEIGHT_400 ;
01804                         }
01805                         else if (a_value->content.num->val <= 550)
01806                         {
01807                                 a_style->font_weight = FONT_WEIGHT_500 ;
01808                         }
01809                         else if (a_value->content.num->val <= 650)
01810                         {
01811                                 a_style->font_weight = FONT_WEIGHT_600 ;
01812                         }
01813                         else if (a_value->content.num->val <= 750)
01814                         {
01815                                 a_style->font_weight = FONT_WEIGHT_700 ;
01816                         }
01817                         else if (a_value->content.num->val <= 850)
01818                         {
01819                                 a_style->font_weight = FONT_WEIGHT_800 ;
01820                         }
01821                         else
01822                         {
01823                                 a_style->font_weight = FONT_WEIGHT_900 ;
01824                         }                        
01825                 }
01826                 break ;
01827 
01828         default:
01829                 status = CR_UNKNOWN_PROP_VAL_ERROR ;
01830                 break ;
01831         }
01832 
01833         return status ;
01834 }
01835 
01836 /******************
01837  *Public methods
01838  ******************/
01839 
01840 /**
01841  *Default constructor of #CRStyle.
01842  */
01843 CRStyle *
01844 cr_style_new (void)
01845 {
01846         CRStyle *result = NULL ;
01847 
01848         result = g_try_malloc (sizeof (CRStyle)) ;
01849         if (!result)
01850         {
01851                 cr_utils_trace_info ("Out of memory") ;
01852                 return NULL ;
01853         }
01854         memset (result, 0, sizeof (CRStyle)) ;
01855         gv_prop_hash_ref_count ++ ;
01856 
01857         /*set the style properties to their default values*/
01858         cr_style_set_props_to_defaults (result) ;
01859 
01860         return result ;
01861 }
01862 
01863 
01864 /**
01865  *Walks through a css2 property declaration, and populated the
01866  *according field(s) in the #CRStyle structure.
01867  *If the properties or their value(s) are/is not known, 
01868  *sets the corresponding field(s) of #CRStyle to its/their default 
01869  *value(s)
01870  *@param a_this the instance of #CRStyle to set.
01871  *@param a_decl the declaration from which the #CRStyle fields are set.
01872  *@return CR_OK upon successfull completion, an error code otherwise.
01873  */
01874 enum CRStatus
01875 cr_style_set_style_from_decl (CRStyle *a_this, CRDeclaration *a_decl)
01876 {
01877         CRTerm *value = NULL ;
01878         enum CRStatus status = CR_OK ;
01879 
01880         enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN ;
01881 
01882         g_return_val_if_fail (a_this && a_decl
01883                               && a_decl
01884                               && a_decl->property
01885                               && a_decl->property->str,
01886                               CR_BAD_PARAM_ERROR) ;
01887 
01888         prop_id = cr_style_get_prop_id (a_decl->property->str) ;
01889 
01890         value = a_decl->value ;
01891         switch (prop_id)
01892         {
01893         case PROP_ID_PADDING_TOP:
01894                 status = set_prop_padding_x_from_value 
01895                         (a_this, value, DIR_TOP) ;
01896                 break ;
01897 
01898         case PROP_ID_PADDING_RIGHT:
01899                 status = set_prop_padding_x_from_value 
01900                         (a_this, value, DIR_RIGHT) ;
01901                 break ;
01902         case PROP_ID_PADDING_BOTTOM:
01903                 status = set_prop_padding_x_from_value 
01904                         (a_this, value, DIR_BOTTOM) ;
01905                 break ;
01906 
01907         case PROP_ID_PADDING_LEFT:
01908                 status = set_prop_padding_x_from_value 
01909                         (a_this, value, DIR_LEFT) ;
01910                 break ;
01911 
01912         case PROP_ID_PADDING:
01913                 status = set_prop_padding_from_value (a_this, value) ;
01914                 break ;
01915 
01916         case PROP_ID_BORDER_TOP_WIDTH:
01917                 status = 
01918                         set_prop_border_x_width_from_value (a_this, value,
01919                                                             DIR_TOP) ;
01920                 break ;
01921 
01922         case PROP_ID_BORDER_RIGHT_WIDTH:
01923                 status = 
01924                         set_prop_border_x_width_from_value (a_this, value,
01925                                                             DIR_RIGHT) ;
01926                 break ;
01927 
01928         case PROP_ID_BORDER_BOTTOM_WIDTH:
01929                 status = 
01930                         set_prop_border_x_width_from_value (a_this, value,
01931                                                             DIR_BOTTOM) ;
01932                 break ;
01933 
01934         case PROP_ID_BORDER_LEFT_WIDTH:
01935                 status = 
01936                         set_prop_border_x_width_from_value (a_this, value,
01937                                                             DIR_LEFT) ;
01938                 break ;
01939 
01940         case PROP_ID_BORDER_TOP_STYLE:
01941                 status = 
01942                         set_prop_border_x_style_from_value (a_this, value,
01943                                                             DIR_TOP) ;
01944                 break ;
01945 
01946         case PROP_ID_BORDER_RIGHT_STYLE:
01947                 status = 
01948                         set_prop_border_x_style_from_value (a_this, value,
01949                                                             DIR_RIGHT) ;
01950                 break ;
01951 
01952         case PROP_ID_BORDER_BOTTOM_STYLE:
01953                 status = 
01954                         set_prop_border_x_style_from_value (a_this, value,
01955                                                             DIR_BOTTOM) ;
01956                 break ;
01957 
01958         case PROP_ID_BORDER_LEFT_STYLE: 
01959                 status = 
01960                         set_prop_border_x_style_from_value (a_this, value,
01961                                                             DIR_LEFT) ;
01962                 break ;
01963 
01964         case PROP_ID_BORDER_TOP_COLOR:
01965                 status =
01966                         set_prop_border_x_color_from_value (a_this, value,
01967                                                             DIR_TOP) ;
01968                 break ;
01969 
01970         case PROP_ID_BORDER_RIGHT_COLOR:
01971                 status =
01972                         set_prop_border_x_color_from_value (a_this, value,
01973                                                             DIR_RIGHT) ;
01974                 break ;
01975 
01976         case PROP_ID_BORDER_BOTTOM_COLOR:
01977                 status =
01978                         set_prop_border_x_color_from_value (a_this, value,
01979                                                             DIR_BOTTOM) ;
01980                 break ;
01981 
01982         case PROP_ID_BORDER_LEFT_COLOR:
01983                 status =
01984                         set_prop_border_x_color_from_value (a_this, value,
01985                                                             DIR_BOTTOM) ;
01986                 break ;
01987 
01988         case PROP_ID_BORDER_TOP:
01989                 status =
01990                         set_prop_border_x_from_value (a_this, value,
01991                                                       DIR_TOP) ;
01992                 break ;
01993 
01994         case PROP_ID_BORDER_RIGHT:
01995                 status =
01996                         set_prop_border_x_from_value (a_this, value,
01997                                                       DIR_TOP) ;
01998                 break ;
01999 
02000         case PROP_ID_BORDER_BOTTOM:
02001                 status =
02002                         set_prop_border_x_from_value (a_this, value,
02003                                                       DIR_BOTTOM) ;
02004                 break ;
02005 
02006         case PROP_ID_BORDER_LEFT:
02007                 status =
02008                         set_prop_border_x_from_value (a_this, value,
02009                                                       DIR_BOTTOM) ;
02010                 break ;
02011 
02012         case PROP_ID_MARGIN_TOP:
02013                 status = 
02014                         set_prop_margin_x_from_value (a_this, value,
02015                                                       DIR_TOP) ;
02016                 break ;
02017 
02018         case PROP_ID_BORDER:
02019                 status =
02020                         set_prop_border_from_value (a_this, value) ;
02021                 break ;
02022 
02023         case PROP_ID_MARGIN_RIGHT:
02024                 status = 
02025                         set_prop_margin_x_from_value (a_this, value,
02026                                                       DIR_RIGHT) ;
02027                 break ;
02028 
02029         case PROP_ID_MARGIN_BOTTOM:
02030                 status = 
02031                         set_prop_margin_x_from_value (a_this, value,
02032                                                       DIR_BOTTOM) ;
02033                 break ;
02034 
02035         case PROP_ID_MARGIN_LEFT:
02036                 status = 
02037                         set_prop_margin_x_from_value (a_this, value,
02038                                                       DIR_LEFT) ;
02039                 break ;
02040 
02041         case PROP_ID_MARGIN:
02042                 status =
02043                         set_prop_margin_from_value (a_this, value) ;
02044                 break ;
02045 
02046         case PROP_ID_DISPLAY:
02047                 status = 
02048                         set_prop_display_from_value (a_this, value) ;
02049                 break ;
02050 
02051         case PROP_ID_POSITION:
02052                 status = set_prop_position_from_value (a_this, value) ;
02053                 break ;
02054 
02055         case PROP_ID_TOP:
02056                 status = set_prop_x_from_value (a_this, value,
02057                                                 DIR_TOP) ;
02058                 break ;
02059 
02060         case PROP_ID_RIGHT:
02061                 status = set_prop_x_from_value (a_this, value,
02062                                                 DIR_RIGHT) ;
02063                 break ;
02064 
02065         case PROP_ID_BOTTOM:
02066                 status = set_prop_x_from_value (a_this, value,
02067                                                 DIR_BOTTOM) ;
02068                 break ;
02069 
02070         case PROP_ID_LEFT:
02071                 status = set_prop_x_from_value (a_this, value,
02072                                                 DIR_LEFT) ;
02073                 break ;
02074 
02075         case PROP_ID_FLOAT:
02076                 status = set_prop_float (a_this, value) ;
02077                 break ;
02078 
02079         case PROP_ID_WIDTH:
02080                 status = set_prop_width (a_this, value) ;
02081                 break ;
02082 
02083         case PROP_ID_COLOR:
02084                 status = set_prop_color_rgb (a_this, value) ;
02085                 break ;
02086 
02087         case PROP_ID_BACKGROUND_COLOR:
02088                 status = set_prop_background_color (a_this, value) ;
02089                 break ;
02090                 
02091         case PROP_ID_FONT_FAMILY:
02092                 status = 
02093                         set_prop_font_family_from_value (a_this, value) ;
02094                 break ;
02095 
02096         case PROP_ID_FONT_SIZE:
02097                 status =
02098                         set_prop_font_size_from_value (a_this, value) ;
02099                 break ;
02100 
02101         case PROP_ID_FONT_STYLE:
02102                 status =
02103                         set_prop_font_style_from_value (a_this, value) ;
02104                 break ;
02105 
02106         case PROP_ID_FONT_WEIGHT:
02107                 status =
02108                         set_prop_font_weight_from_value (a_this, value) ;
02109                 break ;
02110 
02111         default:
02112                 return CR_UNKNOWN_TYPE_ERROR ;
02113 
02114         }
02115 
02116         return status ;
02117 }
02118 
02119 /**
02120  *Increases the reference count
02121  *of the current instance of #CRStyle.
02122  *@param a_this the current instance of #CRStyle.
02123  *@return CR_OK upon successfull completion, an error code
02124  *otherwise.
02125  */
02126 enum CRStatus
02127 cr_style_ref (CRStyle *a_this)
02128 {
02129         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
02130 
02131         a_this->ref_count ++ ;
02132         return CR_OK ;
02133 }
02134 
02135 
02136 /**
02137  *Decreases the reference count of
02138  *the current instance of #CRStyle.
02139  *If the reference count reaches 0, the
02140  *instance of #CRStyle is destoyed.
02141  *@param a_this the current instance of #CRStyle.
02142  *@return TRUE if the instance has been destroyed, FALSE
02143  *otherwise.
02144  */
02145 gboolean
02146 cr_style_unref (CRStyle *a_this)
02147 {
02148         g_return_val_if_fail (a_this,
02149                               FALSE) ;
02150 
02151         if (a_this->ref_count)
02152                 a_this->ref_count -- ;
02153 
02154         if (!a_this->ref_count)
02155         {
02156                 cr_style_destroy (a_this) ;
02157                 return TRUE ;
02158         }
02159 
02160         return FALSE ;
02161 }
02162 
02163 /**
02164  *Duplicates the current instance of #CRStyle .
02165  *The newly created instance of #CRStyle must be
02166  *freed using cr_style_destroy ().
02167  *@param a_this the current instance of #CRStyle.
02168  *@return the newly duplicated instance of #CRStyle.
02169  */
02170 CRStyle *
02171 cr_style_dup (CRStyle *a_this)
02172 {
02173         CRStyle *result = NULL ;
02174 
02175         g_return_val_if_fail (a_this, NULL) ;
02176 
02177         result = cr_style_new () ;
02178         if (!result)
02179         {
02180                 cr_utils_trace_info ("Out of memory") ;
02181                 return NULL ;
02182         }
02183         memcpy (result, a_this, sizeof (CRStyle)) ;
02184 
02185         return result ;
02186 }
02187 
02188 
02189 enum CRStatus
02190 cr_style_to_pango_font_attributes (CRStyle *a_style,
02191                                    PangoAttrList *a_pgo_attrs,
02192                                    gulong a_text_len)
02193 {
02194         enum CRStatus status = CR_OK ;
02195         PangoAttribute * pgo_attr = NULL ;
02196         PangoFontDescription *pgo_font_desc = NULL ;
02197         PangoStyle pgo_style = PANGO_STYLE_NORMAL ;
02198         guchar *font_family = NULL ;
02199         PangoWeight pgo_weight = PANGO_WEIGHT_NORMAL ;
02200 
02201         g_return_val_if_fail (a_pgo_attrs
02202                               && a_style,
02203                               CR_BAD_PARAM_ERROR) ;
02204 
02205         pgo_font_desc = pango_font_description_new () ;
02206         if (!pgo_font_desc)
02207         {
02208                 cr_utils_trace_info ("Could not instanciate " 
02209                                      "pango font description") ;
02210                 return CR_ERROR ;
02211         }
02212 
02213         if (a_style->font_size)
02214         /*set font size*/
02215                 switch (a_style->font_size->type)
02216                 {
02217                 case PREDEFINED_ABSOLUTE_FONT_SIZE:
02218                         if ( !(a_style->font_size->value.predefined 
02219                                < NB_PREDEFINED_ABSOLUTE_FONT_SIZES))
02220                         {
02221                                 status = CR_OUT_OF_BOUNDS_ERROR ;
02222                                 goto cleanup ;
02223                         }
02224                         pango_font_description_set_size 
02225                                 (pgo_font_desc, 
02226                                  gv_predefined_abs_font_size_tab
02227                                  [a_style->font_size->value.predefined]
02228                                  * PANGO_SCALE) ;
02229                         break ;
02230 
02231                 case ABSOLUTE_FONT_SIZE:
02232                         if (!a_style->font_size->value.absolute)
02233                         {
02234                                 status = CR_BAD_PARAM_ERROR ;
02235                                 goto cleanup ;
02236                         }
02237                         pango_font_description_set_size 
02238                                 (pgo_font_desc, 
02239                                  a_style->font_size->value.absolute->val 
02240                                  * PANGO_SCALE) ;
02241                         break ;
02242 
02243                 case RELATIVE_FONT_SIZE:
02244                         cr_utils_trace_info ("relative font size are not supported "
02245                                              "yes") ;
02246 
02247                         break ;
02248 
02249                 case INHERITED_FONT_SIZE:
02250                         cr_utils_trace_info ("inherited font size are not supported "
02251                                              "yes") ;
02252                         break ;
02253                 }
02254 
02255 
02256         /*set font family*/
02257         if (a_style->font_family)
02258                 font_family = cr_font_family_to_string (a_style->font_family,
02259                                                         TRUE) ;
02260         if (font_family)
02261         {
02262                 pango_font_description_set_family (pgo_font_desc,
02263                                                    font_family) ;
02264         }
02265         
02266         /*set style*/
02267         switch (a_style->font_style)
02268         {
02269         case FONT_STYLE_NORMAL:
02270                 pgo_style = PANGO_STYLE_NORMAL ;
02271                 break ;
02272 
02273         case FONT_STYLE_ITALIC:
02274                 pgo_style = PANGO_STYLE_ITALIC ;
02275                 break ;
02276 
02277         case FONT_STYLE_OBLIQUE:
02278                 pgo_style = PANGO_STYLE_OBLIQUE ;
02279                 break ;
02280 
02281         case FONT_STYLE_INHERIT:
02282                 cr_utils_trace_info ("font-style: inherit not supported yet") ;
02283                 break ;
02284 
02285         default:
02286                 cr_utils_trace_info ("unknown font-sytle property value") ;
02287                 break ;
02288         }
02289 
02290         pango_font_description_set_style (pgo_font_desc,
02291                                           pgo_style) ;
02292 
02293         /*set font weight*/
02294         switch (a_style->font_weight)
02295         {
02296         case FONT_WEIGHT_NORMAL:
02297                 pgo_weight = PANGO_WEIGHT_NORMAL ;
02298                 break ;
02299 
02300         case FONT_WEIGHT_BOLD:
02301                 pgo_weight = PANGO_WEIGHT_BOLD;
02302                 break ;
02303 
02304         case FONT_WEIGHT_BOLDER:
02305                 cr_utils_trace_info 
02306                         ("font-weight: bolder is not supported yet");
02307                 break ;
02308 
02309         case FONT_WEIGHT_LIGHTER:
02310                 cr_utils_trace_info 
02311                         ("font-weight: lighter is not supported yet");
02312                 break ;
02313 
02314         case FONT_WEIGHT_100:
02315                 pgo_weight = 100 ;
02316                 break ;
02317 
02318         case FONT_WEIGHT_200:
02319                 pgo_weight = 200;
02320                 break ;
02321 
02322         case FONT_WEIGHT_300:
02323                 pgo_weight = 300 ;
02324                 break ;
02325 
02326         case FONT_WEIGHT_400:
02327                 pgo_weight = 400 ;
02328                 break ;
02329 
02330         case FONT_WEIGHT_500:
02331                 pgo_weight = 500 ;
02332                 break ;
02333 
02334         case FONT_WEIGHT_600:
02335                 pgo_weight = 600 ;
02336                 break ;
02337 
02338         case FONT_WEIGHT_700:
02339                 pgo_weight = 700 ;
02340                 break ;
02341 
02342         case FONT_WEIGHT_800:
02343                 pgo_weight = 800 ;
02344                 break ;
02345 
02346         case FONT_WEIGHT_900:
02347                 pgo_weight = 900 ;
02348                 break ;
02349 
02350         case FONT_WEIGHT_INHERIT:
02351                 cr_utils_trace_info 
02352                         ("font-weight: inherit is not supported yet.") ;
02353                 break ;
02354 
02355         default:
02356                 cr_utils_trace_info ("unknown property value") ;
02357                 break ;
02358         }
02359 
02360         pango_font_description_set_weight (pgo_font_desc,
02361                                            pgo_weight) ;
02362 
02363         pgo_attr = pango_attr_font_desc_new (pgo_font_desc) ;        
02364         if (!pgo_attr)
02365         {
02366                 status = CR_INSTANCIATION_FAILED_ERROR ;
02367                 goto cleanup ;
02368         }
02369         pgo_attr->start_index = 0 ;
02370         pgo_attr->end_index = a_text_len ;
02371         pango_attr_list_change (a_pgo_attrs, pgo_attr) ;
02372         pgo_attr = NULL ;
02373         
02374         
02375  cleanup:
02376         
02377         if (pgo_attr)
02378         {
02379                 pango_attribute_destroy (pgo_attr) ;
02380                 pgo_attr = NULL ;
02381         }
02382         if (pgo_font_desc)
02383         {
02384                 pango_font_description_free (pgo_font_desc) ;
02385                 pgo_font_desc = NULL ;
02386         }
02387 
02388         return status ;
02389 }
02390 
02391 /**
02392  *Destructor of the #CRStyle class.
02393  *@param a_this the instance to destroy.
02394  */
02395 void
02396 cr_style_destroy (CRStyle *a_this)
02397 {
02398         g_return_if_fail (a_this) ;
02399 
02400         g_free (a_this) ;
02401 }

Generated on Wed Oct 1 01:36:48 2003 for Libcroco by doxygen 1.3.3